Custom GPT ClickFix RAT (Canon and Stardock DLL Sideload)
Executive Summary
Attacker objective: install a full-featured remote access trojan on Windows machines belonging to people who go looking for ChatGPT. The entry point is the new part. A Google sponsored result for the search "chatgpt" led to an attacker-built Custom GPT titled "Plus 5.6" that lives on the genuine chatgpt.com domain and is dressed to look like a new model. Whatever the visitor types, it answers with a "Service Availability Notice" and sends them to a "backup domain", which is a Google Sites page posing as a Cloudflare check. That page is a ClickFix lure: the victim pastes a PowerShell command, and an eight-stage chain follows.
Huntress (O'Halloran and Semon, published 2026-09-28) tied at least 40 incidents to the Google Sites page and confirmed two as having begun at a Custom GPT. OpenAI removed the first GPT by 2026-09-25 and Huntress found a replacement on 2026-09-27 that delivers the identical RAT through a modified wrapper.
The chain is built so every hop hides the next. PowerShell fetches a script from a server written as a decimal number instead of a dotted IP address, defeating dotted-IP rules. The script silently installs an MSI. The MSI drops a genuine, validly signed vendor binary (Canon COTFileReadApp.exe in the first wave, Stardock DeElevate64.exe in the second) into a fake product folder under %LOCALAPPDATA%\Programs\ and launches it. The signed binary loads a patched logging DLL from its own folder, which pulls in malicious helpers. A helper decrypts a loader out of a WAV file whose audio was overwritten with ciphertext (V1) or out of a NuGet package (V2). The loader blinds AMSI, unhooks ntdll, checks for VMs, and unpacks the RAT from monitor.raw, a home-made encrypted archive of 806 files that also holds a persistence script. Persistence is a Run value and a scheduled task with the same name, and the script recreates whichever one you delete.
Attribution and naming: Huntress attributes this to no named actor and gives the RAT no family name. This pack does not coin one. It refers to the Custom GPT ClickFix RAT campaign (Huntress research) and states plainly that the RAT family is unnamed in public reporting.
Highest-value defensive angle: hunt the behaviour, not the names. Huntress itself warns that Canon- and Stardock-keyed detections "will miss the next swap" and that a third installer was already staged. The durable chain is PowerShell to a silent msiexec on a GUID-named MSI in Temp, then a signed app started by msiexec from a fake folder under %LOCALAPPDATA%\Programs\, then a Run value and scheduled task that share a name and come back when deleted.
Defender priority: a hit means a remote operator with screen, camera, microphone and file-search access, not a malware cleanup. When you eradicate, kill the signed host process first, then remove both persistence artefacts; delete either one while the implant runs and it returns within minutes. Treat credentials and sessions on the host as exposed. Q1, Q4 and Q6 are the three highest-confidence hunts.
Source Review & Web Hunter Notes
| Tier | Source | Key finding | Carry forward |
|---|---|---|---|
| 1 | Huntress, "Attackers Abuse ChatGPT Custom GPTs to Deliver RAT via ClickFix" (2026-09-28). Snapshot 01. | Primary vendor research with decoded samples. Full eight-stage chain, V1 and V2 comparison, detection opportunities, and the IOC table (hashes, IPs, URLs, value names, paths). | Yes. Source of every atomic indicator and the chain. |
| 2 | BleepingComputer, "Custom ChatGPTs push ClickFix attacks to deploy RAT malware" (2026-09-29). Snapshot 02. | Corroborates the Plus 5.6 GPT, Google Sites hop, the Canon-to-Stardock change, the shared Run key and task name, and OpenAI's 2026-09-25 takedown. Reports OpenAI plans to retire Custom GPTs on 2026-12-11. | Yes. Behaviour corroboration; no atomic IOCs. |
| 2 | Security Affairs, "Attackers Abuse ChatGPT Custom GPTs to Deploy a Full-Featured RAT". Snapshot 03. | Restates the chain and Huntress's advice that the sequence PowerShell, msiexec, signed-app sideload, persistence, RAT is the stable part. | Yes. Behaviour corroboration. |
| 2 | The Hacker News, "Attackers Abuse ChatGPT Custom GPTs..." (2026-09). Snapshot 04. | Corroborates the chain and carries both Custom GPT URLs. The page also links unrelated ClickFix stories; none of that content is used. | Yes. Second source for the two GPT URLs. |
| 2 | CyberSecurityNews, "Custom GPT malware" (2026-09-29). Snapshot 05. | States the decimal value 1614733393 and the resolved address 96.62.224[.]81, and the ceiinfolog.dll and monitor.raw names. | Yes. Second source for the delivery IP (basis for prevent). |
| 3 | Cloud Security Alliance research note, "ChatGPT Custom GPTs Weaponized for ClickFix RAT Delivery" (2026-10-01). Snapshot 06. | Lists the Google Sites lure path and both delivery IPs. States itself that it was generated with AI assistance and had no formal CSA review, and it cites Huntress as its source. | Partial. Third document for 96.62.224[.]81; second for 45.140.205[.]28. Its claims that go beyond Huntress (for example credential extraction across 17 browsers) are NOT used. |
| n/a | SecurityWeek, Help Net Security, SOC Prime, itsecurityguru | Help Net Security returned HTTP 404 on the guessed URL, and SecurityWeek and itsecurityguru did not surface in search. SOC Prime appears in search results as detection-rule listings that were not retrieved. None is cited. | No. Nothing from these is in the pack. |
Hunter notes and deliberate omissions
- All coverage is one lineage. BleepingComputer, Security Affairs, The Hacker News, CyberSecurityNews and the CSA note all relay the Huntress report. Outlet count is not independent confirmation of the indicators. This is why only one indicator ships at prevent and every hash ships at detect.
- Prevent posture: exactly one indicator,
96.62.224[.]81, is set to prevent. It appears in the Huntress table, CyberSecurityNews and the CSA note, and it is a bare delivery address with no legitimate use. No hash is at prevent because every hash is carried by Huntress alone. - No legitimate binary is blocked.
COTFileReadApp.exeandDeElevate64.exeare genuinely signed vendor software, as aremsiexec.exe,powershell.exeandGOMCam2024.exe. Their hashes ship at detect with low severity and are triaged on install path. - Legitimate platforms are not blocked as domains.
chatgpt.comandsites.google.comare legitimate. The GPT and Sites URLs are proxy-log pivots and optional path-level blocks, never Falcon domain IOCs. - C2 not recovered. Huntress did not find the C2 address in any file; the RAT resolves it through DNS-over-HTTPS. The CSV carries a labelled
REPLACE_WITH_C2_GATE_DOMAINplaceholder rather than an invented value. - The attacker command is not reproduced. Its shape (fetch cmdlet, decimal host, numbered script in Temp, bypass flag) is described and hunted in Q1 and Q2.
- Scope separation from other ClickFix packs. The library carries other ClickFix campaigns. No lure, domain, hash or infrastructure from any of them is used here. What distinguishes this campaign is the Custom GPT entry, the decimal-encoded host, the Canon and Stardock sideload pair, the WAV carrier,
monitor.rawand the two named persistence artefacts. - Unverified in this pack: the Huntress "Defense Drill" video, figures, and the full IOC table were read as text only; the samples themselves were not analysed independently. The third MSI (
UltraFreeISOCreateWizardSolution.msi) was not obtained by Huntress, so no hash exists.
Hunt Brief & Attack Chain
Hypotheses (ordered by fidelity)
| ID | Hypothesis | MITRE | Telemetry | Confidence |
|---|---|---|---|---|
| H1 | PowerShell on a user endpoint is fetching from a host written as a decimal or hex number. | T1059.001, T1105 | Process creation with command line (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | HIGH |
| H2 | PowerShell is launching msiexec to quietly install a GUID-prefixed MSI from Temp. | T1218.007 | Process creation with command line (as above) | HIGH |
| H3 | A signed Canon or Stardock binary is running from the per-user Programs tree instead of a real install. | T1574.002, T1036.005 | Process creation with image path (as above) | HIGH |
| H4 | The sideload components and carrier files (patched DLL, helper DLLs, WAV, monitor.raw) are present beside the host. | T1574.002, T1027 | Executable file written (CrowdStrike: PeFileWritten, NewExecutableWritten. SentinelOne: File Creation. Defender: DeviceFileEvents); file open for non-PE carriers (CrowdStrike: FileOpenInfo) | MEDIUM |
| H5 | A Run value and a scheduled task share a name and launch the signed host. | T1547.001, T1053.005 | Registry value set, scheduled task created (CrowdStrike: AsepValueUpdate, ScheduledTaskRegistered. SentinelOne: Registry Value Modified; task events to confirm. Defender: DeviceRegistryEvents, DeviceEvents ScheduledTaskCreated) | HIGH |
| H6 | The same autostart artefact is rewritten repeatedly within minutes of removal. | T1053.005, T1547.001 | Registry value set, scheduled task created (as above) | MEDIUM |
| H7 | The signed host process is making outbound HTTPS or DNS requests it never makes legitimately. | T1071.001, T1572 | Outbound network connection, DNS lookup (CrowdStrike: NetworkConnectIP4, DnsRequest. SentinelOne: IP Connect, DNS Resolved. Defender: DeviceNetworkEvents) | MEDIUM |
| H8 | An endpoint contacted a published delivery IP or wrote a published component hash. | T1105 | Outbound network connection; executable file written (as above) | HIGH |
Attack chain
| Step | Behavior | Telemetry | Hunt angle |
|---|---|---|---|
| 1 | Google sponsored result for "chatgpt" leads to Custom GPT "Plus 5.6" on chatgpt.com, which hands the visitor to a Google Sites "backup domain" | Web proxy or DNS and browser history (outside endpoint telemetry) | N1. Accepted endpoint gap. |
| 2 | Google Sites page posing as a Cloudflare check gets the victim to paste a PowerShell command (Run dialog or terminal) | Registry value set (RunMRU); process creation with command line | Q2, Q3 |
| 3 | PowerShell fetches a script from a decimal-encoded IP host, writes it to a numbered .ps1 in Temp, runs it, and the script deletes itself | Process creation with command line; outbound connection | Q1, Q2, Q5 |
| 4 | The decoded script (never on disk) downloads the MSI over plain HTTP and installs it quietly via msiexec | Process creation; outbound connection | Q4, Q5 |
| 5 | MSI "Advanced Printer Configuration Reader" (V1) or "Stardock Smart DeElevation Tool" (V2) installs under %LOCALAPPDATA%\Programs\ and launches the signed host | Process creation with image path; executable file written | Q6, Q7, Q8 |
| 6 | Signed host loads the patched DLL from its own folder, which imports the malicious helper | Module load (no practical Falcon query; see gaps) | Q8 (staging), N3 |
| 7 | Helper decrypts the loader from a WAV (V1) or Build.dat NuGet package (V2) and runs it in memory; AMSI bypass, ntdll unhooking, anti-VM | File open; in-memory only | Q9, N5. Execution itself is an accepted gap. |
| 8 | Loader unpacks the RAT from monitor.raw; the embedded script writes the Run value and task, and recreates them | Registry value set; scheduled task created | Q10, Q11 |
| 9 | RAT: remote desktop, camera, microphone, file search, DNS-over-HTTPS C2, follow-on payloads such as GOMCam2024.exe | Outbound connection; DNS lookup; process creation | Q12, Q13, Q15 |
Consolidated IOC Table
Read before importing: 18 atomic indicators ship in the CSV in section 10. Exactly one (96.62.224[.]81) is prevent. All others, including every hash, are detect because they are single-sourced to Huntress or are legitimate signed software. URL, value-name, path and filename indicators are behavioural signals, not CSV rows.
| Type | Value | Confidence | Action | Context | Expiry | Sources |
|---|---|---|---|---|---|---|
| IPv4 | 96.62.224[.]81 | HIGH | PREVENT | Hosts the ClickFix script and the MSI. Decimal form 1614733393 in commands. Three saved sources. | 2027-01-11 | Huntress, CSN, CSA |
| IPv4 | 45.140.205[.]28 | MEDIUM | DETECT | Payload server in a related incident. Two documents, the second derived from Huntress. | 2027-04-11 | Huntress, CSA |
| Host form | 1614733393 | HIGH | BEHAVIORAL | Decimal encoding of 96.62.224[.]81 used in the PowerShell command. Hunted by shape in Q1, not by value, because the next server will encode differently. | n/a | Huntress, CSN |
| URL | hxxps://sites[.]google[.]com/view/antibot172881 | HIGH | BEHAVIORAL | Google Sites ClickFix lure page. The domain is a legitimate platform and must never be blocked as a domain; block this path at a TLS-inspecting proxy only. Not in the Falcon CSV. | n/a | Huntress, CSA |
| URL | hxxps://chatgpt[.]com/g/g-6ab595ad6554819181b686d4876efb80-plus-5-6 | MEDIUM | INFO ONLY | First Custom GPT "Plus 5.6". Removed by OpenAI by 2026-09-25. Legitimate domain; proxy-log pivot only. | n/a | Huntress, THN |
| URL | hxxps://chatgpt[.]com/g/g-6ab6ba039440819185ed491740b11cf8-plus-5-6 | MEDIUM | INFO ONLY | Second Custom GPT "Plus 5.6", active at publication. Legitimate domain; proxy-log pivot only. | n/a | Huntress, THN |
| URL | hxxp://1614733393/app/afafa98279c9/ISOSimple[.]msi | HIGH | BEHAVIORAL | V1 MSI download URL. Per-campaign path; hunted through Q1, Q4, Q5. | n/a | Huntress |
| URL | hxxp[://]1614733393/s/50d6565cf39e | HIGH | BEHAVIORAL | V2 stage-2 script URL (spoofed Chrome user agent, re-obfuscated per request). | n/a | Huntress |
| URL | hxxp://1614733393/app/50d6565cf39e/IconEdit2Turb[.]msi | HIGH | BEHAVIORAL | V2 MSI download URL. | n/a | Huntress |
| URL | hxxp://1614733393/app/a26b67343315/UltraFreeISOCreateWizardSolution[.]msi | LOW | BEHAVIORAL | Third MSI on the same server, seen 2026-09-23, not obtained by Huntress. Evidence the signed host will be swapped again. | n/a | Huntress |
| SHA256 | ISOSimple.msi6761aad48a3f987238994d92bca97e4b8550e0150607bd67b47b1b6366a371fc | MEDIUM | DETECT | V1 installer ("Advanced Printer Configuration Reader", publisher Softplicity). Single source. | 2027-04-11 | Huntress |
| SHA256 | IconEdit2Turb.msi91a22cf3154944897cbcaffc7d20d4596e972d280ee134197d41d8d8eefb0fe2 | MEDIUM | DETECT | V2 installer ("Stardock Smart DeElevation Tool"). Single source. | 2027-04-11 | Huntress |
| SHA256 | ceiinfolog.dlle58831766e8d4313db9f8b85f90c3a840aa0d84cfeac285beefa40e39ad0d1fb | MEDIUM | DETECT | V1 patched Canon logging DLL (signature stripped; imports rdCore.dll). Single source. | 2027-04-11 | Huntress |
| SHA256 | rdCore.dllb77575413c0f97eaf31e4a44c884c1ecdc0049ec89916ceb0bf3aaaedc0442fe | MEDIUM | DETECT | V1 loader DLL, fake Polly 7.2.3 version info. Single source. | 2027-04-11 | Huntress |
| SHA256 | WPFLocalizeExtension.dlleff5d63ddf1813962f0d8ad1250cea5486c8bb5dd27c3f432b43957a33e43764 | MEDIUM | DETECT | V1 malicious native DLL with a real open-source library name. Single source. | 2027-04-11 | Huntress |
| SHA256 | WMPCL.dll9c615db040b88c18ce6b96f30d08797045b7d506f940bea452dc7a6992fdbb8d | MEDIUM | DETECT | V1 helper DLL. Single source. | 2027-04-11 | Huntress |
| SHA256 | DeElevator64.dll0457414c4504b70115798eee9c8384a8bf9e793461ffb2e0661a6dcc6ed4809f | MEDIUM | DETECT | V2 patched Stardock DLL (imports I++u.dll). Single source. | 2027-04-11 | Huntress |
| SHA256 | I++u.dll3cd1484cc5bf10e22d79784beba58a75d7b126c46efb5e1a85d6aab884447621 | MEDIUM | DETECT | V2 loader DLL, fake SharpCompress version info. Single source. | 2027-04-11 | Huntress |
| SHA256 | senddmp.resources.dllb59a21a8d4c0c11a9ecbbdbe2a2938499c99c5ebb210c9c6db9683c7ad19f4c4 | MEDIUM | DETECT | V2 alloc and exec helper. Single source. | 2027-04-11 | Huntress |
| SHA256 | res.dlla27cafb84876a3374ef4aba1062345def6cd0b029eaf8e0dc44fa24fc943f3c6 | MEDIUM | DETECT | V2 network helper. Single source. | 2027-04-11 | Huntress |
| SHA256 | Common.Integrator.Preview.wav54c94f85ba6e950903d5ff42c0971c5a9d0741596be26e06afe7d60ec38edf31 | MEDIUM | DETECT | V1 loader carrier (valid WAV header, ciphertext from offset 0x24362). Single source. | 2027-04-11 | Huntress |
| SHA256 | monitor.rawe614b7d5a7a363fb1b355a87e2e8d9e8a05bbbca08f2cee3d606bdb5015ac53b | MEDIUM | DETECT | V1 encrypted archive (806 files and 315 folders once decrypted). Single source. | 2027-04-11 | Huntress |
| SHA256 | Build.datd3fda1e6cf886fd530bf62e2d16c39ad23ed12a2c933fc211f1f4876ceaa033e | MEDIUM | DETECT | V2 NuGet carrier for the loader. Single source. | 2027-04-11 | Huntress |
| SHA256 | execute_engine_disconnect.rawd5acf44658f0dce90bd160f15d8e07a96938c81661d87dc7e9cb0107863bfb90 | MEDIUM | DETECT | V2 encrypted archive. Single source. | 2027-04-11 | Huntress |
| SHA256 | COTFileReadApp.exe278e2f3e2f26c18666b89ef774b4af9ce954e36b2bf54a2392608619245d8c48 | HIGH | DETECT | LEGITIMATE Canon-signed sideload host. Never prevent. The hash is genuine vendor software; triage on install path (Q6). | 2027-04-11 | Huntress |
| SHA256 | DeElevate64.exe22869e3326fe1de011cd500e666769027126c5c440b76837baf55139f30094e4 | HIGH | DETECT | LEGITIMATE Stardock-signed sideload host. Never prevent. The hash is genuine vendor software; triage on install path (Q6). | 2027-04-11 | Huntress |
| SHA256 | 6469.ps114e3376befd4b7b52de0757b6264da294ac6b0f9e4ff51cb9bc5b19b243fe335 | LOW | INFO ONLY | V1 obfuscated stager. Filename and hash vary per victim; reference only. Not in the CSV. | n/a | Huntress |
| SHA256 | 5689.ps1c4603646701069ebdeabc96f74e1f947355ace8575560986d8393fcc6b88d0b7 | LOW | INFO ONLY | V2 stager. Re-obfuscated on every request; hash is worthless as an indicator. Not in the CSV. | n/a | Huntress |
| SHA256 | Loader shellcode20c7befc174a61117770535e809046c75e93c71284bf1a9c6cd532f55b315f53 | LOW | INFO ONLY | Loader shellcode decoded from the WAV. Exists in memory only. Not in the CSV. | n/a | Huntress |
| SHA256 | RAT shellcodeab65bbfc505dbe1cebe6021fb36e2011f6aa1d64f5d87cee1cbee3fc2a0c7907 | LOW | INFO ONLY | RAT shellcode decoded from monitor.raw. Exists in memory only. Not in the CSV. | n/a | Huntress |
| Value name | Canon Configuration Reader | HIGH | BEHAVIORAL | Name of both the HKCU Run value and the scheduled task (V1). Q10. | n/a | Huntress, BC, CSN, CSA |
| Value name | Stardock DeElevation Tool | HIGH | BEHAVIORAL | Name of both the Run value and the scheduled task (V2). Q10. | n/a | Huntress, CSA |
| Path | %LOCALAPPDATA%\Programs\Advanced Printer Configuration Reader\ | HIGH | BEHAVIORAL | V1 install folder. Q6, Q7, Q8. | n/a | Huntress |
| Path | %LOCALAPPDATA%\Programs\Stardock Smart DeElevation Tool\ | HIGH | BEHAVIORAL | V2 install folder. Q6, Q7, Q8. | n/a | Huntress |
| Path | %LOCALAPPDATA%\AppstorageFile\GOMCam2024.exe | MEDIUM | BEHAVIORAL | Usual follow-on payload (legitimately signed). Q15. | n/a | Huntress |
| C2 | Gate address | LOW | PLACEHOLDER | Not recovered from any sample. DNS-over-HTTPS via Cloudflare, Google and Quad9 resolvers. CSV carries a REPLACE_WITH_ row. | n/a | Huntress |
Affected Surface & Telemetry Matrix
| Surface | Telemetry | Priority | Gap risk |
|---|---|---|---|
| Windows endpoint, process tree | Process creation with command line, path and parent (CrowdStrike: ProcessRollup2, SyntheticProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | HIGH | Low. This is where the durable signal lives. |
| Windows endpoint, file writes | Executable file written (CrowdStrike: PeFileWritten, NewExecutableWritten. SentinelOne: File Creation. Defender: DeviceFileEvents) | HIGH | Medium. Covers PE files only; WAV, .raw and .dat carriers are not PE. |
| Windows endpoint, non-PE file opens | File open (CrowdStrike: FileOpenInfo, sensor-policy dependent) | MEDIUM | High. Collection varies by sensor policy; confirm in gate G1. |
| Windows endpoint, registry and tasks | Registry value set, scheduled task created (CrowdStrike: AsepValueUpdate, RegGenericValueUpdate, ScheduledTaskRegistered. SentinelOne: Registry Value Modified; task event names to confirm. Defender: DeviceRegistryEvents, DeviceEvents ScheduledTaskCreated) | HIGH | Medium. Task event fields vary by sensor version. |
| Windows endpoint, network and DNS | Outbound connection and DNS lookup with process context (CrowdStrike: NetworkConnectIP4, DnsRequest. SentinelOne: IP Connect, DNS Resolved. Defender: DeviceNetworkEvents) | MEDIUM | Medium. DNS-over-HTTPS C2 never appears as DNS; only the TLS connection to the resolver does. |
| DLL load events | Module load with signature state | MEDIUM | High. No module-load event is used in this pack. Use Sysmon event 7 or equivalent (native hunt N3). |
| Web proxy, secure web gateway, browser history | URL and referrer logs for the Custom GPT and Google Sites hops | HIGH | Outside endpoint telemetry. The lure is on two legitimate domains and invisible to host sensors. |
| PowerShell logging | Script block log (Windows event 4104) | HIGH | Medium. AMSI is blinded later in the chain, but 4104 records the decoded stage-1 script, which is built with a scriptblock and never touches disk. |
ATT&CK Mapping
| Tactic | Technique | Name | Observed behavior | Query or control |
|---|---|---|---|---|
| Resource Development | T1583.008 | Malvertising | Google sponsored result for "chatgpt" points at the Custom GPT | N1, N8 |
| Initial Access | T1566.002 (closest) | Phishing: Spearphishing Link | Not email; a trusted-platform chat hands the victim a link to the lure page. Mapped to the nearest link-based technique. | N1, S2 |
| Execution | T1204.004 | User Execution: Malicious Copy and Paste | ClickFix: victim pastes the PowerShell command | Q2, Q3, I1 |
| Execution | T1059.001 | PowerShell | Fetch from decimal-encoded host; obfuscated stage-1 script | Q1, Q2, I3 |
| Command and Control | T1105 | Ingress Tool Transfer | MSI and follow-on payloads fetched over plain HTTP | Q1, Q5, Q13 |
| Defense Evasion | T1027 | Obfuscated Files or Information | Integer-array script with two decoding layers; encrypted shellcode; custom archive | Q1, Q9, N6 |
| Defense Evasion | T1027.013 (closest) | Encrypted/Encoded File | Loader ciphertext overwrites the audio section of a WAV (Huntress: not true steganography); V2 inside a NuGet package | Q9, N5 |
| Defense Evasion | T1218.007 | System Binary Proxy Execution: Msiexec | Silent msiexec install of the MSI | Q4, I2 |
| Defense Evasion | T1553.005 | Subvert Trust Controls: Mark-of-the-Web Bypass | V2 strips Mark-of-the-Web from the MSI before install | Q2 |
| Defense Evasion, Persistence | T1574.002 | DLL Side-Loading | Signed COTFileReadApp.exe or DeElevate64.exe loads a patched DLL from its own folder | Q6, Q7, Q8, Q14, N3, S1 |
| Defense Evasion | T1036.005 | Masquerading: Match Legitimate Name or Location | Fake product folders; DLL names borrowed from Canon, Stardock and open-source libraries; version info faked | Q6, Q7, Q8 |
| Defense Evasion | T1562.001 | Impair Defenses: Disable or Modify Tools | AMSI bypass and ntdll unhooking in the loader (in memory) | Gap; S1, I4 |
| Defense Evasion | T1497.001 | Virtualization/Sandbox Evasion: System Checks | Anti-VM checks; V2 opens a harmless window if a helper call fails | Gap (in memory) |
| Defense Evasion | T1070.004 | Indicator Removal: File Deletion | Stage-1 script deletes itself | N2 |
| Persistence | T1547.001 | Registry Run Keys | HKCU Run value "Canon Configuration Reader" / "Stardock DeElevation Tool" | Q10, Q11 |
| Persistence | T1053.005 | Scheduled Task | Task with the same name, recreated every 875 s if removed | Q10, Q11 |
| Discovery | T1082, T1518.001 | System Information, Security Software Discovery | Host recon: antivirus via WMI, Defender status, domain, adapters, ports, software | Gap |
| Collection | T1113, T1125, T1123 | Screen, Video and Audio Capture | Remote desktop, camera, microphone and system-audio capture | Gap (no endpoint telemetry); C4 response |
| Collection | T1005, T1083 | Data from Local System; File and Directory Discovery | File manager with host-wide content search | Gap |
| Command and Control | T1071.001, T1572 | Web Protocols; Protocol Tunneling | DNS-over-HTTPS via Cloudflare, Google and Quad9 to find the C2 "Gate" | Q12 |
Native Audit-Log Hunts
Non-CQL checks, for platforms and logs outside the Falcon event stream. Run N1 first: it is the only place the Custom GPT and Google Sites hops are visible.
| ID | Where | What to look for |
|---|---|---|
| N1 | Web proxy, secure web gateway, DNS filter, browser history | Requests to chatgpt.com paths of the form /g/g-<id>-plus-5-6 and to sites.google.com/view/antibot172881, especially with a Google Ads click-tracking query string (gad_source, gad_campaignid) on the GPT URL. A GPT titled "Plus 5.6" shown as "by a community builder" is the lure. Also any HTTP request whose host is a bare integer. |
| N2 | PowerShell Operational log, event 4104 (script block logging) | A very long single line of negative integers followed by a scriptblock create. The decoded layer is logged even though it never touches disk. Also numbered .ps1 files created and removed in %TEMP%. |
| N3 | Sysmon event 7 (image loaded), or Defender for Endpoint DeviceImageLoadEvents | COTFileReadApp.exe or DeElevate64.exe loading ceiinfolog.dll or DeElevator64.dll with Signed=false or a signature that does not validate, from its own folder under %LOCALAPPDATA%\Programs\. Huntress notes the V2 DLL has a header checksum that no longer matches. |
| N4 | Windows Task Scheduler Operational log (events 106 registered, 140 updated, 141 deleted) and Security 4698 | A task named Canon Configuration Reader or Stardock DeElevation Tool, and any task registered again shortly after event 141 for the same name (the 875-second recreation). |
| N5 | Endpoint file-system sweep (read-only) | Run the sweep below on suspect hosts. A WAV that "has a valid header but whose header size is smaller than the file" is the V1 carrier. |
| N6 | Windows Installer log (MsiInstaller events 11707 and 1033) | A per-user product from publisher "Softplicity" ("Advanced Printer Configuration Reader") or "Stardock Smart DeElevation Tool", installed from Temp, with the Programs and Features entry hidden (ARPSYSTEMCOMPONENT=1). |
| N7 | Microsoft Defender alert history | Huntress saw Trojan:Script/Wacatac.H!ml quarantine ISOSimple.msi after it had already run. A Defender detection on a Temp MSI is not containment; check the Run value and task. |
| N8 | Ad and brand monitoring | Sponsored results for "chatgpt" pointing at a chatgpt.com /g/ URL instead of the product home page. Report the GPT to OpenAI and the Sites page to Google. |
N5 sweep (read-only)
# Prerequisites: run as the affected user or an administrator; read-only, changes nothing
# Reboot required: no
# Rollback: none required (no changes made)
$p = Join-Path $env:LOCALAPPDATA 'Programs'
Get-ChildItem -Path $p -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match '^(ceiinfolog|rdCore|WPFLocalizeExtension|WMPCL|DeElevator64|I\+\+u|senddmp\.resources|res)\.dll$' -or
$_.Name -match '^(Common\.Integrator\.Preview\.wav|monitor\.raw|execute_engine_disconnect\.raw|Build\.dat)$' } |
Select-Object FullName, Length, LastWriteTime,
@{n='Signature';e={ (Get-AuthenticodeSignature $_.FullName).Status }}
Get-ChildItem -Path (Join-Path $env:LOCALAPPDATA 'AppstorageFile') -ErrorAction SilentlyContinue
Hunt Queries: CrowdStrike CQL and SentinelOne PowerQuery
Use your tenant's own address. SentinelOne does not document a link that pre-fills a query, so each "Copy & open SentinelOne" button copies the query and opens this console: paste it into PowerQuery.
All 15 queries describe behaviour from the Huntress report and use Falcon event and field names from the data model. Filename matches use the FileName basename so no path slash sits inside a regex. Run window: set the console time picker (30 days for the first baseline run). Q6, Q10 and Q15 match legitimately signed software and are detect-only by design. Q9, Q10, Q11 and Q12 depend on telemetry that varies by sensor version and carry a validate-in-tenant note.
Looks for: the single most campaign-specific command-line shape. The reporting says the ClickFix command writes its server as one decimal number instead of a dotted quad, which Windows resolves normally but which dotted-IP rules never see. The query matches a web-fetch cmdlet or .NET download method followed by a bare 8 to 10 digit integer (or a 0x hex form) in host position, and separately any URL whose host is such a number. Legitimate scripts almost never address a web server this way. The attacker's command is not reproduced here; only its shape is hunted.
Known limitations and deployment notes
- PowerQuery: A fetch launched by a process the agent did not observe starting is not captured.
- PowerQuery: Hosts written as an octal or mixed-radix number are not covered, as in the CQL.
- PowerQuery assumes: On Process Creation, tgt.process.* is the new process and src.process.* is its creator, so the CQL FileName maps to tgt.process.name and ParentBaseFileName to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
- PowerQuery assumes: The single and double quote characters in the CQL character class are written as \x27 and \x22 because the pattern sits inside a single-quoted PowerQuery string; the regex engine is assumed to accept hex escapes.
// HUNT: PowerShell web fetch addressed to a decimal- or hex-encoded IP host (Custom GPT ClickFix RAT stage 1) // MITRE: T1059.001, T1105, T1027 // CONF: high | FP: low | COST: low | REQUIRES: process creation with command line // FALSE POSITIVES: a script that passes a large integer as a timeout or size right after a fetch cmdlet and a space // SOURCE: Huntress 2026-09-28 (host written as a decimal number; resolves to the delivery IP) #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(powershell|pwsh)\.exe$/i | CommandLine=/\b(irm|iwr|Invoke-RestMethod|Invoke-WebRequest|DownloadString|DownloadFile|DownloadData|curl|wget)\b[^|;&]{0,80}?(\s|['"(=]|:\W{1,3})(0x[0-9a-f]{8}|[0-9]{8,10})([^0-9.]|$)/i or CommandLine=/https?:\W{1,4}(0x[0-9a-f]{8}|[0-9]{8,10})([^0-9.]|$)/i | table([@timestamp, ComputerName, UserName, FileName, ParentBaseFileName, CommandLine, aid], limit=200)
5 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nametgt.process.name: Created process nametgt.process.cmdline: Created command line
Recommended fields
src.process.name: Creator or acting processsrc.process.user: src.process.user
Readiness test
event.type = 'Process Creation' endpoint.name = * tgt.process.name = * tgt.process.cmdline = * | limit 5 | columns event.type, event.time, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: PowerShell web fetch addressed to a decimal- or hex-encoded IP host (Custom GPT ClickFix RAT stage 1)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1059.001, T1105, T1027
// CONF: high | FP: low
// FALSE POSITIVES: a script that passes a large integer as a timeout or size right after a fetch cmdlet and a space
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: PowerShell whose command line pairs a fetch cmdlet with a decimal or hex 8 to 10 digit host, or an http(s) URL whose host is such a number. The lazy gap quantifier is made greedy because PowerQuery has no lazy quantifiers; with a bounded gap and a required following group the set of matching lines is the same.
// REQUIRES: SentinelOne Process Creation telemetry with command lines
// TUNING: A script that passes a large integer right after a fetch cmdlet and a space is the known false positive; exclude by full command line after review.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: A fetch launched by a process the agent did not observe starting is not captured. Hosts written as an octal or mixed-radix number are not covered, as in the CQL.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation'
tgt.process.name in:anycase ('powershell.exe','pwsh.exe')
(tgt.process.cmdline matches '\\b(irm|iwr|Invoke-RestMethod|Invoke-WebRequest|DownloadString|DownloadFile|DownloadData|curl|wget)\\b[^|;&]{0,80}(\\s|[\\x27\\x22(=]|:\\W{1,3})(0x[0-9a-f]{8}|[0-9]{8,10})([^0-9.]|$)' or tgt.process.cmdline matches 'https?:\\W{1,4}(0x[0-9a-f]{8}|[0-9]{8,10})([^0-9.]|$)')
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline, agent.uuid
| limit 200Looks for: the behavioural ClickFix launch that survives a change of server. PowerShell started by the Run dialog (explorer.exe), a browser, or a terminal host, whose command line fetches remote content and either bypasses execution policy or stages through the temp folder. The reporting also describes the V2 stager stripping Mark-of-the-Web from the MSI, so an Unblock-File or Zone.Identifier edit that names an .msi is included as a second branch. FP: admin one-liners and package-manager bootstraps pasted into a terminal.
Known limitations and deployment notes
- PowerQuery: A paste that reaches PowerShell through a parent not in the list is not captured.
- PowerQuery assumes: On Process Creation, tgt.process.* is the new process and src.process.* is its creator, so the CQL FileName maps to tgt.process.name and ParentBaseFileName to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
- PowerQuery assumes: In the CQL, $env:temp is a regex where $ anchors; here the dollar sign is escaped so it matches the literal text $env:temp.
// HUNT: user-launched PowerShell with a web fetch plus bypass or temp staging, or MSI Mark-of-the-Web removal (ClickFix launch) // MITRE: T1204.004, T1059.001, T1553.005 // CONF: medium | FP: medium | COST: low | REQUIRES: process creation with command line and parent // FALSE POSITIVES: administrators pasting install one-liners; developer tooling bootstraps // TUNING: exclude the IT admin asset group and known package-manager bootstraps (parent cmd.exe with a vendor installer URL); keep hits where the parent is explorer.exe or a browser #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(powershell|pwsh)\.exe$/i | ParentBaseFileName=/^(explorer|chrome|msedge|firefox|brave|opera|WindowsTerminal|OpenConsole|conhost|cmd)\.exe$/i | CommandLine=/\b(irm|iwr|iex|Invoke-RestMethod|Invoke-WebRequest|Invoke-Expression|Unblock-File)\b/i | CommandLine=/bypass|out-file|set-content|\$env:temp|%temp%|\.msi|zone\.identifier/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, CommandLine, aid], limit=200)
6 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nametgt.process.name: Created process nametgt.process.cmdline: Created command linesrc.process.name: Creator or acting process
Recommended fields
src.process.user: src.process.user
Readiness test
event.type = 'Process Creation' endpoint.name = * tgt.process.name = * tgt.process.cmdline = * src.process.name = * | limit 5 | columns event.type, event.time, endpoint.name, tgt.process.name, tgt.process.cmdline, src.process.name
// HUNT: user-launched PowerShell with a web fetch plus bypass or temp staging, or MSI Mark-of-the-Web removal (ClickFix launch)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1204.004, T1059.001, T1553.005
// CONF: medium | FP: medium
// FALSE POSITIVES: administrators pasting install one-liners; developer tooling bootstraps
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: PowerShell launched by an interactive or console parent, a web-fetch or unblock cmdlet, and a bypass or temp-staging or MSI marker. Lineage re-mapped for SentinelOne.
// REQUIRES: SentinelOne Process Creation telemetry with command lines and parent names
// TUNING: Exclude the IT admin asset group and known package-manager bootstraps (parent cmd.exe with a vendor installer URL); keep hits where the parent is explorer.exe or a browser.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: A paste that reaches PowerShell through a parent not in the list is not captured.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation'
tgt.process.name in:anycase ('powershell.exe','pwsh.exe')
src.process.name in:anycase ('explorer.exe','chrome.exe','msedge.exe','firefox.exe','brave.exe','opera.exe','WindowsTerminal.exe','OpenConsole.exe','conhost.exe','cmd.exe')
tgt.process.cmdline matches '\\b(irm|iwr|iex|Invoke-RestMethod|Invoke-WebRequest|Invoke-Expression|Unblock-File)\\b'
tgt.process.cmdline matches 'bypass|out-file|set-content|\\$env:temp|%temp%|\\.msi|zone\\.identifier'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline, agent.uuid
| limit 200Looks for: the lure at the moment of execution. If the victim pastes the ClickFix command into Run rather than a terminal, Windows records it in RunMRU even when later stages fail or are cleaned up. Fires upstream of every process-based detection. A paste into Windows Terminal or a PowerShell window does not touch RunMRU, so a miss here proves nothing; Q1 and Q2 cover that path.
⚠ Validate in tenant: RunMRU value writes depend on registry collection settings in your sensor policy. Run the event filter alone first (gate G1).
Known limitations and deployment notes
- PowerQuery: If the agent does not monitor RunMRU the query returns nothing, which reads as clean.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
- PowerQuery assumes: RunMRU writes are assumed to arrive as Registry Value Modified events with the typed text in registry.value.
// HUNT: Run-dialog entry that launches PowerShell with a web fetch (ClickFix paste, RunMRU) // MITRE: T1204.004, T1059.001 // CONF: high | FP: low | COST: low | REQUIRES: registry value telemetry for RunMRU (validate in tenant) // FALSE POSITIVES: an administrator typing a PowerShell download into Run // TUNING: exclude the IT admin asset group if it uses Run for scripted downloads #event_simpleName=/^(RegGenericValueUpdate|AsepValueUpdate|RegSystemConfigValueUpdate)$/ | RegObjectName=/RunMRU/i | RegStringValue=/(powershell|pwsh)/i | RegStringValue=/\b(irm|iwr|iex|Invoke-RestMethod|Invoke-WebRequest|Invoke-Expression)\b/i | table([@timestamp, ComputerName, UserName, RegObjectName, RegValueName, RegStringValue, aid], limit=200)
5 required fields · View requirements
Required telemetry
- Registry Value Modified
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nameregistry.keyPath: Registry key pathregistry.value: Registry value data
Recommended fields
src.process.name: Creator or acting processsrc.process.user: src.process.user
Optional fields
registry.valueName: Registry value name
Readiness test
event.type = 'Registry Value Modified' endpoint.name = * registry.keyPath = * registry.value = * | limit 5 | columns event.type, event.time, endpoint.name, registry.keyPath, registry.value
// HUNT: Run-dialog entry that launches PowerShell with a web fetch (ClickFix paste, RunMRU) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1204.004, T1059.001 // CONF: high | FP: low // FALSE POSITIVES: an administrator typing a PowerShell download into Run // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a RunMRU registry write whose data names PowerShell and a web-fetch cmdlet. // REQUIRES: SentinelOne Registry Value Modified telemetry covering HKCU RunMRU // TUNING: Exclude the IT admin asset group if it uses Run for scripted downloads. // LOOKBACK: 30d; set the console time range or the query window to cover the exposure period // CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule. // KNOWN GAPS: If the agent does not monitor RunMRU the query returns nothing, which reads as clean. // VALIDATION LEVEL: static-reviewed event.type = 'Registry Value Modified' registry.keyPath matches 'RunMRU' registry.value matches '(powershell|pwsh)' registry.value matches '\\b(irm|iwr|iex|Invoke-RestMethod|Invoke-WebRequest|Invoke-Expression)\\b' | columns event.time, endpoint.name, src.process.user, src.process.name, registry.keyPath, registry.valueName, registry.value, agent.uuid | limit 200
Looks for: Huntress's lead process-level detection. The decoded stage-1 script installs the MSI with a quiet, no-restart msiexec invocation from the temp folder, under a 32-hex-character GUID prefix (<GUID>_ISOSimple.msi, and _IconEdit2Turb.msi in V2). A third installer, UltraFreeISOCreateWizardSolution.msi, sat on the same server, so the query also keeps the generic shape. The Tier column ranks hits: named in the report, GUID-prefixed, or generic.
Known limitations and deployment notes
- PowerQuery: A parent that is not PowerShell, such as cmd.exe or a script host, is not captured, as in the CQL.
- PowerQuery assumes: On Process Creation, tgt.process.* is the new process and src.process.* is its creator, so the CQL FileName maps to tgt.process.name and ParentBaseFileName to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
- PowerQuery assumes: tier is a ternary with spaces around the colon, replacing the CQL case block.
// HUNT: powershell spawning a silent msiexec install of an MSI from a user-writable path (Custom GPT ClickFix RAT stage 2) // MITRE: T1218.007, T1059.001, T1105 // CONF: high | FP: low | COST: low | REQUIRES: process creation with command line and parent // FALSE POSITIVES: PowerShell-driven software deployment that stages MSIs in Temp // SOURCE: Huntress 2026-09-28 detection opportunities (powershell launching msiexec on a GUID-named MSI in Temp) #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^msiexec\.exe$/i | ParentBaseFileName=/^(powershell|pwsh)\.exe$/i | CommandLine=/\.msi/i | CommandLine=/\W(qn|quiet|qb)\b/i | CommandLine=/(\\temp\\|%temp%|\\appdata\\|\\users\\public\\|\\programdata\\)/i | case { CommandLine=/(ISOSimple|IconEdit2Turb|UltraFreeISOCreateWizardSolution)\.msi/i | Tier := "named-in-report"; CommandLine=/[0-9a-f]{32}_\w+\.msi/i | Tier := "guid-prefixed"; * | Tier := "generic"; } | table([@timestamp, ComputerName, UserName, Tier, ParentBaseFileName, CommandLine, aid], limit=200)
6 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nametgt.process.name: Created process nametgt.process.cmdline: Created command linesrc.process.name: Creator or acting process
Recommended fields
src.process.user: src.process.user
Readiness test
event.type = 'Process Creation' endpoint.name = * tgt.process.name = * tgt.process.cmdline = * src.process.name = * | limit 5 | columns event.type, event.time, endpoint.name, tgt.process.name, tgt.process.cmdline, src.process.name
// HUNT: powershell spawning a silent msiexec install of an MSI from a user-writable path (Custom GPT ClickFix RAT stage 2)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1218.007, T1059.001, T1105
// CONF: high | FP: low
// FALSE POSITIVES: PowerShell-driven software deployment that stages MSIs in Temp
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: msiexec created by PowerShell on an MSI with a quiet switch and a user-writable path. The three-tier case becomes a computed tier column.
// REQUIRES: SentinelOne Process Creation telemetry with command lines and parent names
// TUNING: Exclude PowerShell-driven software deployment that stages MSIs in Temp, by full command line.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: A parent that is not PowerShell, such as cmd.exe or a script host, is not captured, as in the CQL.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation'
tgt.process.name in:anycase ('msiexec.exe')
src.process.name in:anycase ('powershell.exe','pwsh.exe')
tgt.process.cmdline contains '.msi'
tgt.process.cmdline matches '\\W(qn|quiet|qb)\\b'
tgt.process.cmdline matches '(\\\\temp\\\\|%temp%|\\\\appdata\\\\|\\\\users\\\\public\\\\|\\\\programdata\\\\)'
| let tier = tgt.process.cmdline matches '(ISOSimple|IconEdit2Turb|UltraFreeISOCreateWizardSolution)\\.msi' ? 'named-in-report' : (tgt.process.cmdline matches '[0-9a-f]{32}_\\w+\\.msi' ? 'guid-prefixed' : 'generic')
| columns event.time, endpoint.name, src.process.user, tier, src.process.name, tgt.process.cmdline, agent.uuid
| limit 200Looks for: the transport the reporting describes: the MSI comes over plain HTTP from the same IP-addressed host as the script, so there is no DNS lookup and no TLS. PowerShell or msiexec opening an outbound port 80 connection to a routable address is uncommon on managed endpoints. This also catches infrastructure that rotates between incidents, which Huntress says it does. FP: legacy HTTP-only internal or vendor endpoints reached from scripts.
Known limitations and deployment notes
- PowerQuery: Connections by a process that is not PowerShell or msiexec are not captured.
- PowerQuery assumes: On non-Process-Creation events the acting process is src.process.*, so the CQL ContextBaseFileName maps to src.process.name.
- PowerQuery assumes: Each excluded range is a separate net_ipsubnet negation so the ranges stay verbatim.
// HUNT: powershell or msiexec outbound plain HTTP (port 80) to a public IP, no DNS needed (decimal-IP delivery) // MITRE: T1105, T1071.001 // CONF: medium | FP: medium | COST: low | REQUIRES: NetworkConnectIP4 with process context // FALSE POSITIVES: scripts pulling from HTTP-only vendor or internal repositories // TUNING: exclude known HTTP-only destinations by RemoteAddressIP4 and the IT admin asset group; msiexec.exe hits need almost no tuning #event_simpleName=NetworkConnectIP4 | ContextBaseFileName=/^(powershell|pwsh|msiexec)\.exe$/i | RemotePort=80 | !cidr(RemoteAddressIP4, subnet=["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "127.0.0.0/8", "169.254.0.0/16"]) | table([@timestamp, ComputerName, UserName, ContextBaseFileName, RemoteAddressIP4, RemotePort, aid], limit=200)
6 required fields · View requirements
Required telemetry
- IP Connect
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host namesrc.process.name: Creator or acting processdst.ip.address: Remote IPdst.port.number: Remote port
Recommended fields
src.process.user: src.process.user
Readiness test
event.type = 'IP Connect' endpoint.name = * src.process.name = * dst.ip.address = * dst.port.number = * | limit 5 | columns event.type, event.time, endpoint.name, src.process.name, dst.ip.address, dst.port.number
// HUNT: powershell or msiexec outbound plain HTTP (port 80) to a public IP, no DNS needed (decimal-IP delivery)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1105, T1071.001
// CONF: medium | FP: medium
// FALSE POSITIVES: scripts pulling from HTTP-only vendor or internal repositories
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: PowerShell or msiexec connecting out on port 80 to an address outside the private, loopback and link-local ranges.
// REQUIRES: SentinelOne IP Connect telemetry with process context
// TUNING: Exclude known HTTP-only destinations by dst.ip.address and the IT admin asset group; msiexec.exe hits need almost no tuning.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: Connections by a process that is not PowerShell or msiexec are not captured.
// VALIDATION LEVEL: static-reviewed
event.type = 'IP Connect'
src.process.name in:anycase ('powershell.exe','pwsh.exe','msiexec.exe')
dst.port.number = 80
!(net_ipsubnet(dst.ip.address,'10.0.0.0/8'))
!(net_ipsubnet(dst.ip.address,'172.16.0.0/12'))
!(net_ipsubnet(dst.ip.address,'192.168.0.0/16'))
!(net_ipsubnet(dst.ip.address,'127.0.0.0/8'))
!(net_ipsubnet(dst.ip.address,'169.254.0.0/16'))
| columns event.time, endpoint.name, src.process.user, src.process.name, dst.ip.address, dst.port.number, agent.uuid
| limit 200Looks for: the signed sideload host in the wrong place. COTFileReadApp.exe (Canon, V1) and DeElevate64.exe (Stardock, V2) are genuine signed binaries, which is exactly why a hash or signature check passes. Genuine installs live under Program Files; this campaign's MSI installs the host to a fake product folder under the per-user %LOCALAPPDATA%\Programs\ tree and launches it from an install custom action. Detect only: the binary is legitimate vendor software, so this query must never feed a block rule.
Known limitations and deployment notes
- PowerQuery: A host copied to a path outside AppData\Local\Programs is not captured.
- PowerQuery assumes: On Process Creation, tgt.process.* is the new process and src.process.* is its creator, so the CQL FileName maps to tgt.process.name and ParentBaseFileName to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
// HUNT: signed Canon or Stardock sideload host executing from the per-user LocalAppData Programs tree // MITRE: T1574.002, T1036.005 // CONF: high | FP: low | COST: low | REQUIRES: process creation with image path // FALSE POSITIVES: a user who genuinely installs the vendor software per-user (very rare for either product) // NOTE: both binaries are legitimately signed vendor software. Detect only, never prevent. // SOURCE: Huntress 2026-09-28 (host runs from %LOCALAPPDATA%\Programs\ instead of a real Canon or Stardock install) #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(COTFileReadApp|DeElevate64)\.exe$/i | ImageFileName=/\\AppData\\Local\\Programs\\/i | table([@timestamp, ComputerName, UserName, FileName, ImageFileName, ParentBaseFileName, SHA256HashData, CommandLine, aid], limit=200)
5 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nametgt.process.name: Created process nametgt.process.image.path: Created image path
Recommended fields
src.process.name: Creator or acting processsrc.process.user: src.process.user
Optional fields
tgt.process.image.sha256: Created image SHA-256tgt.process.cmdline: Created command line
Readiness test
event.type = 'Process Creation' endpoint.name = * tgt.process.name = * tgt.process.image.path = * | limit 5 | columns event.type, event.time, endpoint.name, tgt.process.name, tgt.process.image.path
// HUNT: signed Canon or Stardock sideload host executing from the per-user LocalAppData Programs tree
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1574.002, T1036.005
// CONF: high | FP: low
// FALSE POSITIVES: a user who genuinely installs the vendor software per-user (very rare for either product)
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the signed Canon or Stardock host running from the per-user Programs tree. FileName maps to tgt.process.name and ImageFileName to tgt.process.image.path.
// REQUIRES: SentinelOne Process Creation telemetry with image paths
// TUNING: No exclusions expected. Both binaries are legitimately signed vendor software: detect only, never prevent.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: A host copied to a path outside AppData\Local\Programs is not captured.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation'
tgt.process.name in:anycase ('COTFileReadApp.exe','DeElevate64.exe')
tgt.process.image.path matches '\\\\AppData\\\\Local\\\\Programs\\\\'
| columns event.time, endpoint.name, src.process.user, tgt.process.name, tgt.process.image.path, src.process.name, tgt.process.image.sha256, tgt.process.cmdline, agent.uuid
| limit 200Looks for: the behaviour that survives the next costume change. Huntress found a third installer on the same server and expects other signed applications to be rotated in, so name-based detections will miss them. The MSI custom action starts the signed app straight after install, so the parent is msiexec.exe and the image sits under %LOCALAPPDATA%\Programs\. FP: legitimate per-user MSI installers that launch the app on finish.
Known limitations and deployment notes
- PowerQuery: hosts is approximate at high cardinality.
- PowerQuery assumes: On Process Creation, tgt.process.* is the new process and src.process.* is its creator, so the CQL FileName maps to tgt.process.name and ParentBaseFileName to src.process.name.
- PowerQuery assumes: hosts uses estimate_distinct, which is approximate; the CQL count is exact.
- PowerQuery assumes: first_seen is the earliest event.time in the group.
// HUNT: executable started by msiexec from the per-user LocalAppData Programs tree (any signed-host swap) // MITRE: T1218.007, T1574.002 // CONF: medium | FP: medium | COST: low | REQUIRES: process creation with image path and parent // FALSE POSITIVES: per-user MSI installers that launch the product at the end of setup // TUNING: build an exclusion list of vendor folders you deploy per-user (for example your collaboration and editor clients) and exclude them by ImageFileName; review the rest by publisher and prevalence // SOURCE: Huntress 2026-09-28 (signed app started by msiexec from a fake product folder under LocalAppData Programs) #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ParentBaseFileName=/^msiexec\.exe$/i | ImageFileName=/\\AppData\\Local\\Programs\\/i | FileName!=/^(msiexec|conhost|cmd|powershell)\.exe$/i | groupBy([FileName, ImageFileName], function=[count(aid, distinct=true, as=Hosts), count(as=Launches), min(@timestamp, as=FirstSeen)], limit=500) | sort(Hosts, order=asc, limit=200)
6 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.type: Event typeevent.time: Event timesrc.process.name: Creator or acting processtgt.process.name: Created process nametgt.process.image.path: Created image pathagent.uuid: Agent identifier
Readiness test
event.type = 'Process Creation' src.process.name = * tgt.process.name = * tgt.process.image.path = * agent.uuid = * | limit 5 | columns event.type, event.time, src.process.name, tgt.process.name, tgt.process.image.path, agent.uuid
// HUNT: executable started by msiexec from the per-user LocalAppData Programs tree (any signed-host swap)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1218.007, T1574.002
// CONF: medium | FP: medium
// FALSE POSITIVES: per-user MSI installers that launch the product at the end of setup
// EQUIVALENCE: equivalent-with-schema-assumptions - Same population: executables created by msiexec under the per-user Programs tree, grouped by name and path with host and launch counts, rarest first.
// REQUIRES: SentinelOne Process Creation telemetry with image paths
// TUNING: Build an exclusion list of vendor folders you deploy per-user (for example your collaboration and editor clients) and exclude them by tgt.process.image.path; review the rest by publisher and prevalence.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: hosts is approximate at high cardinality.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation'
src.process.name in:anycase ('msiexec.exe')
tgt.process.image.path matches '\\\\AppData\\\\Local\\\\Programs\\\\'
!(tgt.process.name in:anycase ('msiexec.exe','conhost.exe','cmd.exe','powershell.exe'))
| group hosts = estimate_distinct(agent.uuid), launches = count(), first_seen = min(event.time) by tgt.process.name, tgt.process.image.path
| sort +hosts
| limit 200Looks for: the dropped component set. The MSI writes the patched logging DLL and its helpers next to the signed host: ceiinfolog.dll, rdCore.dll, WPFLocalizeExtension.dll, WMPCL.dll (V1) and DeElevator64.dll, I++u.dll, senddmp.resources.dll, res.dll (V2). Huntress notes WPFLocalizeExtension.dll borrows the name of a real open-source library, so the path restriction is what keeps this usable. This is a file-write view; it shows the staging, not the DLL load itself. FP: genuine WPF applications installed per-user that ship the real WPFLocalizeExtension.dll.
⚠ Validate in tenant: the file-path field on PeFileWritten and NewExecutableWritten is TargetFileName on most sensors; confirm on yours.
Known limitations and deployment notes
- PowerQuery: A DLL written by a kernel path with no file event is not captured.
- PowerQuery: Per-user installs of genuine WPF applications that ship WPFLocalizeExtension.dll will match.
- PowerQuery assumes: On non-Process-Creation events the acting process is src.process.*, so the CQL ContextBaseFileName maps to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
- PowerQuery assumes: The regex backslashes are double-escaped as PowerQuery requires.
// HUNT: Custom GPT ClickFix sideload component DLLs written under the per-user Programs tree (V1 Canon and V2 Stardock sets) // MITRE: T1574.002, T1036.005 // CONF: high | FP: medium | COST: low | REQUIRES: PeFileWritten or NewExecutableWritten (TargetFileName: validate in tenant) // FALSE POSITIVES: per-user installs of genuine WPF applications that ship WPFLocalizeExtension.dll; res.dll is a generic name // TUNING: for WPFLocalizeExtension.dll and res.dll require a second signal on the same aid (Q6, Q7 or Q4 within 24h) before alerting; ceiinfolog, rdCore, WMPCL, DeElevator64, I++u and senddmp.resources are distinctive on their own #event_simpleName=/^(PeFileWritten|NewExecutableWritten)$/ | TargetFileName=/\\AppData\\Local\\Programs\\/i | TargetFileName=/\\(ceiinfolog|rdCore|WPFLocalizeExtension|WMPCL|DeElevator64|I\+\+u|senddmp\.resources|res)\.dll$/i | table([@timestamp, ComputerName, UserName, ContextBaseFileName, TargetFileName, SHA256HashData, aid], limit=200)
4 required fields · View requirements
Required telemetry
- File Creation
- File Modification
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nametgt.file.path: Written file path
Recommended fields
src.process.name: Creator or acting processsrc.process.user: src.process.user
Optional fields
tgt.file.sha256: Written file SHA-256
Readiness test
event.type in ('File Creation','File Modification') endpoint.name = * tgt.file.path = *
| limit 5
| columns event.type, event.time, endpoint.name, tgt.file.path// HUNT: Custom GPT ClickFix sideload component DLLs written under the per-user Programs tree (V1 Canon and V2 Stardock sets)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1574.002, T1036.005
// CONF: high | FP: medium
// FALSE POSITIVES: per-user installs of genuine WPF applications that ship WPFLocalizeExtension.dll; res.dll is a generic name
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a sideload component DLL name written under the per-user Programs tree. Falcon PE-written events map to File Creation and File Modification, which also cover non-PE files, so the dll extension test carries the PE filter.
// REQUIRES: SentinelOne File Creation and File Modification telemetry
// TUNING: For WPFLocalizeExtension.dll and res.dll require a second signal on the same agent.uuid (Q6, Q7 or Q4 within 24h) before alerting; ceiinfolog, rdCore, WMPCL, DeElevator64, I++u and senddmp.resources are distinctive on their own.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: A DLL written by a kernel path with no file event is not captured. Per-user installs of genuine WPF applications that ship WPFLocalizeExtension.dll will match.
// VALIDATION LEVEL: static-reviewed
event.type in ('File Creation','File Modification')
tgt.file.path matches '\\\\AppData\\\\Local\\\\Programs\\\\'
tgt.file.path matches '\\\\(ceiinfolog|rdCore|WPFLocalizeExtension|WMPCL|DeElevator64|I\\+\\+u|senddmp\\.resources|res)\\.dll$'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.file.path, tgt.file.sha256, agent.uuid
| limit 200Looks for: the carrier files read by the sideloaded DLLs. V1 hides the loader in Common.Integrator.Preview.wav (a real WAV header with the audio section overwritten by ciphertext) and keeps the RAT in monitor.raw. V2 moves the loader into Build.dat, a NuGet package, and renames the archive execute_engine_disconnect.raw. The query watches for those names being opened. A WAV or .raw file is not a PE, so the PE-written events never see it; this relies on file-open telemetry, which is sensor-policy dependent. Treat a hit as high value and a miss as inconclusive.
⚠ Validate in tenant: FileOpenInfo is not collected by every sensor policy and its file-name field can differ. Run the event filter alone first (gate G1). If it returns nothing, use native hunt N5 (file-system sweep) instead.
Known limitations and deployment notes
- PowerQuery: File opens are not visible: a carrier file that was staged before the agent was installed or only read is not captured.
- PowerQuery: Build.dat is matched as a write by DeElevate64.exe, not an open by it; the other three names are matched on any writer, as in the CQL.
- PowerQuery assumes: On non-Process-Creation events the acting process is src.process.*, so the CQL ContextBaseFileName maps to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
// HUNT: open of the Custom GPT ClickFix loader and storage carrier files (WAV, monitor.raw, Build.dat, execute_engine_disconnect.raw) // MITRE: T1027, T1027.013, T1574.002 // CONF: medium | FP: low | COST: low | REQUIRES: FileOpenInfo (validate in tenant) // FALSE POSITIVES: Build.dat is a generic name, so it only counts when opened by DeElevate64.exe #event_simpleName=FileOpenInfo | FileName=/^(Common\.Integrator\.Preview\.wav|monitor\.raw|execute_engine_disconnect\.raw)$/i or (FileName=/^Build\.dat$/i and ContextBaseFileName=/^DeElevate64\.exe$/i) | table([@timestamp, ComputerName, UserName, ContextBaseFileName, FileName, FilePath, aid], limit=200)
4 required fields · View requirements
Required telemetry
- File Creation
- File Modification
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nametgt.file.path: Written file path
Recommended fields
src.process.name: Creator or acting processsrc.process.user: src.process.user
Readiness test
event.type in ('File Creation','File Modification') endpoint.name = * tgt.file.path = *
| limit 5
| columns event.type, event.time, endpoint.name, tgt.file.path// HUNT: open of the Custom GPT ClickFix loader and storage carrier files (WAV, monitor.raw, Build.dat, execute_engine_disconnect.raw)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1027, T1027.013, T1574.002
// CONF: medium | FP: low
// FALSE POSITIVES: Build.dat is a generic name, so it only counts when opened by DeElevate64.exe
// EQUIVALENCE: telemetry-gap - The CQL reads Falcon file-open events. SentinelOne has no attested file-open event, so this partial pivot finds the carrier files being written instead, and Build.dat written by DeElevate64.exe instead of opened by it.
// REQUIRES: SentinelOne File Creation and File Modification telemetry
// TUNING: Treat a hit as the carrier file existing on disk, not as the loader reading it; pivot to Q6 for the host process.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: File opens are not visible: a carrier file that was staged before the agent was installed or only read is not captured. Build.dat is matched as a write by DeElevate64.exe, not an open by it; the other three names are matched on any writer, as in the CQL.
// VALIDATION LEVEL: static-reviewed
event.type in ('File Creation','File Modification')
(tgt.file.path matches '\\\\(Common\\.Integrator\\.Preview\\.wav|monitor\\.raw|execute_engine_disconnect\\.raw)$' or (tgt.file.path matches '\\\\Build\\.dat$' and src.process.name in:anycase ('DeElevate64.exe')))
| columns event.type, event.time, endpoint.name, src.process.user, src.process.name, tgt.file.path, agent.uuid
| limit 200Looks for: the two persistence artefacts the implant creates. The same name is used for an HKCU Run value and a scheduled task: Canon Configuration Reader (V1) and Stardock DeElevation Tool (V2). Both launch the signed host. Legitimate Canon or Stardock products do not register persistence under these names per Huntress. Includes the schtasks.exe command-line route for completeness; the implant itself most likely registers through the task API, so the task-registered event is the main source.
⚠ Validate in tenant: ScheduledTaskRegistered and its TaskName field vary by sensor version. The Run-key and schtasks branches work without it.
Known limitations and deployment notes
- PowerQuery: A task registered through the Task Scheduler API without schtasks.exe and without a monitored TaskCache write is not captured.
- PowerQuery assumes: On Process Creation, tgt.process.* is the new process and src.process.* is its creator, so the CQL FileName maps to tgt.process.name and ParentBaseFileName to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
- PowerQuery assumes: Task registration is assumed to write a TaskCache Tree key named after the task, visible in registry.keyPath.
// HUNT: Run value or scheduled task named Canon Configuration Reader or Stardock DeElevation Tool (Custom GPT ClickFix RAT persistence) // MITRE: T1547.001, T1053.005, T1036.005 // CONF: high | FP: low | COST: low | REQUIRES: ScheduledTaskRegistered (validate in tenant), AsepValueUpdate, ProcessRollup2 // FALSE POSITIVES: none expected. Genuine Canon and Stardock products do not use these names // SOURCE: Huntress 2026-09-28 (both Run value and scheduled task carry the same name; later wave uses the Stardock name) #event_simpleName=/^(ScheduledTaskRegistered|AsepValueUpdate|RegGenericValueUpdate|ProcessRollup2|SyntheticProcessRollup2)$/ | TaskName=/(Canon Configuration Reader|Stardock DeElevation Tool)/i or RegValueName=/^(Canon Configuration Reader|Stardock DeElevation Tool)$/i or (FileName=/^schtasks\.exe$/i and CommandLine=/(Canon Configuration Reader|Stardock DeElevation Tool)/i) | table([@timestamp, ComputerName, UserName, #event_simpleName, TaskName, TaskExecutable, RegObjectName, RegValueName, RegStringValue, CommandLine, aid], limit=200)
3 required fields · View requirements
Required telemetry
- Registry Value Modified
- Process Creation
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host name
Recommended fields
src.process.name: Creator or acting processsrc.process.user: src.process.user
Optional fields
registry.keyPath: Registry key pathregistry.valueName: Registry value nameregistry.value: Registry value datatgt.process.cmdline: Created command line
Readiness test
event.type in ('Registry Value Modified','Process Creation') endpoint.name = *
| limit 5
| columns event.type, event.time, endpoint.name// HUNT: Run value or scheduled task named Canon Configuration Reader or Stardock DeElevation Tool (Custom GPT ClickFix RAT persistence)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1547.001, T1053.005, T1036.005
// CONF: high | FP: low
// FALSE POSITIVES: none expected. Genuine Canon and Stardock products do not use these names
// EQUIVALENCE: approximate-analytic - SentinelOne has no attested scheduled-task-registered event. The query matches the Run value name, the Task Scheduler TaskCache registry key for the same name, and schtasks.exe naming it on the command line.
// REQUIRES: SentinelOne Registry Value Modified and Process Creation telemetry
// TUNING: No exclusions expected: genuine Canon and Stardock products do not use these names.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: A task registered through the Task Scheduler API without schtasks.exe and without a monitored TaskCache write is not captured.
// VALIDATION LEVEL: static-reviewed
(event.type = 'Registry Value Modified' (registry.valueName matches '^(Canon Configuration Reader|Stardock DeElevation Tool)$' or registry.keyPath matches 'Schedule\\\\TaskCache\\\\Tree\\\\(Canon Configuration Reader|Stardock DeElevation Tool)')) or (event.type = 'Process Creation' tgt.process.name in:anycase ('schtasks.exe') tgt.process.cmdline matches '(Canon Configuration Reader|Stardock DeElevation Tool)')
| columns event.type, event.time, endpoint.name, src.process.user, src.process.name, registry.keyPath, registry.valueName, registry.value, tgt.process.cmdline, agent.uuid
| limit 200Looks for: the recreation behaviour. The persistence script in monitor.raw re-checks the Run value every 150 seconds and the scheduled task every 875 seconds, and rewrites the Run value again at shutdown, so removing one artefact while the implant runs brings it back within minutes. The query is name-agnostic on purpose, because the operators change names by shipping a new monitor.raw. It groups task registrations and Run-value writes by host and name and keeps those written more than once within two hours. FP: updaters and sync clients that rewrite their own autostart on every launch.
Known limitations and deployment notes
- PowerQuery: Scheduled task re-registration is not visible, so the task half of the self-healing signal is missing.
- PowerQuery: The span greater than zero and below 120 minutes filter is not applied; use a short console time range instead.
- PowerQuery assumes: Autostart coverage is limited to the Run and RunOnce keys; other autostart locations in the CQL ASEP event are not covered.
- PowerQuery assumes: first_seen and last_seen are returned so the span can be read; set the console range to 2h to approximate the CQL span below 120 minutes.
// HUNT: same scheduled task or autostart value written repeatedly on one host within hours (implant self-healing) // MITRE: T1053.005, T1547.001 // CONF: medium | FP: medium | COST: medium | REQUIRES: ScheduledTaskRegistered (validate in tenant), AsepValueUpdate // FALSE POSITIVES: browser, collaboration and cloud-sync updaters that rewrite their own autostart entry // TUNING: exclude the vendor names that top the first 30-day run (updater tasks and Run values), and exclude names that appear on more than a handful of hosts; keep names that appear on one host only or whose executable sits under AppData\Local\Programs // SOURCE: Huntress 2026-09-28 (Run key re-created every 150 s, task every 875 s) #event_simpleName=/^(ScheduledTaskRegistered|AsepValueUpdate)$/ | persist_name := coalesce([TaskName, RegValueName]) | persist_name=* | groupBy([aid, ComputerName, persist_name], function=[count(as=Writes), min(@timestamp, as=FirstSeen), max(@timestamp, as=LastSeen), collect([TaskExecutable, RegStringValue])], limit=2000) | Writes > 1 | SpanMin := (LastSeen - FirstSeen) / 60000 | SpanMin > 0 | SpanMin < 120 | sort(Writes, order=desc, limit=200)
6 required fields · View requirements
Required telemetry
- Registry Value Modified
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nameregistry.keyPath: Registry key pathregistry.valueName: Registry value nameagent.uuid: Agent identifier
Optional fields
registry.value: Registry value data
Readiness test
event.type = 'Registry Value Modified' endpoint.name = * registry.keyPath = * registry.valueName = * agent.uuid = * | limit 5 | columns event.type, event.time, endpoint.name, registry.keyPath, registry.valueName, agent.uuid
// HUNT: same scheduled task or autostart value written repeatedly on one host within hours (implant self-healing) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1053.005, T1547.001 // CONF: medium | FP: medium // FALSE POSITIVES: browser, collaboration and cloud-sync updaters that rewrite their own autostart entry // EQUIVALENCE: telemetry-gap - Partial pivot: the Run and RunOnce half of the CQL, a value rewritten more than once per host. The scheduled-task half and the in-query span filter are not expressible, so the console time range carries the window. // REQUIRES: SentinelOne Registry Value Modified telemetry for the Run keys // TUNING: Exclude the vendor names that top the first 30-day run (updater Run values), and exclude names that appear on more than a handful of hosts; keep names on one host only or whose executable sits under AppData\Local\Programs. // LOOKBACK: 2h in the console time range approximates the CQL span; widen only to review // CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule. // KNOWN GAPS: Scheduled task re-registration is not visible, so the task half of the self-healing signal is missing. The span greater than zero and below 120 minutes filter is not applied; use a short console time range instead. // VALIDATION LEVEL: static-reviewed event.type = 'Registry Value Modified' registry.keyPath matches '\\\\CurrentVersion\\\\Run(Once)?(\\\\|$)' registry.valueName = * | group writes = count(), first_seen = min(event.time), last_seen = max(event.time), value_data = any(registry.value) by agent.uuid, host = endpoint.name, persist_name = registry.valueName | filter writes > 1 | sort -writes | limit 200
Looks for: the C2 channel from the host process. The RAT finds its C2 ("Gate") through DNS-over-HTTPS to Cloudflare, Google and Quad9, so its lookups are ordinary HTTPS to well-known resolver addresses and never appear in local DNS logs. The C2 address was not recovered in any sample. A scanner-utility or display-tool host process making any outbound connection is the signal. FP: a genuine CaptureOnTouch install that phones home for updates.
⚠ Validate in tenant: process attribution on DnsRequest (ContextBaseFileName) depends on sensor version.
Known limitations and deployment notes
- PowerQuery: DNS-over-HTTPS appears as an IP Connect to the resolver, not a DNS Resolved event.
- PowerQuery assumes: On non-Process-Creation events the acting process is src.process.*, so the CQL ContextBaseFileName maps to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
- PowerQuery assumes: event.dns.request is the pySigma-mapped DNS field; some schema versions use dns.request, so run the readiness test first.
// HUNT: Canon or Stardock sideload host process making network connections or DNS lookups (DoH C2 channel) // MITRE: T1071.001, T1572 // CONF: high | FP: medium | COST: low | REQUIRES: NetworkConnectIP4, DnsRequest with process context (validate in tenant) // FALSE POSITIVES: a legitimate CaptureOnTouch or DeElevation install updating itself // TUNING: pivot each hit on the process image path with Q6; a host process running from Program Files on a known scanner workstation is benign, one running from AppData\Local\Programs is not // SOURCE: Huntress 2026-09-28 (DNS-over-HTTPS via Cloudflare, Google and Quad9; C2 address not recovered) #event_simpleName=/^(NetworkConnectIP4|DnsRequest)$/ | ContextBaseFileName=/^(COTFileReadApp|DeElevate64)\.exe$/i | table([@timestamp, ComputerName, UserName, #event_simpleName, ContextBaseFileName, RemoteAddressIP4, RemotePort, DomainName, aid], limit=200)
4 required fields · View requirements
Required telemetry
- IP Connect
- DNS Resolved
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host namesrc.process.name: Creator or acting process
Recommended fields
src.process.user: src.process.userdst.ip.address: Remote IPdst.port.number: Remote port
Optional fields
event.dns.request: DNS name
Readiness test
event.type in ('IP Connect','DNS Resolved') endpoint.name = * src.process.name = *
| limit 5
| columns event.type, event.time, endpoint.name, src.process.name// HUNT: Canon or Stardock sideload host process making network connections or DNS lookups (DoH C2 channel)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1071.001, T1572
// CONF: high | FP: medium
// FALSE POSITIVES: a legitimate CaptureOnTouch or DeElevation install updating itself
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: any network connection or DNS lookup by the Canon or Stardock host process. ContextBaseFileName maps to src.process.name.
// REQUIRES: SentinelOne IP Connect and DNS Resolved telemetry with process context
// TUNING: Pivot each hit on the process image path with Q6; a host running from Program Files on a known scanner workstation is benign, one running from AppData\Local\Programs is not.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: DNS-over-HTTPS appears as an IP Connect to the resolver, not a DNS Resolved event.
// VALIDATION LEVEL: static-reviewed
event.type in ('IP Connect','DNS Resolved')
src.process.name in:anycase ('COTFileReadApp.exe','DeElevate64.exe')
| columns event.type, event.time, endpoint.name, src.process.user, src.process.name, dst.ip.address, dst.port.number, event.dns.request, agent.uuid
| limit 200Looks for: retrospective exposure to the two delivery addresses in the Huntress IOC table. 96.62.224[.]81 hosts the ClickFix script and the MSI and is the address behind the decimal host. 45.140.205[.]28 was a payload server in a related incident. Both are perishable and Huntress states that the server changes between incidents, so a clean result proves little. Rely on Q1 to Q7 for coverage.
Known limitations and deployment notes
- PowerQuery: Addresses are perishable, and an inbound-only contact is not captured.
- PowerQuery assumes: On non-Process-Creation events the acting process is src.process.*, so the CQL ContextBaseFileName maps to src.process.name.
// HUNT: outbound connections to the two published Custom GPT ClickFix delivery IPs (atomic IOC sweep) // MITRE: T1105, T1071.001 // CONF: high | FP: low | COST: low | REQUIRES: NetworkConnectIP4 // FALSE POSITIVES: none expected; both are published delivery addresses // SOURCE: Huntress 2026-09-28 IOC table; 96.62.224.81 also in CyberSecurityNews and the CSA research note; 45.140.205.28 also in the CSA research note #event_simpleName=NetworkConnectIP4 | RemoteAddressIP4=/^(96\.62\.224\.81|45\.140\.205\.28)$/ | table([@timestamp, ComputerName, UserName, ContextBaseFileName, RemoteAddressIP4, RemotePort, aid], limit=200)
4 required fields · View requirements
Required telemetry
- IP Connect
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host namedst.ip.address: Remote IP
Recommended fields
src.process.name: Creator or acting processsrc.process.user: src.process.userdst.port.number: Remote port
Readiness test
event.type = 'IP Connect' endpoint.name = * dst.ip.address = * | limit 5 | columns event.type, event.time, endpoint.name, dst.ip.address
// HUNT: outbound connections to the two published Custom GPT ClickFix delivery IPs (atomic IOC sweep)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1105, T1071.001
// CONF: high | FP: low
// FALSE POSITIVES: none expected; both are published delivery addresses
// EQUIVALENCE: equivalent-with-schema-assumptions - Same exact-address test on the two published delivery IPs.
// REQUIRES: SentinelOne IP Connect telemetry
// TUNING: No exclusions expected; both are published delivery addresses.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: Addresses are perishable, and an inbound-only contact is not captured.
// VALIDATION LEVEL: static-reviewed
event.type = 'IP Connect'
dst.ip.address in ('96.62.224.81','45.140.205.28')
| columns event.time, endpoint.name, src.process.user, src.process.name, dst.ip.address, dst.port.number, agent.uuid
| limit 200Looks for: the eight malicious or patched DLL hashes from the Huntress table (four per wave), matched on executable writes and on process starts. The legitimately signed host hashes are deliberately not in this list. Hashes are single-sourced to Huntress, so this is a detect query, and a miss does not clear a host: the operators rebuild components per wave.
Known limitations and deployment notes
- PowerQuery: The hashes are single-sourced; DLLs that are loaded but never written or started in the window are not captured.
- PowerQuery assumes: Hash population on tgt.file.sha256 and tgt.process.image.sha256 varies by tenant; run the readiness test.
- PowerQuery assumes: in:anycase reproduces the CQL case-insensitive match.
// HUNT: SHA256 sweep for the Custom GPT ClickFix patched and malicious sideload DLLs (V1 Canon set and V2 Stardock set) // MITRE: T1574.002 // CONF: high | FP: low | COST: medium | REQUIRES: SHA256HashData on file-write and process events // FALSE POSITIVES: none expected for these hashes // SOURCE: Huntress 2026-09-28 IOC table (single source) #event_simpleName=/^(PeFileWritten|NewExecutableWritten|ProcessRollup2|SyntheticProcessRollup2)$/ | SHA256HashData=/^(e58831766e8d4313db9f8b85f90c3a840aa0d84cfeac285beefa40e39ad0d1fb|b77575413c0f97eaf31e4a44c884c1ecdc0049ec89916ceb0bf3aaaedc0442fe|eff5d63ddf1813962f0d8ad1250cea5486c8bb5dd27c3f432b43957a33e43764|9c615db040b88c18ce6b96f30d08797045b7d506f940bea452dc7a6992fdbb8d|0457414c4504b70115798eee9c8384a8bf9e793461ffb2e0661a6dcc6ed4809f|3cd1484cc5bf10e22d79784beba58a75d7b126c46efb5e1a85d6aab884447621|b59a21a8d4c0c11a9ecbbdbe2a2938499c99c5ebb210c9c6db9683c7ad19f4c4|a27cafb84876a3374ef4aba1062345def6cd0b029eaf8e0dc44fa24fc943f3c6)$/i | table([@timestamp, ComputerName, UserName, #event_simpleName, FileName, TargetFileName, ImageFileName, SHA256HashData, aid], limit=200)
5 required fields · View requirements
Required telemetry
- File Creation
- File Modification
- Process Creation
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nametgt.file.sha256: Written file SHA-256tgt.process.image.sha256: Created image SHA-256
Recommended fields
tgt.process.name: Created process nametgt.file.path: Written file path
Optional fields
tgt.process.image.path: Created image path
Readiness test
event.type in ('File Creation','File Modification','Process Creation') endpoint.name = *
| limit 5
| columns event.type, event.time, endpoint.name, tgt.file.sha256, tgt.process.image.sha256// HUNT: SHA256 sweep for the Custom GPT ClickFix patched and malicious sideload DLLs (V1 Canon set and V2 Stardock set)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1574.002
// CONF: high | FP: low
// FALSE POSITIVES: none expected for these hashes
// EQUIVALENCE: equivalent-with-schema-assumptions - Same eight published SHA-256 values tested on file writes and on process creation.
// REQUIRES: SentinelOne File and Process Creation events with SHA-256 populated
// TUNING: Hashes change on rebuild; treat a miss as no evidence.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: The hashes are single-sourced; DLLs that are loaded but never written or started in the window are not captured.
// VALIDATION LEVEL: static-reviewed
(event.type in ('File Creation','File Modification') tgt.file.sha256 in:anycase ('e58831766e8d4313db9f8b85f90c3a840aa0d84cfeac285beefa40e39ad0d1fb','b77575413c0f97eaf31e4a44c884c1ecdc0049ec89916ceb0bf3aaaedc0442fe','eff5d63ddf1813962f0d8ad1250cea5486c8bb5dd27c3f432b43957a33e43764','9c615db040b88c18ce6b96f30d08797045b7d506f940bea452dc7a6992fdbb8d','0457414c4504b70115798eee9c8384a8bf9e793461ffb2e0661a6dcc6ed4809f','3cd1484cc5bf10e22d79784beba58a75d7b126c46efb5e1a85d6aab884447621','b59a21a8d4c0c11a9ecbbdbe2a2938499c99c5ebb210c9c6db9683c7ad19f4c4','a27cafb84876a3374ef4aba1062345def6cd0b029eaf8e0dc44fa24fc943f3c6')) or (event.type = 'Process Creation' tgt.process.image.sha256 in:anycase ('e58831766e8d4313db9f8b85f90c3a840aa0d84cfeac285beefa40e39ad0d1fb','b77575413c0f97eaf31e4a44c884c1ecdc0049ec89916ceb0bf3aaaedc0442fe','eff5d63ddf1813962f0d8ad1250cea5486c8bb5dd27c3f432b43957a33e43764','9c615db040b88c18ce6b96f30d08797045b7d506f940bea452dc7a6992fdbb8d','0457414c4504b70115798eee9c8384a8bf9e793461ffb2e0661a6dcc6ed4809f','3cd1484cc5bf10e22d79784beba58a75d7b126c46efb5e1a85d6aab884447621','b59a21a8d4c0c11a9ecbbdbe2a2938499c99c5ebb210c9c6db9683c7ad19f4c4','a27cafb84876a3374ef4aba1062345def6cd0b029eaf8e0dc44fa24fc943f3c6'))
| columns event.type, event.time, endpoint.name, src.process.user, tgt.process.name, tgt.file.path, tgt.file.sha256, tgt.process.image.path, tgt.process.image.sha256, agent.uuid
| limit 200Looks for: the most common follow-on Huntress saw after the RAT came up: a legitimately signed GOMCam2024.exe dropped into %LOCALAPPDATA%\AppstorageFile\, which then launched chrome.exe with a throwaway profile under the temp folder. The binary is legitimate software, so this is detect only. It is a post-compromise confirmation signal, not an early-warning one, and Huntress notes GOMCam was not the only follow-on.
Known limitations and deployment notes
- PowerQuery: A payload renamed and run from a different folder is not captured.
- PowerQuery assumes: On Process Creation, tgt.process.* is the new process and src.process.* is its creator, so the CQL FileName maps to tgt.process.name and ParentBaseFileName to src.process.name.
- PowerQuery assumes: PowerQuery matches and contains are case-insensitive by default and the name lists use in:anycase, reproducing the CQL /i regex.
// HUNT: GOMCam2024.exe running from the AppstorageFile folder, or Chrome started with a temp-folder profile by it (RAT follow-on) // MITRE: T1105, T1036.005 // CONF: medium | FP: low | COST: low | REQUIRES: process creation with image path and parent // FALSE POSITIVES: a user who genuinely installed GOM Cam into this unusual folder (no known vendor path uses AppstorageFile) // NOTE: GOMCam2024.exe is legitimately signed software. Detect only, never prevent. // SOURCE: Huntress 2026-09-28 (GOMCam2024.exe in %LOCALAPPDATA%\AppstorageFile\ was the usual next step) #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ImageFileName=/\\AppData\\Local\\AppstorageFile\\/i or (FileName=/^chrome\.exe$/i and ParentBaseFileName=/^GOMCam2024\.exe$/i) | table([@timestamp, ComputerName, UserName, FileName, ImageFileName, ParentBaseFileName, CommandLine, SHA256HashData, aid], limit=200)
6 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.type: Event typeevent.time: Event timeendpoint.name: Host nametgt.process.name: Created process nametgt.process.image.path: Created image pathsrc.process.name: Creator or acting process
Recommended fields
src.process.user: src.process.usertgt.process.cmdline: Created command line
Optional fields
tgt.process.image.sha256: Created image SHA-256
Readiness test
event.type = 'Process Creation' endpoint.name = * src.process.name = * tgt.process.name = * tgt.process.image.path = * | limit 5 | columns event.type, event.time, endpoint.name, tgt.process.name, tgt.process.image.path, src.process.name
// HUNT: GOMCam2024.exe running from the AppstorageFile folder, or Chrome started with a temp-folder profile by it (RAT follow-on)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1105, T1036.005
// CONF: medium | FP: low
// FALSE POSITIVES: a user who genuinely installed GOM Cam into this unusual folder (no known vendor path uses AppstorageFile)
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: any process from the AppstorageFile folder, or chrome.exe created by GOMCam2024.exe. FileName and ImageFileName map to tgt.process.name and tgt.process.image.path; the parent maps to src.process.name.
// REQUIRES: SentinelOne Process Creation telemetry with image paths and parent names
// TUNING: No exclusions expected. GOMCam2024.exe is legitimately signed software: detect only, never prevent.
// LOOKBACK: 30d; set the console time range or the query window to cover the exposure period
// CONFIGURATION: No lookup tables or custom detection objects required; paste the query into Event Search or a scheduled PowerQuery rule.
// KNOWN GAPS: A payload renamed and run from a different folder is not captured.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation'
(tgt.process.image.path matches '\\\\AppData\\\\Local\\\\AppstorageFile\\\\' or (tgt.process.name in:anycase ('chrome.exe') and src.process.name in:anycase ('GOMCam2024.exe')))
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.image.path, tgt.process.cmdline, tgt.process.image.sha256, agent.uuid
| limit 200Detection Rules by Platform
Four queries are clean enough to promote to Custom IOA. Every rule is detect-only (Monitor). No rule blocks anything. Three of the four anchor on legitimately signed or built-in binaries (powershell.exe, msiexec.exe, COTFileReadApp.exe, DeElevate64.exe), which must never be blocked. The only prevent action in this pack is the IOC Management entry for 96.62.224[.]81.
CrowdStrike: Custom IOA
| IOA name | From | Rule group / type | Pattern | Exclusions | Action |
|---|---|---|---|---|---|
| CustomGPT-ClickFix, PowerShell Fetch From Decimal IP | Promote Q1 | Process Creation (Windows) | Image powershell.exe or pwsh.exe; command line contains a fetch cmdlet followed by an 8 to 10 digit integer or 0x hex host | None known | Detect: High |
| CustomGPT-ClickFix, PowerShell Spawns Silent msiexec | Promote Q4 | Process Creation (Windows) | Image msiexec.exe; parent powershell.exe; command line has .msi, a quiet switch and a Temp or AppData path | Software deployment that stages MSIs in Temp via PowerShell | Detect: High (never Block: stock binaries) |
| CustomGPT-ClickFix, Signed Sideload Host in LocalAppData Programs | Promote Q6 | Process Creation (Windows) | Image file name COTFileReadApp.exe or DeElevate64.exe with an image path under \AppData\Local\Programs\ | None known | Detect: High (never Block: legitimate signed vendor software) |
| CustomGPT-ClickFix, Named Persistence | Promote Q10 | Registry Operation / Scheduled Task (Windows) | Run value name or task name Canon Configuration Reader or Stardock DeElevation Tool | None | Detect: High |
Deployment path
- Endpoint security → Configuration → Custom IOA rule groups. Create a group named for this campaign and attach it to a pilot prevention policy.
- Create each rule at Monitor (detect-only) and leave it for one business week.
- Do not raise any rule to Block. A block rule on a PowerShell, msiexec or signed vendor-binary pattern will eventually disrupt benign activity, and the signed hosts will be swapped for other vendors anyway.
- Import the section 10 CSV into IOC Management. Only
96.62.224[.]81imports as prevent. Delete theREPLACE_WITH_C2_GATE_DOMAINrow before import.
Investigate-only queries
- Q2, Q3, Q5, Q7, Q8, Q9, Q11, Q12, Q14, Q15: run as scheduled searches to a hunt queue; their FP profile needs a local baseline before alerting.
- Correlation is where fidelity lives. Any host hitting two or more of Q1 to Q12 within 24 hours should escalate regardless of the individual ratings.
SentinelOne: custom detection rules
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| CustomGPT-ClickFix, PowerShell Fetch From Decimal IP | Q1, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device". This pack's own text mentions a baseline or pilot; follow it as written |
| CustomGPT-ClickFix, PowerShell Spawns Silent msiexec | Q4, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device". This pack's own text mentions a baseline or pilot; follow it as written |
| CustomGPT-ClickFix, Signed Sideload Host in LocalAppData Programs | Q6, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device". This pack's own text mentions a baseline or pilot; follow it as written |
| CustomGPT-ClickFix, Named Persistence | Q10, PowerQuery tab | Hunt only until the gap is closed | Q10 is only an approximation here. SentinelOne has no attested scheduled-task-registered event. The query matches the Run value name, the Task Scheduler TaskCache registry key for the same name, and schtasks.exe naming it on the command line.. This pack's own text mentions a baseline or pilot; follow it as written |
Create the rule with POST /web/api/v2.1/cloud-detection/rules, queryType: "scheduled" and queryLang: "2.0", with the query in data.scheduledParams.query. Use 2.0 operator spellings: a rule written with the 1.0 token ContainsCIS was accepted and never fired on a tenant. The API does not warn, so lint the body before deploying.
Machine-Readable IOC Appendix
Read before importing: only 96.62.224[.]81 imports as prevent (Huntress, CyberSecurityNews and the CSA note). Everything else is detect: all hashes are single-sourced to Huntress, and the two signed vendor host hashes are legitimate software at low severity. URLs on chatgpt.com and sites.google.com are deliberately not in the CSV because they would block legitimate platforms. The REPLACE_WITH_C2_GATE_DOMAIN row is a placeholder: Huntress did not recover the C2 address. Delete it before import.
type,value,action,severity,expiration,description,tags ipv4,96.62.224.81,prevent,critical,2027-01-11,Custom GPT ClickFix script and MSI delivery server (decimal host 1614733393); Huntress + CyberSecurityNews + CSA note,campaign:CustomGPTClickFixRAT ipv4,45.140.205.28,detect,high,2027-04-11,Payload server seen in a related incident; Huntress + CSA note only; delivery infrastructure varies per incident,campaign:CustomGPTClickFixRAT sha256,6761aad48a3f987238994d92bca97e4b8550e0150607bd67b47b1b6366a371fc,detect,high,2027-04-11,V1 installer Advanced Printer Configuration Reader; single source Huntress,campaign:CustomGPTClickFixRAT sha256,91a22cf3154944897cbcaffc7d20d4596e972d280ee134197d41d8d8eefb0fe2,detect,high,2027-04-11,V2 installer Stardock Smart DeElevation Tool; single source Huntress,campaign:CustomGPTClickFixRAT sha256,e58831766e8d4313db9f8b85f90c3a840aa0d84cfeac285beefa40e39ad0d1fb,detect,critical,2027-04-11,V1 patched Canon logging DLL; signature stripped; imports rdCore.dll; single source Huntress,campaign:CustomGPTClickFixRAT sha256,b77575413c0f97eaf31e4a44c884c1ecdc0049ec89916ceb0bf3aaaedc0442fe,detect,critical,2027-04-11,V1 unsigned loader DLL that decodes the WAV carrier; single source Huntress,campaign:CustomGPTClickFixRAT sha256,eff5d63ddf1813962f0d8ad1250cea5486c8bb5dd27c3f432b43957a33e43764,detect,high,2027-04-11,V1 malicious native DLL borrowing an open-source library name; single source Huntress,campaign:CustomGPTClickFixRAT sha256,9c615db040b88c18ce6b96f30d08797045b7d506f940bea452dc7a6992fdbb8d,detect,high,2027-04-11,V1 helper DLL loaded by rdCore.dll; single source Huntress,campaign:CustomGPTClickFixRAT sha256,0457414c4504b70115798eee9c8384a8bf9e793461ffb2e0661a6dcc6ed4809f,detect,critical,2027-04-11,V2 patched Stardock DLL; imports I++u.dll; single source Huntress,campaign:CustomGPTClickFixRAT sha256,3cd1484cc5bf10e22d79784beba58a75d7b126c46efb5e1a85d6aab884447621,detect,critical,2027-04-11,V2 loader DLL with fake SharpCompress version info; single source Huntress,campaign:CustomGPTClickFixRAT sha256,b59a21a8d4c0c11a9ecbbdbe2a2938499c99c5ebb210c9c6db9683c7ad19f4c4,detect,high,2027-04-11,V2 alloc and exec helper DLL; single source Huntress,campaign:CustomGPTClickFixRAT sha256,a27cafb84876a3374ef4aba1062345def6cd0b029eaf8e0dc44fa24fc943f3c6,detect,high,2027-04-11,V2 network helper DLL; single source Huntress,campaign:CustomGPTClickFixRAT sha256,54c94f85ba6e950903d5ff42c0971c5a9d0741596be26e06afe7d60ec38edf31,detect,high,2027-04-11,V1 WAV carrying the encrypted loader; non-PE; matches only where the sensor hashes it; single source Huntress,campaign:CustomGPTClickFixRAT sha256,e614b7d5a7a363fb1b355a87e2e8d9e8a05bbbca08f2cee3d606bdb5015ac53b,detect,high,2027-04-11,V1 encrypted archive with persistence script and RAT; non-PE; single source Huntress,campaign:CustomGPTClickFixRAT sha256,d3fda1e6cf886fd530bf62e2d16c39ad23ed12a2c933fc211f1f4876ceaa033e,detect,high,2027-04-11,V2 NuGet package carrying the encrypted loader; non-PE; single source Huntress,campaign:CustomGPTClickFixRAT sha256,d5acf44658f0dce90bd160f15d8e07a96938c81661d87dc7e9cb0107863bfb90,detect,high,2027-04-11,V2 encrypted archive; non-PE; single source Huntress,campaign:CustomGPTClickFixRAT sha256,278e2f3e2f26c18666b89ef774b4af9ce954e36b2bf54a2392608619245d8c48,detect,low,2027-04-11,LEGITIMATE Canon-signed host abused for sideload. Do not block globally. Alert only; triage on path (Q6),campaign:CustomGPTClickFixRAT sha256,22869e3326fe1de011cd500e666769027126c5c440b76837baf55139f30094e4,detect,low,2027-04-11,LEGITIMATE Stardock-signed host abused for sideload. Do not block globally. Alert only; triage on path (Q6),campaign:CustomGPTClickFixRAT domain,REPLACE_WITH_C2_GATE_DOMAIN,detect,high,2027-04-11,RAT C2 (Gate) address NOT recovered by Huntress; resolved via DNS-over-HTTPS. Delete this row before import,campaign:CustomGPTClickFixRAT
This pack does not ship a SentinelOne import block: the import format could not be verified against SentinelOne's own documentation. Export a sample from your console and the block can be added with confidence.
Custom GPT ClickFix RAT - behavioral signatures (outlive every domain, hash and host swap) B1 PowerShell web fetch (irm / iwr / DownloadString) addressed to a bare integer or 0x hex host B2 PowerShell launched from explorer, a browser or a terminal host, fetching remote content with bypass or temp staging B3 PowerShell parent of msiexec.exe /i <GUID>_<name>.msi in Temp with a quiet switch B4 Plain-HTTP (port 80) connection to a public IP from powershell.exe or msiexec.exe (no DNS lookup first) B5 msiexec.exe parent of an executable under %LOCALAPPDATA%\Programs\<fake product>\ B6 Signed Canon or Stardock binary (COTFileReadApp.exe, DeElevate64.exe) running from %LOCALAPPDATA%\Programs\ B7 Unsigned or checksum-broken DLL sitting beside the signed host, with a vendor-looking name B8 WAV / .raw / .dat file beside the host opened by the host (WAV with a valid header and noise after offset 0x24362) B9 HKCU Run value AND scheduled task with the same name, both launching the signed host B10 The same Run value or task rewritten every few minutes after deletion (150 s Run, 875 s task) B11 Scanner-utility or display-tool host process opening outbound HTTPS or DNS (DoH to public resolvers) B12 Follow-on: GOMCam2024.exe in %LOCALAPPDATA%\AppstorageFile\ launching chrome.exe with a temp-folder profile URL-LEVEL (proxy or secure web gateway only, never block the parent domain): chatgpt.com/g/g-<id>-plus-5-6 Custom GPT titled "Plus 5.6" (legitimate domain) sites.google.com/view/antibot172881 Google Sites ClickFix lure (legitimate domain) KEY INSIGHT: names change (Canon to Stardock, ISOSimple to IconEdit2Turb, a third installer already seen). The chain does not: PowerShell > msiexec > signed app from a fake product folder > Run value + task that come back.
Entry point : Google sponsored result for "chatgpt" > Custom GPT "Plus 5.6" > Google Sites page posing as a Cloudflare check
Custom GPT status : first removed by OpenAI on 2026-09-25; second seen 2026-09-27
ClickFix launch : PowerShell with -ExecutionPolicy Bypass, web fetch to a decimal-encoded IP host, script written to %TEMP%\<digits>.ps1
Stage-1 script : one 27,581-character line of 3,036 negative integers; two XOR-style layers; deletes itself
MSI : %TEMP%\<32 hex>_ISOSimple.msi (V1) / _IconEdit2Turb.msi (V2); msiexec /qn /norestart; ARPSYSTEMCOMPONENT=1 hides it
Install folder : %LOCALAPPDATA%\Programs\Advanced Printer Configuration Reader\ | ...\Stardock Smart DeElevation Tool\
Signed host : COTFileReadApp.exe (Canon) | DeElevate64.exe (Stardock). Legitimate. Never prevent.
Sideload chain V1 : COTFileReadApp.dll > ceiinfolog.dll (patched) > rdCore.dll > WPFLocalizeExtension.dll + WMPCL.dll
Sideload chain V2 : DeElevate64.exe > DeElevator64.dll (patched) > I++u.dll > senddmp.resources.dll + res.dll
Loader carrier : Common.Integrator.Preview.wav (V1), offset 0x24362, 341,395 bytes | Build.dat NuGet package (V2)
Loader behaviour : AMSI bypass, CLR host, ntdll unhooking, anti-VM checks, fake LOADING window, searches own folder for .bak .db .bin .dat .raw .pak
Storage : monitor.raw (V1) / execute_engine_disconnect.raw (V2): 1,128 index entries, 315 folders, 806 files
Persistence : HKCU Run value + scheduled task, same name: Canon Configuration Reader | Stardock DeElevation Tool
Self-healing : Run value checked every 150 s, task every 875 s; Run rewritten at shutdown. Kill the process first.
RAT : remote desktop and screen broadcast, camera, microphone and system audio, 17 browsers, file manager with content search,
EXE / DLL / MSI / PowerShell / Batch / VBScript / JScript / ZIP execution, DNS-over-HTTPS C2 ("Gate")
Follow-on : GOMCam2024.exe in %LOCALAPPDATA%\AppstorageFile\, chrome.exe with a throwaway profile in %TEMP%
Defender detection : Trojan:Script/Wacatac.H!ml quarantined ISOSimple.msi in one incident AFTER install; persistence continued
Attribution : none. Huntress names no actor. The RAT family is UNNAMED in public reporting.
# Run dialog removed for the user? (note: Windows Terminal is not affected by this policy)
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer' -Name NoRun -ErrorAction SilentlyContinue
# Windows Installer restriction for non-managed installs?
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer' -Name DisableMSI -ErrorAction SilentlyContinue
# PowerShell script block logging on? (records the decoded layer even though it never touches disk)
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Name EnableScriptBlockLogging -ErrorAction SilentlyContinue
# Hidden installs (ARPSYSTEMCOMPONENT=1) under the per-user Programs tree on this host
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue |
Where-Object { $_.SystemComponent -eq 1 -or $_.InstallLocation -like '*\AppData\Local\Programs\*' } |
Select-Object DisplayName, Publisher, InstallLocation, PSChildName
# Defender ASR rules in audit or block (only meaningful if Defender is the active antivirus)
(Get-MpPreference).AttackSurfaceReductionRules_Ids
Detection Validation Gates
Work these in order. A query that has not cleared gate 2 has no business being an alert.
| Gate | What to prove | How | Pass criteria |
|---|---|---|---|
| G1 · Telemetry ready | The events each query depends on arrive in your tenant | Run each event filter alone over 24h with count(). Pay particular attention to registry RunMRU writes (Q3), scheduled task registration (Q10, Q11), file open of non-PE files (Q9) and process attribution on DNS lookups (Q12). Platform names: process creation (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents); registry value set (CrowdStrike: AsepValueUpdate. SentinelOne: Registry Value Modified. Defender: DeviceRegistryEvents). | Non-zero counts and the named fields populated. |
| G2 · Benign baseline | You know what normal looks like | Run Q1 to Q15 across 30 days and classify every hit. Q7 and Q11 will surface legitimate per-user installers and updaters; build the exclusion list here. | Every recurring hit is explained and excluded, or escalated. |
| G3 · Positive test | The query fires on the behaviour it claims to detect | On an isolated test host in a change window, with harmless stand-ins only: run PowerShell with a benign fetch addressed to a decimal-form loopback or lab host (Q1); register a throwaway task and Run value with one of the two names (Q10); copy any signed harmless executable renamed COTFileReadApp.exe to a folder under %LOCALAPPDATA%\Programs\ and run it (Q6). Do not use real malware. | The matching query fires. |
| G4 · Negative test | Your exclusions did not blind the query | Re-run G3 with tuning exclusions applied. | Test events still fire. |
| G5 · Promotion | Safe to alert | Custom IOA in Monitor mode for one business week on a pilot policy. | Zero unexplained detections. |
| G6 · Response readiness | The team can act on a hit | Tabletop the section 14 runbook, including the kill-first ordering and the 20-minute recreation watch. | An analyst can state the order of eradication and the credential reset step without prompting. |
Hardening: Tiered
Controls are ordered by leverage against this chain. It needs five things from the endpoint: a human willing to paste a command, PowerShell with web access, the ability to install an MSI without elevation, permission to run a binary and load DLLs from a per-user folder, and an unmonitored autostart. Remove or watch each one. Where a platform has no formal benchmark entry the control is flagged.
- I1 · Remove the Run dialog (per-user policy) and brief users that no ChatGPT, CAPTCHA or "backup domain" page ever needs them to paste a command. MITRE M1042 (T1204.004) and M1017. Benchmark: CIS Microsoft Windows 11 Enterprise Benchmark, user Start Menu and taskbar settings (confirm the exact recommendation number in your benchmark version). Limit: Huntress describes the command being pasted into a terminal, and this policy does not affect Windows Terminal, so I1 reduces one path only. Playbook P1. Verify with the section 10 audit block.
- I2 · Turn on PowerShell script block logging. M1047 (T1059.001). Benchmark: CIS Windows benchmark, Administrative Templates, Windows PowerShell. The decoded stage-1 layer is built in memory with a scriptblock, so event 4104 is the one place the real script is recorded. Playbook P3.
- I3 · Import the IOC CSV and promote the four IOAs in Monitor. M1049 (detection side). Only
96.62.224[.]81is prevent; see section 10. - I4 · Alert on the pasted-command shape at the web gateway. Add a proxy rule for any HTTP request whose host is a bare integer, and log (do not yet block) requests to
chatgpt.com/g/andsites.google.com/view/. M1021 (T1566.002, T1105). best-practice, no formal benchmark
- N1 · Restrict per-user MSI installs. Set the Windows Installer policy to prevent installs of non-managed applications by standard users, so a user-context MSI cannot lay a signed host and DLLs into
%LOCALAPPDATA%\Programs\. M1038 (T1218.007). Benchmark: Microsoft Learn, Windows Installer policy settings; CIS Windows benchmark, Administrative Templates, Windows Installer. Pilot carefully: confirm your RMM and software-deployment installs still succeed, and read Microsoft's documentation for the exact meaning of the DisableMSI values before deploying. Playbook P2. - N2 · Enable ASR rules in audit, then block for potentially obfuscated scripts and for executables that fail a prevalence, age or trusted-list test. M1040 (T1027, T1059.001). Benchmark: Microsoft Defender attack surface reduction rules reference (confirm rule GUIDs there). Applies only where Microsoft Defender Antivirus is the active antivirus. On Falcon-primary endpoints ASR is inert, so use the equivalent Falcon prevention-policy settings.
- N3 · Narrow PowerShell's web egress. The first wave downloads over plain HTTP. Blocking outbound port 80 from PowerShell is cheap but easy to bypass by switching to HTTPS, so treat it as friction, not a fix. M1031 (T1105). Playbook P4. best-practice, no formal benchmark
- N4 · Treat sites.google.com/view/ and AI-chat share links as higher risk in web filtering, with browser isolation or a warning page. M1021. best-practice, no formal benchmark
- S1 · Application control with DLL enforcement. Deploy WDAC or AppLocker with DLL rules so that neither executables nor DLLs run from
%LOCALAPPDATA%\Programs\unless explicitly allowed. This is the control that stops sideloading of a validly signed host regardless of vendor, which is the point of Huntress's warning about "the next swap". M1038 (T1574.002, T1036.005). Benchmark: Microsoft WDAC and AppLocker deployment guides; CIS Windows benchmark, AppLocker section. Audit mode for at least a full business cycle first. - S2 · User training on AI-platform lures. Trained-against-attachments users are not primed to distrust an answer from "ChatGPT" itself telling them to use a backup domain. M1017 (T1204.004). Include the sponsored-result vector: bookmark the product, do not search for it. best-practice, no formal benchmark
- S3 · Constrained Language Mode for standard users through WDAC, so the fetch-and-run pattern fails by default. M1038 (T1059.001). Benchmark: Microsoft WDAC documentation. High compatibility cost; only for locked-down fleets.
Deployable Playbooks
Test every playbook on a pilot ring before fleet deployment. P1 and P2 change user-visible behaviour. Each playbook lists its prerequisites, reboot requirement and rollback. P5 is destructive eradication: export first, and run it only on a contained host.
P1 · Remove the Run dialog (per-user policy)
# Prerequisites: run as the target user, or push through GPO or a logon script. Pilot ring first.
# Reboot required: no (sign out and back in, or restart Explorer, for the change to apply)
# Rollback: Remove-ItemProperty -Path $k -Name NoRun then sign out and back in
# Note: does not restrict Windows Terminal or PowerShell opened another way
$k = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer'
if (-not (Test-Path $k)) { New-Item -Path $k -Force | Out-Null }
New-ItemProperty -Path $k -Name NoRun -PropertyType DWord -Value 1 -Force | Out-Null
# Verify
Get-ItemProperty -Path $k -Name NoRun
P2 · Restrict installs of non-managed MSI packages
# Prerequisites: local administrator. Inventory how your RMM and deployment tool install MSIs first.
# Confirm the meaning of the DisableMSI values in Microsoft's Windows Installer policy documentation.
# Reboot required: no
# Rollback: Remove-ItemProperty -Path $k -Name DisableMSI (installs return to default behaviour)
# Value 1 restricts non-managed application installs; value 2 restricts all installs (do NOT use 2 without testing)
$k = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer'
if (-not (Test-Path $k)) { New-Item -Path $k -Force | Out-Null }
New-ItemProperty -Path $k -Name DisableMSI -PropertyType DWord -Value 1 -Force | Out-Null
# Verify, then test a standard-user per-user MSI install on the pilot ring AND a managed deployment
Get-ItemProperty -Path $k -Name DisableMSI
P3 · PowerShell script block and module logging
# Prerequisites: local administrator; size the PowerShell Operational log (for example 512 MB) first.
# Reboot required: no
# Rollback: set both values back to 0 (or delete the two policy keys)
$sb = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
$ml = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging'
foreach ($k in $sb, $ml) { if (-not (Test-Path $k)) { New-Item -Path $k -Force | Out-Null } }
New-ItemProperty -Path $sb -Name EnableScriptBlockLogging -PropertyType DWord -Value 1 -Force | Out-Null
New-ItemProperty -Path $ml -Name EnableModuleLogging -PropertyType DWord -Value 1 -Force | Out-Null
# Raise the Operational log size to 512 MB
wevtutil sl "Microsoft-Windows-PowerShell/Operational" /ms:536870912
# Verify
Get-ItemProperty -Path $sb -Name EnableScriptBlockLogging
(wevtutil gl "Microsoft-Windows-PowerShell/Operational") -match 'maxSize'
P4 · Block PowerShell outbound plain HTTP (friction control)
# Prerequisites: local administrator; run Q5 for 30 days first and list legitimate HTTP-only destinations.
# Reboot required: no
# Rollback: Remove-NetFirewallRule -DisplayName 'HuntPack block PowerShell outbound 80*'
# Note: bypassed by switching the attacker's download to HTTPS. Defence in depth only.
$progs = @("$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe",
"$env:SystemRoot\SysWOW64\WindowsPowerShell\v1.0\powershell.exe")
$i = 0
foreach ($p in $progs) {
$i++
New-NetFirewallRule -DisplayName "HuntPack block PowerShell outbound 80 ($i)" -Direction Outbound -Action Block `
-Program $p -Protocol TCP -RemotePort 80 -Profile Any | Out-Null
}
# Verify
Get-NetFirewallRule -DisplayName 'HuntPack block PowerShell outbound 80*' | Select-Object DisplayName, Enabled, Action
P5 · Eradicate the implant (kill first, then both persistence artefacts)
# Prerequisites: local administrator on the CONTAINED host (Falcon network containment on; use Real Time Response
# to run it). Capture evidence first (section 14, C2). Run in the affected user's context for the HKCU steps.
# Reboot required: no
# Rollback: none after deletion. The script exports the task XML and the Run value to the evidence folder first.
# ORDER MATTERS: the implant's script recreates the Run value (every 150 s) and the task (every 875 s) while it runs.
$ev = Join-Path $env:ProgramData 'IR-Evidence'; New-Item -ItemType Directory -Path $ev -Force | Out-Null
$names = 'Canon Configuration Reader','Stardock DeElevation Tool'
$hosts = 'COTFileReadApp','DeElevate64'
# 1. Kill the signed host process (only copies running from the per-user Programs tree)
Get-Process -Name $hosts -ErrorAction SilentlyContinue |
Where-Object { $_.Path -like '*\AppData\Local\Programs\*' } |
ForEach-Object { $_.Path | Add-Content "$ev\killed-process-paths.txt"; Stop-Process -Id $_.Id -Force }
# 2. Export, then remove, the scheduled task and the Run value
foreach ($n in $names) {
$t = Get-ScheduledTask -TaskName $n -ErrorAction SilentlyContinue
if ($t) { Export-ScheduledTask -TaskName $n | Out-File "$ev\task-$($n -replace ' ','_').xml"; Unregister-ScheduledTask -TaskName $n -Confirm:$false }
$rk = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'
$v = Get-ItemProperty -Path $rk -Name $n -ErrorAction SilentlyContinue
if ($v) { "$n = $($v.$n)" | Add-Content "$ev\runvalue.txt"; Remove-ItemProperty -Path $rk -Name $n }
}
# 3. Wait out one task interval (875 s) and confirm nothing came back
Start-Sleep -Seconds 900
Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object { $names -contains $_.TaskName }
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' -ErrorAction SilentlyContinue | Select-Object $names
# 4. List the hidden product folders and MSI entries for the analyst to uninstall by product code (do not auto-delete)
Get-ChildItem (Join-Path $env:LOCALAPPDATA 'Programs') -Directory -ErrorAction SilentlyContinue | Select-Object FullName, CreationTime
Containment Runbook
Sequencing rule: kill the signed host process before removing the Run value or task, and then watch for a recreation for at least one task interval (875 seconds; allow 20 minutes). The persistence script lives inside monitor.raw and runs in the host process. Treat the host as having had a live remote operator.
| Phase | Actions | Owner | Evidence to capture |
|---|---|---|---|
| C0 · Triage 0 to 15 min | Confirm which query fired (Q1 to Q15). Identify the user, host and time. Check whether Q1, Q4, Q6 and Q10 also fired on the same aid. Ask the user what they searched for and what they pasted. | SOC L1 | Falcon process tree; triggering query output; aid and ComputerName; the user's account of the lure |
| C1 · Isolate 15 to 30 min | Network-contain the host in Falcon. Do not power off: the loader, shellcode and RAT run from memory only. Preserve volatile state first where policy allows (memory image). | SOC L2 | Containment timestamp; memory image if taken; list of running processes |
| C2 · Preserve evidence 30 to 60 min | Copy the install folder under %LOCALAPPDATA%\Programs\, the WAV or Build.dat, monitor.raw or execute_engine_disconnect.raw, the patched DLLs, the Temp MSI (if still present) and the exported task XML and Run value. Hash everything. Pull PowerShell event 4104 for the decoded stage-1 script. | DFIR | File hashes (compare with section 10); task XML; Run value data; 4104 events; MSI product code |
| C3 · Eradicate 1 to 4 hours | Run playbook P5: kill the host process, then remove the task and the Run value, then wait 20 minutes and re-check both. Uninstall the hidden MSI product by product code. Look for the follow-on GOMCam2024.exe folder and any other payload. If any doubt remains, rebuild the host: the RAT can run EXE, DLL, MSI, PowerShell, batch, VBScript, JScript and ZIP payloads, so you cannot enumerate what else was dropped. | SOC L2 / IR | Before and after screenshots of persistence; confirmation that nothing recreated |
| C4 · Credentials and sessions parallel with C3 | The RAT had screen, camera, microphone, file search and 17 browsers in scope. From a clean device: reset the user's passwords, revoke active sessions and tokens, re-register MFA, and rotate any secret that was on the host or in its browsers. Do not wait for C3 to finish. | Identity team | Session revocation timestamps; list of accounts and secrets reset |
| C5 · Scope same day | Sweep the fleet with Q1, Q4, Q6, Q7, Q8, Q10, Q13 and Q14 over 30 days. Search the proxy for the Custom GPT and Google Sites URLs and bare-integer hosts (N1) to find users who clicked but did not execute. Hunt for other signed hosts launched by msiexec from the Programs tree (Q7): the operators already staged a third installer. | Threat hunt | Hit list by host and user; proxy hit list |
| C6 · Recover and report 1 to 3 days | Return the host to service only after rebuild or confirmed clean. Add the proxy path blocks. Report the Custom GPT to OpenAI and the Google Sites page to Google. Brief users on the sponsored-result lure. Close the loop on the section 12 immediate controls. | SOC lead | Ticket closure notes; list of reports filed |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | Hardening | CrowdStrike coverage | SentinelOne |
|---|---|---|---|---|---|---|
| T1583.008 / T1566.002 | Sponsored result to Custom GPT to Google Sites lure | None | No | I4, N4, S2 | GAP (invisible to host sensors; proxy and DNS only, N1) | GAP |
| T1204.004 | Pasted ClickFix command | Q2, Q3 | No | I1, S2 | PARTIAL (RunMRU only if pasted into Run; terminal path relies on Q1, Q2) | Partial: same limit as CrowdStrike |
| T1059.001 / T1105 | Decimal-encoded IP fetch | Q1, Q5 | Yes (Q1) | I2, N3 | GOOD (attacker can change encoding; Q2 and Q5 are backstops) | Good, with assumptions |
| T1218.007 | Silent msiexec on a Temp MSI | Q4 | Yes (Q4) | N1, N2 | GOOD | Good, with assumptions |
| T1574.002 / T1036.005 | Signed host from fake Programs folder | Q6, Q7 | Yes (Q6) | S1 | GOOD (Q7 is the host-swap-proof half) | Good, with assumptions |
| T1574.002 | Component DLL staging and hashes | Q8, Q14 | No | S1 | PARTIAL (file writes and known hashes only; the DLL load itself is not queried) | Partial: same limit as CrowdStrike |
| T1574.002 | Unsigned DLL actually loaded by the signed host | None | No | S1 | GAP (no module-load query in this pack; use Sysmon event 7, N3) | GAP |
| T1027 / T1027.013 | WAV or NuGet carrier and encrypted archive | Q9 | No | S1 | PARTIAL (depends on file-open telemetry; sweep N5 as fallback) | Partial: Q9 telemetry gap |
| T1562.001 / T1497.001 | AMSI bypass, ntdll unhooking, anti-VM | None | No | N2, S1 | GAP (in memory; relies on sensor prevention, not hunts) | GAP |
| T1547.001 / T1053.005 | Named Run value and scheduled task | Q10 | Yes (Q10) | S1 | GOOD (names are changeable by shipping a new monitor.raw) | Partial: Q10 approximate |
| T1053.005 / T1547.001 | Self-healing recreation | Q11 | No | None | PARTIAL (noisy; name-agnostic by design) | Partial: Q11 telemetry gap |
| T1071.001 / T1572 | DNS-over-HTTPS C2 from the host process | Q12, Q13 | No | N3 | PARTIAL (C2 address never recovered; resolver traffic blends with normal HTTPS) | Partial: same limit as CrowdStrike |
| T1105 | Follow-on payload (GOMCam2024.exe) | Q15 | No | S1 | PARTIAL (post-compromise confirmation; other follow-ons exist) | Partial: same limit as CrowdStrike |
| T1113 / T1125 / T1123 / T1005 | Screen, camera, microphone capture; file search | None | No | None | GAP (no practical endpoint telemetry; handled by response, C4) | GAP |
Gap summary
- The lure is invisible to host sensors. The Custom GPT and the Google Sites page sit on legitimate domains. Only proxy, DNS or browser history sees them (N1). OpenAI plans to retire Custom GPTs on 2026-12-11, which may close this exact vector, but not the pattern.
- No DLL-load hunt. Falcon module-load events are not used in this pack, so the sideload itself is hunted by its staging, its host path and its persistence. Add Sysmon event 7 (N3) where available.
- Names are perishable. Canon, Stardock, ISOSimple, IconEdit2Turb and the two persistence names will change. Q1, Q4, Q7 and Q11 are the durable half.
- C2 never recovered. No C2 indicator exists; the CSV carries a placeholder.
Validation: gates G1 to G6 in section 11 govern promotion. No query proceeds to alert before clearing G2, and none is recommended for Block.
Hunt Summary Ticket
TITLE: Custom GPT ClickFix RAT - Plus 5.6 GPT, decimal-IP PowerShell, Canon/Stardock DLL sideload, WAV loader
SEVERITY: High - Huntress research 2026-09-28; at least 40 incidents, 2 confirmed from Custom GPT; no named actor, RAT family unnamed
SCOPE: All Windows endpoints with interactive users and web access. Priority: users who search for ChatGPT, and
any host where msiexec has started a program from %LOCALAPPDATA%\Programs\.
HYPOTHESIS: A user followed a sponsored result to a Custom GPT on chatgpt.com, was sent to a Google Sites page posing as a
Cloudflare check, and pasted a PowerShell command that fetches from a decimal-encoded IP. The script installs an
MSI that drops a signed Canon or Stardock binary and a patched DLL under LocalAppData Programs. The DLL chain
decrypts a loader from a WAV (or NuGet package), unpacks a RAT from monitor.raw, and persists with a Run value
and scheduled task of the same name that it recreates when removed.
QUERIES: Q1 PowerShell fetch from decimal/hex IP host CONF high | FP low | COST low
Q2 ClickFix-shaped PowerShell launch CONF med | FP med | COST low
Q3 Run-dialog paste of PowerShell fetch (RunMRU) CONF high | FP low | COST low
Q4 PowerShell spawns silent msiexec on Temp MSI CONF high | FP low | COST low
Q5 PowerShell/msiexec plain-HTTP to public IP CONF med | FP med | COST low
Q6 Signed Canon/Stardock host in LocalAppData Prog. CONF high | FP low | COST low
Q7 Any exe launched by msiexec from Programs tree CONF med | FP med | COST low
Q8 Sideload component DLLs written under Programs CONF high | FP med | COST low
Q9 WAV / monitor.raw / Build.dat carrier opens CONF med | FP low | COST low
Q10 Named Run value / scheduled task CONF high | FP low | COST low
Q11 Self-healing: same task/Run value rewritten CONF med | FP med | COST med
Q12 Signed host making network/DNS (DoH C2) CONF high | FP med | COST low
Q13 Published delivery IP connections CONF high | FP low | COST low
Q14 Component DLL hash sweep CONF high | FP low | COST med
Q15 GOMCam2024.exe follow-on CONF med | FP low | COST low
DO FIRST: 1. Q6 + Q10 across 30 days (signed host in wrong place; named persistence)
2. Q1 + Q4 across 30 days (decimal-IP fetch; silent MSI)
3. Q13 + Q14 retrospective sweep (perishable)
4. Q7 to surface a swapped signed host
5. Proxy search N1 for the GPT and Google Sites URLs
FINDINGS: [ ] Q1 hits: ______ [ ] Q4 hits: ______ [ ] Q6 hits: ______
[ ] Q10 hits: ______ [ ] Q13/Q14 hits: ______
[ ] Hosts with 2+ query hits in 24h (auto-escalate): ______
[ ] Users requiring credential and session reset: ______
GAPS: - Custom GPT and Google Sites hops: outside endpoint telemetry (proxy, DNS, browser history only)
- No DLL-load query; sideload hunted by staging, host path and persistence
- AMSI bypass, unhooking, in-memory loader and RAT: no endpoint hunt
- C2 address never recovered; CSV carries a REPLACE_WITH_ placeholder
- All indicators single-lineage (Huntress); only 96.62.224.81 ships at prevent
ACTIONS: [ ] Promote Q1, Q4, Q6, Q10 to Custom IOA (Monitor mode, pilot policy, 1 week)
[ ] Import the section 10 CSV (delete the REPLACE_WITH_ row first); only 96.62.224.81 is prevent
[ ] Deploy Immediate hardening: I1 Run dialog, I2 PS logging, I3 IOC/IOA, I4 proxy rule
[ ] Confirm RunMRU, task registration and file-open telemetry (gate G1)
[ ] Eradication order: kill host process, then task and Run value, then watch 20 minutes
OWNER: ______________________
VERSION: v0.1 - 2026-10-11
Changelog
References
| Tier | Source | Used for | Accessed |
|---|---|---|---|
| 1 | Huntress: Attackers Abuse ChatGPT Custom GPTs to Deliver RAT via ClickFix | Chain, V1 and V2, detection opportunities, full IOC table. Snapshot 01 | 2026-10-11 |
| 2 | BleepingComputer: Custom ChatGPTs push ClickFix attacks to deploy RAT malware | Corroboration, takedown dates, persistence name. Snapshot 02 | 2026-10-11 |
| 2 | Security Affairs: Attackers Abuse ChatGPT Custom GPTs to Deploy a Full-Featured RAT | Corroboration of the durable chain. Snapshot 03 | 2026-10-11 |
| 2 | The Hacker News: Attackers Abuse ChatGPT Custom GPTs | Second source for both Custom GPT URLs. Snapshot 04 | 2026-10-11 |
| 2 | CyberSecurityNews: ChatGPT Custom GPT malware | Second source for the delivery IP and decimal form. Snapshot 05 | 2026-10-11 |
| 3 | Cloud Security Alliance research note (AI-assisted, no formal review) | Third document for the delivery IPs and lure path. Snapshot 06 | 2026-10-11 |
| ref | MITRE ATT&CK | Technique IDs in section 6 and mitigation M-numbers in section 12. Not fetched for this pack | reference |
| ref | Microsoft Learn: Attack surface reduction rules reference | Confirm ASR rule GUIDs before deployment. Not fetched for this pack | reference |
| ref | Microsoft Learn: DisableMSI policy | Confirm DisableMSI value semantics before deploying P2. Not fetched for this pack | reference |
Provenance statement. Every hash, IP, URL, value name and path in this pack is reproduced from the Huntress report (snapshot 01). Two corroborating documents carry the delivery IP behind the only prevent entry. No hash, domain or infrastructure from any other ClickFix campaign is used. No family or campaign nickname is invented: Huntress names neither. The C2 address was not published, so the pack ships a placeholder and a behavioural hunt instead of an invented value.