Doina Loader via Amazon-Themed ClickFix (finger.exe .plan)

Sponsored Google result for "amazon business" · fake Amazon sign-in with a ClickFix CAPTCHA · finger.exe pulls a .plan script · IronPython, Doina, a Node.js stage, a suspected Lumma Stealer and a pirated NetSupport Client
Threat
Amazon-themed ClickFix campaign delivering Doina (no named actor)
Severity
HIGH
Type
Malvertising / ClickFix loader chain with infostealer and RMM
Initial Access
Sponsored search ad, fake CAPTCHA, Run-dialog paste
Version
v0.1 · 2026-10-29
Author
HuntPack
Confidence
MEDIUM-HIGH (one primary vendor report; behaviors corroborated by two independent finger/IronPython sources, indicators single-lineage)
01

Executive Summary

Attacker objective: run code on a Windows (and, per the report, macOS) machine and leave behind credential theft and remote access. Huntress investigated the campaign across multiple incidents and states it hit at least three of its customers. A sponsored Google result for the search term "amazon business" led to a spoofed Amazon sign-in page. After the victim types an email or phone number, a fake "I'm not a robot" CAPTCHA copies a command to the clipboard and instructs the victim to paste it into the Windows Run dialog.

The distinctive first stage is the built-in finger.exe client. The pasted command is obfuscated with commas, carets, hyphens and underscores, and it makes finger talk to a user account on an attacker domain over 79/tcp. The returned .plan text is a Windows script, hidden below the console height with 68 extra carriage returns. That script uses curl to fetch the real IronPython 3.4.2 release into the user Temp directory under a .pdf name, unpacks it with tar, and runs ipyw32.exe from the net462 folder with a Base64 and zlib-compressed Python blob.

The IronPython stage downloads timer6, a Cyrillic-substituted Base64 Python loader around XOR-protected shellcode. It decodes to a PE loader that finds an .ini file holding a URL, downloads from it and RC4-decrypts the body (v6), which is injected into memory. Huntress reports the vendor consensus is that v6 is Doina, a modular loader and RAT. Doina then pulls a ZIP with a portable Node.js runtime and an obfuscated index.js into C:\ProgramData\NodeView. The script decrypts two high-entropy files with AES-256-GCM: a shellcode reflective DLL injector and a larger payload that Huntress describes as "allegedly" Lumma Stealer, injected by process hollowing. A pirated NetSupport Client is also deployed to C:\ProgramData\Prodclear and talks to 167.148.201[.]106 on 725/tcp.

Attribution and persistence: no threat actor is named by any source, and this pack does not name one. Huntress reports no scheduled task or other persistence mechanism, so none is claimed here. The Lumma Stealer identification is hedged by Huntress and is hedged here.

Highest-value defensive angle: the chain is built from legitimate binaries (finger, curl, tar, IronPython, Node.js, NetSupport), so hash blocking alone fails. Hunt the behavior: finger.exe execution and TCP/79 egress (near-zero false positives on a modern fleet), IronPython running from a user-writable folder, node.exe running index.js from ProgramData, and Client32.exe in ProgramData. The pack ships 14 CQL queries, none of which recommends blocking a stock binary.

Defender priority: any host where finger.exe ran or connected out on port 79 should be treated as a credential-theft incident, not a malware cleanup. The final payload is an infostealer targeting browsers, crypto wallets, password managers and email clients, and a remote-management client was installed alongside it. Isolate the host, then reset credentials and sessions for the user and move any crypto holdings, without waiting for host forensics.

02

Source Review & Web Hunter Notes

TierSourceKey FindingCarry Forward
1Huntress, "Amazon-Themed ClickFix Campaign Serves Up Finger-Licking Malware" (2026-10-21)Primary report. Full infection chain, all infrastructure, nine hashes, port 79 and 725 behavior, Doina identification, hedged Lumma identification, NetSupport at Prodclear, no persistence reported.Yes. Source of every campaign indicator. Snapshot 01.
2Security Online, "Amazon ClickFix Campaign Abuses Windows Finger Command"Secondary write-up of the Huntress report. Confirms the Doina, Node.js, suspected-Lumma and NetSupport chain, states no attribution, advises blocking outbound port 79. Adds no indicators.Partial. Corroborates the chain and the port 79 control only; same lineage as Huntress. Snapshot 02.
2SigmaHQ rule "Network Connection Initiated via Finger.EXE"Independent detection content: any network connection initiated by finger.exe is high severity and maps to T1059.003 and T1071.004. States finger's presence in modern Windows already raises suspicion and cites a ClickFix campaign.Yes. Independent basis for the finger.exe behavioral detections (Q1, Q3, Q4). Snapshot 03.
3BlueTeamCoolTeam, "Seven layers of obfuscation, one 1970s LOLBIN"A different finger.exe and IronPython campaign (different domains, different UUID and C2). Independently confirms the technique: cmd.exe with caret obfuscation, finger response executed as batch, renamed curl, IronPython 3.4.2 zip saved as .pdf, tar extraction, ipyw32.exe running an inline Base64 and zlib payload, Cyrillic-substituted Base64.Behavior only. Second independent source for the technique; none of its indicators ship. Snapshot 04.

Hunter notes & deliberate omissions

  • Indicators are single-lineage. Every campaign domain, IP and hash comes from the Huntress report alone; Security Online relays it without adding values. Per the pack rule that blocking needs two independent sources, all 18 imported indicators are detect, none is prevent, and none is critical severity. The finger.exe, IronPython and port 79 behaviors do have two independent sources.
  • The sibling finger/IronPython campaign is not this pack's campaign. The BlueTeamCoolTeam post documents separate infrastructure. Its domains, campaign UUID, build marker, XOR key and YARA are deliberately not shipped here, because a pack carries only its own campaign's indicators.
  • Doina identification. Huntress says the "security vendor consensus" is that v6 is Doina and cites a 2024 Halcyon report tying Doina to pre-ransomware activity. The Halcyon report was not retrieved, so no Doina detail beyond what Huntress states is claimed.
  • Lumma Stealer is hedged. Huntress calls the larger payload "allegedly Lumma Stealer" and says the stealer is "suspected" elsewhere. Query names and IOC descriptions here say attributed or suspected, never confirmed.
  • Domain spelling discrepancy. The ad landing host is written orders-amazon[.]com[.]advancedfences[.]com in the article body and orders-amazon-com[.]advancedfences[.]com in the IOC table. Both are in the snapshot; the pack imports the IOC-table form and notes the other.
  • The ClickFix command is not reproduced. The article does not print the obfuscated string and this pack does not invent one. Q2 and Q12 hunt its shape (finger-letters with separator padding and a user@host argument).
  • Searched but unavailable: Dark Reading, BleepingComputer and Petri coverage returned HTTP 403 to automated fetch, so none is cited.
  • macOS variant: the report says macOS users received Terminal instructions and the destination was offline during research. No macOS payload analysis exists, so no macOS detection is claimed.
03

Hunt Brief & Attack Chain

Hypotheses (ordered by fidelity)

  1. H1, high: a user pasted a ClickFix command that launched finger.exe, which connected out on 79/tcp (T1204.004, T1218, T1105). Q1, Q2, Q3, Q4, Q12.
  2. H2, high: an IronPython interpreter ran from a user-writable folder with an inline encoded script and reached the internet (T1059.006, T1105). Q5, Q6, Q7, Q8.
  3. H3, medium-high: a Node.js runtime executed index.js from ProgramData (T1059.007). Q9.
  4. H4, medium-high: a pirated NetSupport Client ran from ProgramData and beaconed on 725/tcp (T1219). Q10, Q11.
  5. H5, high: the host resolved a published campaign domain (T1071.001). Q13.
  6. H6, high: a single host shows two or more of the chain tools in the window. Q14.

Attack chain

StepBehaviorTelemetry (platform in parentheses)Hunt angle
0Sponsored ad to spoofed Amazon sign-in on Google Sites; fake CAPTCHA copies a commandProxy or browser URL logs with ad-click markers aclk and gclid; DNS (outside endpoint telemetry)Native hunt N1. No endpoint signal
1Victim pastes the command into Run; obfuscated finger command executesProcess creation with command line (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents); registry value writes (RunMRU)Q1, Q2, Q12
2finger.exe connects to 79/tcp and returns the .plan script, executed by cmdNetwork connections (CrowdStrike: NetworkConnectIP4. SentinelOne: IP Connect. Defender: DeviceNetworkEvents); DNS requestsQ3, Q4
3curl downloads IronPython.3.4.2.zip to Temp as .pdf; tar unpacks; ipyw32.exe runs from net462 with an encoded blobProcess creation with command lineQ5, Q6, Q7
4ipyw32.exe fetches timer6; PE loader finds an .ini URL, fetches v6, RC4-decrypts, injects Doina in memoryNetwork and DNS from the interpreter; memory injection (outside endpoint telemetry for the shellcode itself)Q8, Q13. In-memory stage is a gap
5Doina downloads the Node package to C:\ProgramData\NodeView; node.exe runs index.jsProcess creation with command lineQ9
6index.js decrypts two files (AES-256-GCM); sRDI injects the stealer by process hollowing; HTTPS POST then WebSocket beaconsIn-memory injection and WebSocket content (outside endpoint telemetry); DNS and network for the C2 hostsQ13. Stealer behavior is a gap
7Pirated NetSupport Client in C:\ProgramData\Prodclear talks to 167.148.201[.]106 on 725/tcpProcess creation; network connectionsQ10, Q11
04

Consolidated IOC Table

Read before importing: every campaign indicator comes from one primary report, so all import as detect. Legitimate software (finger.exe, curl.exe, tar.exe, ipyw32.exe, node.exe, Client32.exe, the IronPython archive) is listed for context and is never a block target.

TypeValueConfidenceActionContext
domaingrillrecipespro[.]comHIGHdetectHost queried by finger.exe for the .plan script. Source: Huntress.
domaingrillmasterchef[.]comHIGHdetectServes timer6 and v6; Doina C2 (HTTPS POST). Source: Huntress.
domainthegrilljournal[.]comHIGHdetectReported attacker infrastructure; exfil after check-in. Source: Huntress.
domainhomelygrill[.]comHIGHdetectReported attacker infrastructure; exfil after check-in. Source: Huntress.
domainperfectgrillrecipes[.]comHIGHdetectStealer initial check-in. Source: Huntress.
domainEmbersAndBites[.]comMEDIUMdetectListed as attacker infrastructure; role not detailed.
domainkiriosyka[.]comHIGHdetectNode package (sqr-viewertr6) delivery.
domainliokida[.]comHIGHdetectNode and stealer packages (sqr-viewertr6z); embedded in the stealer.
domainorders-amazon-com[.]advancedfences[.]comHIGHdetectSponsored-ad landing subdomain. The article prose renders it orders-amazon[.]com[.]advancedfences[.]com while the IOC table renders it orders-amazon-com[.]advancedfences[.]com; the pack ships the IOC-table form and hunts both via the ad-click markers.
urlhxxps[://]sites[.]google[.]com/view/ch-pc/sign-inMEDIUMhuntFake Amazon sign-in with the ClickFix CAPTCHA, on a legitimate Google Sites host. Hunt only: the host is Google.
urlhxxp[://]ashevilleroofingcontractor[.]com/curl/...LOWhuntAlternate macOS payload URL, offline when researched. Looks like a compromised third-party site, so not imported.
urlhxxp://grillmasterchef[.]com/90e4a147-1234-505c-a024-062e543b5df8/timer6HIGHdetecttimer6 delivery URL (Cyrillic-substituted Base64 Python). Domain imported; full path hunted in proxy logs.
urlhxxps://grillmasterchef[.]com/90e4a147-1234-505c-a024-062e543b5df8/v6HIGHdetectv6 stage URL (RC4-encrypted Doina).
urlhxxps://kiriosyka[.]com/KsxmmKiN5N0j/sqr-viewertr6HIGHdetectNode package URL, a 52MB ZIP per Huntress.
urlhxxps://liokida[.]com/KsxmmKiN5N0j/sqr-viewertr6zHIGHdetectNode/stealer package URL.
ipv4167.148.201[.]106HIGHdetectRogue NetSupport C2 on 725/tcp, URL http://167.148.201[.]106:725/fakeurl.htm. The address only hosts an unrelated restaurant website, so expect no legitimate use but do not block without review.
port79/tcpHIGHdetectFinger protocol egress. Behavioral, not importable.
port725/tcpMEDIUMdetectNetSupport Client traffic on a nonstandard port. Behavioral.
sha256d864b28c302db9ed10baf8def0fb26bac0b97d27349d22c4e9390d30fce54649HIGHdetecttimer6
sha256891cc3ca2d29e9b185a8913e93810f48859d2be1f23ddd977a15cdbeed509e0eHIGHdetectv6 (Doina) RC4-decrypted body
sha25687a047160eb1a9b92e6ede511252dfc624b0f5a7185ac2cec1c7ebde8cdf4eeaHIGHdetectindex.js
sha256035d396b3a329f59d680dc36a0a639eb7fb306bea97e42f5f53293dce817e8b7HIGHdetectNodeview.zip
sha25624a293a662600b2292d9259baebba1c09b41df82a5c9c20f8572625ae759696fHIGHdetect754224f2-3449-4ac7-8b13-1cb8e6af6408.tmp (payload attributed to Lumma Stealer)
sha256b8419a676a3d4af04ea98287a2b85052fae5c06e6278ca9d8bfa4b5b396b39a6HIGHdetect1572cef1-df62-4594-a3aa-a9db91b9d7db.tmp
sha25642527a4388ef4ade6f4eaf52706f0ab31cb4e9ced3a56a6b15402551f9f01208HIGHdetect29d37679-4112-4751-8613-15b94b29ad39.tmp
sha256408b7fc4f08f2a9044046025f05995e8cbd5c96c39844aaa8a7eb8ee4697ea89HIGHdetect545b93c2-e4f7-4397-b32c-8a3c77538594.tmp
filenameIronPython.3.4.2.zipHIGHhuntLegitimate archive, saved to Temp with a .pdf extension. Do not block the name.
filenameipyw32.exe, node.exe, Client32.exe, finger.exe, curl.exe, tar.exeHIGHhuntLegitimate software abused. Behavioral detections only (Q1, Q5 to Q10); never a prevent target.
pathC:\ProgramData\NodeView, C:\ProgramData\ProdclearHIGHhuntInstall folders for the Node runtime and the pirated NetSupport Client.
05

Affected Surface & Telemetry Matrix

SurfaceTelemetry (platform in parentheses)PriorityGap
Windows workstations (Run dialog, finger, cmd, curl, tar)Process creation with command line (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents)HIGHNone for the process events themselves
Egress on 79/tcp and 725/tcpNetwork connections with process (CrowdStrike: NetworkConnectIP4. SentinelOne: IP Connect. Defender: DeviceNetworkEvents)HIGHPerimeter and proxy logs are the second source for hosts without an agent
DNS for the barbecue-themed domainsDNS requests with process (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceNetworkEvents)HIGHProcess attribution varies by sensor; validate in tenant
Run-dialog historyRegistry value writes (CrowdStrike: RegGenericValueUpdate. SentinelOne: Registry Value Modified. Defender: DeviceRegistryEvents)MEDIUMRunMRU capture depends on sensor policy; outside endpoint telemetry if not collected
Ad-click chain to spoofed sign-inWeb proxy or secure web gateway URL logs; browser historyMEDIUMOutside endpoint telemetry
In-memory Doina, shellcode and stealerMemory scanning, behavioral prevention engineMEDIUMNo generic hunt telemetry for reflective loading or process hollowing is written in this pack
macOS usersTerminal process telemetryLOWPayload offline during research; no detection claimed
06

ATT&CK Mapping

TacticTechniqueObserved behaviorQuery / Control
Resource DevelopmentT1583.008 MalvertisingSponsored Google result for "amazon business"N1; S2
ExecutionT1204.004 Malicious Copy and PasteFake CAPTCHA copies a command, victim pastes it into RunQ2, Q12; I2, S2
ExecutionT1059.003 Windows Command Shellcmd executes the finger-returned .plan scriptQ1, Q2; I3
Defense EvasionT1218 System Binary Proxy Executionfinger.exe and tar.exe used as living-off-the-land binariesQ1, Q5; I1, N1
Command and ControlT1105 Ingress Tool Transferfinger over 79/tcp, curl for IronPython, timer6, v6 and Node package downloadsQ3, Q4, Q5, Q8; I1
Defense EvasionT1036.008 Masquerade File TypeIronPython ZIP saved with a .pdf extensionQ5
ExecutionT1059.006 Pythonipyw32.exe runs a Base64 and zlib Python blob, then timer6Q6, Q7, Q8; N1
Defense EvasionT1027 Obfuscated Files or InformationComma, caret, hyphen and underscore padding; Cyrillic-substituted Base64; XOR shellcode; RC4 and AES-256-GCM payloadsQ2, Q7
Defense EvasionT1620 Reflective Code Loading / T1055.012 Process HollowingShellcode in memory; sRDI injects the stealer by process hollowingNone (gap); S1
ExecutionT1059.007 JavaScriptnode.exe runs obfuscated index.js from ProgramData\NodeViewQ9
Credential Access / CollectionT1555.003 Credentials from Web Browsers; T1005 Data from Local SystemSuspected Lumma Stealer targets browsers, wallets, password managers, email clientsNone (gap); C2
Command and ControlT1071.001 Web ProtocolsHTTPS POST and WebSocket C2; DNS to barbecue-themed domainsQ8, Q13
Command and ControlT1219 Remote Access SoftwarePirated NetSupport Client at ProgramData\Prodclear, 725/tcpQ10, Q11; I1
07

Native Audit-Log Hunts

IDSourceWhat to look for
N1Web proxy, secure web gateway or browser historyA request whose path or query carries the ad-click markers aclk or gclid (also gadsource, gadcampaignid, gbraid) followed within minutes by sites.google.com/view/ch-pc/sign-in or a subdomain of advancedfences.com. Huntress recommends these markers to reconstruct the ad-to-malicious-site chain.
N2Firewall, NetFlow, proxyAny outbound 79/tcp from a workstation subnet; any 725/tcp flow; flows to 167.148.201.106.
N3Windows Security 4688 with command-line auditing, or Sysmon 1 / 3 / 11 / 22finger.exe process creation; Sysmon 3 connections from finger.exe (the SigmaHQ rule logic); ipyw32.exe or a node.exe from ProgramData; file creation under %TEMP% of an IronPython*.pdf.
N4DNS server or resolver logsQueries for the eight published second-level domains and the advancedfences.com subdomain.
N5File system sweep (read-only)Existence of C:\ProgramData\NodeView and C:\ProgramData\Prodclear, and GUID-named .tmp files of roughly 17KB and 19MB nearby. See playbook P5 for a read-only check.
N6Proxy logs, timer6 and v6 pathsURL paths containing 90e4a147-1234-505c-a024-062e543b5df8 or KsxmmKiN5N0j, including a ?exclude_bins=true query on the Node package URL.
08

Hunt Queries: CrowdStrike CQL, SentinelOne PowerQuery and Defender XDR KQL

Show all queries in
Pick your tenant's cloud first: every "Open in Falcon" button below uses this selection.

Set the time range in the Falcon time picker (7 to 30 days). No query carries an in-query time filter. finger.exe, ipyw32.exe, node.exe and Client32.exe are legitimate binaries: every detection below is behavioral and none should be turned into a block rule for the binary itself.

Q1 · finger.exe process execution
CONF HIGH FP LOW COST LOW

Looks for: Any execution of the built-in finger client. Stage 1 of the chain pulls the .plan script with it. Run this first: it is the highest-fidelity single signal.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A process the sensor did not observe starting is not captured.
  • PowerQuery assumes: On a Process Creation event src.process.user is the user of the creating process.
  • PowerQuery assumes: tgt.process.name holds the bare image name of the created process.
  • KQL – Defender XDR: A process the sensor did not observe starting is not captured.
  • KQL – Defender XDR assumes: FileName holds the bare image name of the created process.
// HUNT: finger.exe process execution
// MITRE: T1218, T1059.003
// CONF: high | FP: low | COST: low | REQUIRES: process creation with command line (ProcessRollup2)
// FALSE POSITIVES: a legacy admin or lab user running finger against an internal Unix host; very rare on modern Windows
// TUNING: exclude a named jump-host asset group if finger is still used there; otherwise treat every hit as suspect
#event_simpleName=ProcessRollup2
| FileName=/^finger\.exe$/i
| table([@timestamp, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName, aid], limit=200)
Q2 · Obfuscated finger command line inside cmd.exe (comma, caret, hyphen, underscore padding)
CONF HIGH FP LOW COST LOW

Looks for: The ClickFix command breaks the word finger apart with commas, carets, hyphens and underscores that cmd ignores. This regex tolerates those separators between letters and requires a user@host argument. It is a behavioral shape, not the real command (the article does not reproduce the obfuscated string).

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A command line passed through an environment variable and expanded after launch is not visible.
  • PowerQuery assumes: matches is case-insensitive unless :matchcase is given.
  • PowerQuery assumes: On a Process Creation event src.process.user is the user of the creating process.
  • KQL – Defender XDR: A command line passed through an environment variable and expanded after launch is not visible.
  • KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: Obfuscated finger command line inside cmd.exe (comma, caret, hyphen, underscore padding)
// MITRE: T1204.004, T1027, T1059.003
// CONF: high | FP: low | COST: low | REQUIRES: process creation with command line (ProcessRollup2)
// FALSE POSITIVES: none expected; the pattern needs finger-shaped letters plus a user@host argument
// TUNING: none expected; if a legitimate script matches, anchor the regex to the parent process instead
#event_simpleName=ProcessRollup2
| FileName=/^cmd\.exe$/i
| CommandLine=/f[,^_-]*i[,^_-]*n[,^_-]*g[,^_-]*e[,^_-]*r[,^_-]*\s*\S+@[a-z0-9.-]+\.[a-z]{2,}/i
| table([@timestamp, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName, aid], limit=200)
Q3 · Outbound TCP/79 (finger protocol) from any process
CONF HIGH FP LOW COST LOW

Looks for: Finger travels in plaintext on 79/tcp and almost no network blocks it. Any workstation connecting to port 79 is anomalous. Also catches a renamed finger client, because it keys on the port.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A connection the sensor did not observe is not captured.
  • PowerQuery assumes: IP Connect events carry the destination port in dst.port.number as a number.
  • PowerQuery assumes: IP Connect covers outbound connections; inbound listeners on port 79 would need the direction field, which is not used here.
  • KQL – Defender XDR: A connection the sensor did not observe is not captured.
  • KQL – Defender XDR assumes: DeviceNetworkEvents rows with ActionType ConnectionFailed are also returned, which the CQL connect event would not include.
// HUNT: Outbound TCP/79 (finger protocol) from any process
// MITRE: T1105, T1071
// CONF: high | FP: low | COST: low | REQUIRES: network connections with remote port (NetworkConnectIP4)
// FALSE POSITIVES: legacy finger usage against internal Unix hosts; vulnerability scanners on a scanner host
// TUNING: exclude internal RFC1918 destinations and your scanner asset group
#event_simpleName=NetworkConnectIP4
| RemotePort=79
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, RemoteAddressIP4, RemotePort, aid], limit=200)
Q4 · DNS lookup initiated by finger.exe
CONF HIGH FP LOW COST LOW

Looks for: Resolves the attacker .plan host. The campaign finger target was grillrecipespro[.]com; this query is domain-agnostic so it also catches rotation to new domains.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A lookup answered from the host cache without a DNS event is not captured.
  • PowerQuery assumes: The queried name is in event.dns.request; some schema versions use dns.request instead, so confirm which is populated.
  • KQL – Defender XDR: A lookup answered from the host cache without a DNS event is not captured.
  • KQL – Defender XDR assumes: ActionType DnsQueryResponse is populated on this tenant.
  • KQL – Defender XDR assumes: The name is under DnsQueryString or QueryName in AdditionalFields; the readiness test prints AdditionalFields so you can see which key your tenant uses.
// HUNT: DNS lookup initiated by finger.exe
// MITRE: T1071, T1105
// CONF: high | FP: low | COST: low | REQUIRES: DNS requests with process context (DnsRequest)
// FALSE POSITIVES: none expected on modern endpoints
// TUNING: none expected; treat every hit as an incident until proven otherwise
#event_simpleName=DnsRequest
| ContextBaseFileName=/^finger\.exe$/i
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, DomainName, aid], limit=200)
Q5 · curl downloading IronPython and tar unpacking a .pdf archive
CONF MEDIUM FP MEDIUM COST LOW

Looks for: Stage 2: the .plan script uses curl to fetch IronPython.3.4.2.zip into the user Temp directory saved with a .pdf extension, then unpacks it with the built-in tar. The two branches below cover both halves. FP: developers fetching IronPython releases; tar extracting legitimately named .pdf archives is rare. Tuning: exclude developer asset groups for the IronPython branch; the tar-on-.pdf branch needs no exclusion.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A download performed by a different tool than curl.exe is not captured.
  • PowerQuery assumes: contains is a plain substring test and is case-insensitive by default.
  • KQL – Defender XDR: A download performed by a different tool than curl.exe is not captured.
  • KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: curl downloading IronPython and tar unpacking a .pdf archive
// MITRE: T1105, T1036.008, T1218
// CONF: medium | FP: medium | COST: low | REQUIRES: process creation with command line (ProcessRollup2)
// FALSE POSITIVES: developers fetching IronPython releases; tar extracting legitimately named .pdf archives is rare
// TUNING: exclude developer asset groups for the IronPython branch; the tar-on-.pdf branch needs no exclusion
#event_simpleName=ProcessRollup2
| (FileName=/^curl\.exe$/i CommandLine=/IronPython/i) or (FileName=/^tar\.exe$/i CommandLine=/\.pdf/i)
| table([@timestamp, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName, aid], limit=200)
Q6 · IronPython ipyw32.exe execution (stock interpreter, behavioral detect)
CONF HIGH FP MEDIUM COST LOW

Looks for: Stage 3: the stock IronPython windowless interpreter runs from a net462 folder. This is a legitimate binary, so it is a behavioral detection only and never a prevent target. FP: developers and build agents that use IronPython; the chain runs it from a net462 folder under a user profile, which is unusual. Tuning: exclude developer and build asset groups; keep alerting on ipyw32.exe launched from a user-writable path with a cmd.exe parent.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A renamed interpreter outside an IronPython folder is not captured by the path branch.
  • PowerQuery assumes: tgt.process.image.path holds the full Windows image path with backslash separators.
  • PowerQuery assumes: matches is case-insensitive unless :matchcase is given.
  • KQL – Defender XDR: A renamed interpreter outside an IronPython folder is not captured by the path branch.
  • KQL – Defender XDR assumes: FolderPath holds the full image path of the created process, folder plus file name.
// HUNT: IronPython ipyw32.exe execution (stock interpreter, behavioral detect)
// MITRE: T1059.006, T1204.004
// CONF: high | FP: medium | COST: low | REQUIRES: process creation with command line (ProcessRollup2)
// FALSE POSITIVES: developers and build agents that use IronPython; the chain runs it from a net462 folder under a user profile, which is unusual
// TUNING: exclude developer and build asset groups; keep alerting on ipyw32.exe launched from a user-writable path with a cmd.exe parent
#event_simpleName=ProcessRollup2
| FileName=/^ipyw(32)?\.exe$/i or ImageFileName=/\\IronPython[^\\]*\\.*net462\\/i
| table([@timestamp, ComputerName, UserName, FileName, ImageFileName, CommandLine, ParentBaseFileName, aid], limit=200)
Q7 · IronPython launched with an inline encoded script
CONF HIGH FP LOW COST LOW

Looks for: The .plan script passes a Base64-encoded, zlib-compressed Python blob to ipyw32.exe on the command line. Narrower than Q6, so far fewer benign hits.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A script read from a file instead of the command line is not visible here.
  • PowerQuery assumes: matches is case-insensitive unless :matchcase is given.
  • KQL – Defender XDR: A script read from a file instead of the command line is not visible here.
  • KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: IronPython launched with an inline encoded script
// MITRE: T1059.006, T1027
// CONF: high | FP: low | COST: low | REQUIRES: process creation with command line (ProcessRollup2)
// FALSE POSITIVES: a developer passing an inline base64 or zlib snippet to IronPython; uncommon
// TUNING: none expected; review any hit manually
#event_simpleName=ProcessRollup2
| FileName=/^ipyw(32)?\.exe$/i
| CommandLine=/(base64|b64decode|zlib|decompress)/i
| table([@timestamp, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName, aid], limit=200)
Q8 · IronPython interpreter making network connections or DNS lookups
CONF HIGH FP LOW COST LOW

Looks for: ipyw32.exe fetches the timer6 loader over HTTP from the staging domain, so an IronPython process talking to the internet is the network half of Q6/Q7.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptions, telemetry-gapProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A connection the sensor did not observe is not captured.
  • PowerQuery assumes: The queried name is in event.dns.request; some schema versions use dns.request instead, so confirm which is populated.
  • PowerQuery assumes: Event types are matched case-sensitively as IP Connect and DNS Resolved.
  • KQL – Defender XDR: The connection half of the CQL (outbound connections by the interpreter) is not covered; run a DeviceNetworkEvents query on InitiatingProcessFileName for ipyw.exe and ipyw32.exe separately.
  • KQL – Defender XDR assumes: ActionType DnsQueryResponse is populated on this tenant.
  • KQL – Defender XDR assumes: The name is under DnsQueryString or QueryName in AdditionalFields; the readiness test prints AdditionalFields so you can see which key your tenant uses.
// HUNT: IronPython interpreter making network connections or DNS lookups
// MITRE: T1105, T1071.001
// CONF: high | FP: low | COST: low | REQUIRES: network connections and DNS with process context (NetworkConnectIP4, DnsRequest)
// FALSE POSITIVES: IronPython scripts that call web services; rare outside developer hosts
// TUNING: exclude developer asset groups
#event_simpleName=/^(NetworkConnectIP4|DnsRequest)$/
| ContextBaseFileName=/^ipyw(32)?\.exe$/i
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, DomainName, RemoteAddressIP4, RemotePort, aid], limit=200)
Q9 · node.exe running index.js from ProgramData (NodeView package)
CONF HIGH FP MEDIUM COST LOW

Looks for: Stage 4: Doina unpacks a portable Node.js runtime plus index.js into C:\ProgramData\NodeView and runs node.exe against it. node.exe is legitimate, so this is behavioral detection only. FP: software that bundles its own Node.js runtime under ProgramData; check the folder name before dismissing. Tuning: exclude known software that ships node.exe under ProgramData in your baseline; the NodeView folder name is the discriminator.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A node.exe renamed to another file name is not captured.
  • PowerQuery assumes: tgt.process.image.path holds the full Windows image path with backslash separators.
  • KQL – Defender XDR: A node.exe renamed to another file name is not captured.
  • KQL – Defender XDR assumes: FolderPath holds the full image path of the created process.
// HUNT: node.exe running index.js from ProgramData (NodeView package)
// MITRE: T1059.007, T1105
// CONF: high | FP: medium | COST: low | REQUIRES: process creation with command line (ProcessRollup2)
// FALSE POSITIVES: software that bundles its own Node.js runtime under ProgramData; check the folder name before dismissing
// TUNING: exclude known software that ships node.exe under ProgramData in your baseline; the NodeView folder name is the discriminator
#event_simpleName=ProcessRollup2
| FileName=/^node\.exe$/i
| ImageFileName=/\\ProgramData\\/i
| CommandLine=/index\.js/i
| table([@timestamp, ComputerName, UserName, ImageFileName, CommandLine, ParentBaseFileName, aid], limit=200)
Q10 · Client32.exe (NetSupport Client) running from ProgramData
CONF HIGH FP MEDIUM COST LOW

Looks for: Stage 5: a pirated NetSupport Client is deployed to C:\ProgramData\Prodclear. Client32.exe is a legitimate signed RMM binary, so detect on the location and context only. FP: a sanctioned NetSupport Manager deployment that installs the client under ProgramData. Tuning: exclude hosts and paths of your approved NetSupport deployment; the Prodclear folder name was the observed rogue location.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A client renamed to another file name is not captured.
  • PowerQuery assumes: tgt.process.image.path holds the full Windows image path with backslash separators.
  • KQL – Defender XDR: A client renamed to another file name is not captured.
  • KQL – Defender XDR assumes: FolderPath holds the full image path of the created process.
// HUNT: Client32.exe (NetSupport Client) running from ProgramData
// MITRE: T1219
// CONF: high | FP: medium | COST: low | REQUIRES: process creation with command line (ProcessRollup2)
// FALSE POSITIVES: a sanctioned NetSupport Manager deployment that installs the client under ProgramData
// TUNING: exclude hosts and paths of your approved NetSupport deployment; the Prodclear folder name was the observed rogue location
#event_simpleName=ProcessRollup2
| FileName=/^client32\.exe$/i
| ImageFileName=/\\ProgramData\\/i
| table([@timestamp, ComputerName, UserName, ImageFileName, CommandLine, ParentBaseFileName, aid], limit=200)
Q11 · NetSupport C2: connection to 167.148.201.106 or Client32.exe on port 725
CONF HIGH FP LOW COST LOW

Looks for: The Huntress-observed NetSupport C2 is 167.148.201.106 on 725/tcp. Second branch catches a rotated address when Client32.exe uses the same port.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A connection the sensor did not observe is not captured.
  • PowerQuery assumes: IP Connect events carry the destination port in dst.port.number as a number.
  • KQL – Defender XDR: A connection the sensor did not observe is not captured.
  • KQL – Defender XDR assumes: DeviceNetworkEvents rows with ActionType ConnectionFailed are also returned, which the CQL connect event would not include.
// HUNT: NetSupport C2: connection to 167.148.201.106 or Client32.exe on port 725
// MITRE: T1219, T1071.001
// CONF: high | FP: low | COST: low | REQUIRES: network connections with process context (NetworkConnectIP4)
// FALSE POSITIVES: none expected for the IP; port 725 alone is not used here without the process filter
// TUNING: none expected; the IP is single-source so keep it detect and re-verify before any block
#event_simpleName=NetworkConnectIP4
| (RemoteAddressIP4="167.148.201.106") or (RemotePort=725 ContextBaseFileName=/^client32\.exe$/i)
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, RemoteAddressIP4, RemotePort, aid], limit=200)
Q12 · DNS resolution of the campaign domains (atomic IOC sweep)
CONF HIGH FP LOW COST MEDIUM

Looks for: Sweeps the eight published second-level domains from the Huntress report (finger host, delivery, Doina C2 and Node package hosts). Ships detect only: single reporting lineage.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: Rotated domains outside the eight listed labels are not covered.
  • PowerQuery assumes: The queried name is in event.dns.request; some schema versions use dns.request instead, so confirm which is populated.
  • PowerQuery assumes: matches is case-insensitive unless :matchcase is given.
  • KQL – Defender XDR: Rotated domains outside the eight listed labels are not covered.
  • KQL – Defender XDR assumes: ActionType DnsQueryResponse is populated on this tenant.
  • KQL – Defender XDR assumes: The name is under DnsQueryString or QueryName in AdditionalFields; the readiness test prints AdditionalFields so you can see which key your tenant uses.
// HUNT: DNS resolution of the campaign domains (atomic IOC sweep)
// MITRE: T1071.001, T1105
// CONF: high | FP: low | COST: medium | REQUIRES: DNS requests (DnsRequest)
// FALSE POSITIVES: none expected; any hit warrants host triage
// TUNING: none expected; absence of hits is not evidence of absence because the operators rotate barbecue-themed names
#event_simpleName=DnsRequest
| DomainName=/(^|\.)(grillrecipespro|grillmasterchef|thegrilljournal|homelygrill|perfectgrillrecipes|embersandbites|kiriosyka|liokida)\.com$/i
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, DomainName, aid], limit=500)
Q13 · Run-dialog (RunMRU) entry shaped like the obfuscated finger command
CONF MEDIUM FP LOW COST LOW

Looks for: The command the victim pastes into Run is recorded in the RunMRU key. Same finger-shaped regex as Q2, applied to the registry value.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: If the agent policy does not capture RunMRU writes the query returns nothing, which is a telemetry gap and not a clean result.
  • PowerQuery assumes: RunMRU value writes are captured as Registry Value Modified events on this tenant.
  • PowerQuery assumes: registry.value holds the written string data.
  • KQL – Defender XDR: If the sensor does not record RunMRU writes the query returns nothing, which is a telemetry gap and not a clean result.
  • KQL – Defender XDR assumes: RunMRU value writes are recorded as RegistryValueSet on this tenant.
  • KQL – Defender XDR assumes: RegistryValueData holds the written string data.
// HUNT: Run-dialog (RunMRU) entry shaped like the obfuscated finger command
// MITRE: T1204.004
// CONF: medium | FP: low | COST: low | REQUIRES: registry value writes (RegGenericValueUpdate); RunMRU capture depends on sensor policy, validate in tenant
// FALSE POSITIVES: none expected
// TUNING: none expected; if RunMRU writes are not captured in your tenant this returns nothing, which is a telemetry gap and not a clean result
#event_simpleName=/^(RegGenericValueUpdate|AsepValueUpdate)$/
| RegObjectName=/RunMRU/i
| RegStringValue=/f[,^_-]*i[,^_-]*n[,^_-]*g[,^_-]*e[,^_-]*r[,^_-]*\s*\S+@[a-z0-9.-]+\.[a-z]{2,}/i
| table([@timestamp, ComputerName, UserName, RegObjectName, RegValueName, RegStringValue, aid], limit=200)
Q14 · Multi-stage correlation: two or more chain tools on one host
CONF HIGH FP LOW COST MEDIUM

Looks for: Hosts that run two or more of finger.exe, ipyw32.exe and Client32.exe in the window. Escalate regardless of the individual query ratings.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: The CQL also lists which tools were seen; this tab returns the counts and first and last seen times only. Run the process-creation card for the tool names.
  • PowerQuery assumes: Hosts are grouped by endpoint.name; two hosts that share a name would be merged.
  • PowerQuery assumes: estimate_distinct is approximate but exact at this cardinality.
  • KQL – Defender XDR: The CQL counts file names without lower-casing; the case-folding here can only merge, never split, hits.
  • KQL – Defender XDR assumes: FileName holds the bare image name of the created process.
  • KQL – Defender XDR assumes: File names are lower-cased before counting, so Client32.exe and client32.exe count once.
// HUNT: Multi-stage correlation: two or more chain tools on one host
// MITRE: T1204.004, T1059.006, T1219
// CONF: high | FP: low | COST: medium | REQUIRES: process creation (ProcessRollup2)
// FALSE POSITIVES: a developer host that legitimately runs IronPython and a sanctioned NetSupport client
// TUNING: exclude developer and approved remote-support asset groups
#event_simpleName=ProcessRollup2
| FileName=/^(finger|ipyw32|ipyw|client32)\.exe$/i
| groupBy([aid, ComputerName], function=[count(FileName, distinct=true, as=distinct_tools), collect([FileName])])
| distinct_tools >= 2
09

Detection Rules by Platform

Five queries are clean enough to promote to Custom IOA. All are detect-only (Monitor). No rule blocks a legitimate binary and the pack recommends no prevent action.

CrowdStrike: Custom IOA

IOA nameFromRule typePatternExclusionsAction
DoinaClickFix, finger.exe ExecutionPromote Q1Process Creation (Windows)Image finger.exeNamed legacy jump hostsDetect: High (never Block: stock binary)
DoinaClickFix, Obfuscated finger via cmdPromote Q2Process Creation (Windows)Image cmd.exe; command line matches finger letters with separator padding and a user@host argumentNone knownDetect: High
DoinaClickFix, IronPython Inline ScriptPromote Q7Process Creation (Windows)Image ipyw32.exe or ipyw.exe; command line contains base64 or zlib decode callsDeveloper asset groupDetect: High (never Block: stock interpreter)
DoinaClickFix, NodeView node.exePromote Q9Process Creation (Windows)Image node.exe under \ProgramData\; command line contains index.jsKnown ProgramData Node appsDetect: Medium (never Block: stock runtime)
DoinaClickFix, Client32 in ProgramDataPromote Q10Process Creation (Windows)Image client32.exe under \ProgramData\Approved NetSupport deploymentDetect: Medium (never Block: legitimate RMM)

Deployment path

  1. Endpoint security → Configuration → Custom IOA rule groups. Create a group for this campaign on a pilot prevention policy.
  2. Create each rule in Monitor severity and leave it one business week.
  3. Do not raise any rule to Block. All five patterns match legitimate binaries.
  4. Import the section 10 CSV into IOC Management as detect entries.

Sample alert package (Q1)

  • Subject: [HIGH] Detection: finger.exe executed (ClickFix chain)
  • Body: finger.exe ran on HOST-01 as user jdoe, parent process shown in the alert. In the Amazon-themed ClickFix chain this retrieves the .plan script that starts the IronPython and Doina stages. Isolate the host, run Q3, Q6 and Q14 on the same aid, and begin the section 14 runbook.
  • Triage: (1) confirm the parent was explorer.exe or cmd.exe, (2) read the command line for a user@host argument, (3) run Q3 and Q4 for the port 79 connection and resolved host, (4) run Q5 to Q7 for curl, tar and IronPython within 5 minutes, (5) run Q9 and Q10 for NodeView and Prodclear, (6) check the user's browser history for the ad-click markers, (7) isolate and open credential resets for the user.

Investigate-only queries

  • Q3, Q4, Q5, Q6, Q8, Q11, Q12, Q13, Q14: schedule to a hunt queue. Q14 is the correlation query: any host it returns escalates regardless of individual ratings.

SentinelOne: custom detection rules

RuleSource queryRun asNotes
DoinaClickFix, finger.exe ExecutionQ1, PowerQuery tabScheduled custom detection ruleBind 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
DoinaClickFix, Obfuscated finger via cmdQ2, PowerQuery tabScheduled custom detection ruleBind 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
DoinaClickFix, IronPython Inline ScriptQ7, PowerQuery tabScheduled custom detection ruleBind 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
DoinaClickFix, NodeView node.exeQ9, PowerQuery tabScheduled custom detection ruleBind 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
DoinaClickFix, Client32 in ProgramDataQ10, PowerQuery tabScheduled custom detection ruleBind 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

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.

Microsoft Defender: custom detection rules

RuleSource queryRun asNotes
DoinaClickFix, finger.exe ExecutionQ1, KQL – Defender XDR tabCustom detection rule, alert only, every hourThe query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself. This pack's own text mentions a baseline or pilot; follow it as written
DoinaClickFix, Obfuscated finger via cmdQ2, KQL – Defender XDR tabCustom detection rule, alert only, every hourThe query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself. This pack's own text mentions a baseline or pilot; follow it as written
DoinaClickFix, IronPython Inline ScriptQ7, KQL – Defender XDR tabCustom detection rule, alert only, every hourThe query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself. This pack's own text mentions a baseline or pilot; follow it as written
DoinaClickFix, NodeView node.exeQ9, KQL – Defender XDR tabCustom detection rule, alert only, every hourThe query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself. This pack's own text mentions a baseline or pilot; follow it as written
DoinaClickFix, Client32 in ProgramDataQ10, KQL – Defender XDR tabCustom detection rule, alert only, every hourThe query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself. This pack's own text mentions a baseline or pilot; follow it as written

Q3, Q4, Q5, Q6, Q8, Q11, Q12, Q13 and Q14 stay a hunt in this pack, not a rule. A rule can generate only 150 alerts per run. Continuous (NRT) frequency needs a single table and no comment lines, so delete the generated comment header from the query first.

10

Machine-Readable IOC Appendix

Read before importing: all 18 rows import as detect. They rest on one primary report, so none is prevent. The legitimate binaries (finger, curl, tar, ipyw32, node, Client32) are deliberately absent. Expiries are 6 months for infrastructure and hashes, 3 months for the ad-landing subdomain.

Falcon IOC Management CSVbulk import
type,value,action,severity,expiration,description,tags
domain,grillrecipespro.com,detect,high,2027-04-29,Attacker finger/.plan host (finger user@domain),campaign:DoinaAmazonClickFix
domain,grillmasterchef.com,detect,high,2027-04-29,Doina stage host (timer6 and v6 URLs),campaign:DoinaAmazonClickFix
domain,thegrilljournal.com,detect,high,2027-04-29,Reported attacker infrastructure and exfil host,campaign:DoinaAmazonClickFix
domain,homelygrill.com,detect,high,2027-04-29,Reported attacker infrastructure and exfil host,campaign:DoinaAmazonClickFix
domain,perfectgrillrecipes.com,detect,high,2027-04-29,Stealer initial check-in host,campaign:DoinaAmazonClickFix
domain,embersandbites.com,detect,medium,2027-04-29,Reported attacker infrastructure (role not detailed),campaign:DoinaAmazonClickFix
domain,kiriosyka.com,detect,high,2027-04-29,Node package delivery host (sqr-viewertr6),campaign:DoinaAmazonClickFix
domain,liokida.com,detect,high,2027-04-29,Node and stealer package host embedded in stealer,campaign:DoinaAmazonClickFix
domain,orders-amazon-com.advancedfences.com,detect,high,2027-01-29,Sponsored-ad landing subdomain (spoofed Amazon lure),campaign:DoinaAmazonClickFix
ipv4,167.148.201.106,detect,high,2027-04-29,Rogue NetSupport C2 (725/tcp; also hosts an unrelated restaurant site),campaign:DoinaAmazonClickFix
sha256,d864b28c302db9ed10baf8def0fb26bac0b97d27349d22c4e9390d30fce54649,detect,high,2027-04-29,timer6 loader script,campaign:DoinaAmazonClickFix
sha256,891cc3ca2d29e9b185a8913e93810f48859d2be1f23ddd977a15cdbeed509e0e,detect,high,2027-04-29,v6 (Doina) RC4-decrypted body,campaign:DoinaAmazonClickFix
sha256,87a047160eb1a9b92e6ede511252dfc624b0f5a7185ac2cec1c7ebde8cdf4eea,detect,high,2027-04-29,index.js obfuscated Node loader,campaign:DoinaAmazonClickFix
sha256,035d396b3a329f59d680dc36a0a639eb7fb306bea97e42f5f53293dce817e8b7,detect,high,2027-04-29,Nodeview.zip package,campaign:DoinaAmazonClickFix
sha256,24a293a662600b2292d9259baebba1c09b41df82a5c9c20f8572625ae759696f,detect,high,2027-04-29,Decrypted payload attributed to Lumma Stealer (Huntress hedges),campaign:DoinaAmazonClickFix
sha256,b8419a676a3d4af04ea98287a2b85052fae5c06e6278ca9d8bfa4b5b396b39a6,detect,high,2027-04-29,Decrypted payload attributed to Lumma Stealer (Huntress hedges),campaign:DoinaAmazonClickFix
sha256,42527a4388ef4ade6f4eaf52706f0ab31cb4e9ced3a56a6b15402551f9f01208,detect,high,2027-04-29,Decrypted payload attributed to Lumma Stealer (Huntress hedges),campaign:DoinaAmazonClickFix
sha256,408b7fc4f08f2a9044046025f05995e8cbd5c96c39844aaa8a7eb8ee4697ea89,detect,high,2027-04-29,Decrypted payload attributed to Lumma Stealer (Huntress hedges),campaign:DoinaAmazonClickFix
Microsoft Defender indicators CSVSettings, Endpoints, Indicators, Import: audit only
indicatorType,indicatorValue,action,title,description,expirationTime,severity,recommendedActions,rbacGroups,category,mitretechniques,GenerateAlert
DomainName,grillrecipespro.com,Audit,Attacker finger/.plan host,Attacker finger/.plan host (finger user@domain),2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
DomainName,grillmasterchef.com,Audit,Doina stage host,Doina stage host (timer6 and v6 URLs),2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
DomainName,thegrilljournal.com,Audit,Reported attacker infrastructure and exfil host,Reported attacker infrastructure and exfil host,2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
DomainName,homelygrill.com,Audit,Reported attacker infrastructure and exfil host,Reported attacker infrastructure and exfil host,2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
DomainName,perfectgrillrecipes.com,Audit,Stealer initial check-in host,Stealer initial check-in host,2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
DomainName,embersandbites.com,Audit,Reported attacker infrastructure,Reported attacker infrastructure (role not detailed),2027-04-29T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True
DomainName,kiriosyka.com,Audit,Node package delivery host,Node package delivery host (sqr-viewertr6),2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
DomainName,liokida.com,Audit,Node and stealer package host embedded in stealer,Node and stealer package host embedded in stealer,2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
DomainName,orders-amazon-com.advancedfences.com,Audit,Sponsored-ad landing subdomain,Sponsored-ad landing subdomain (spoofed Amazon lure),2027-01-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,167.148.201.106,Audit,Rogue NetSupport C2,Rogue NetSupport C2 (725/tcp; also hosts an unrelated restaurant site),2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,d864b28c302db9ed10baf8def0fb26bac0b97d27349d22c4e9390d30fce54649,Audit,timer6 loader script,timer6 loader script,2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,891cc3ca2d29e9b185a8913e93810f48859d2be1f23ddd977a15cdbeed509e0e,Audit,v6,v6 (Doina) RC4-decrypted body,2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,87a047160eb1a9b92e6ede511252dfc624b0f5a7185ac2cec1c7ebde8cdf4eea,Audit,index.js obfuscated Node loader,index.js obfuscated Node loader,2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,035d396b3a329f59d680dc36a0a639eb7fb306bea97e42f5f53293dce817e8b7,Audit,Nodeview.zip package,Nodeview.zip package,2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,24a293a662600b2292d9259baebba1c09b41df82a5c9c20f8572625ae759696f,Audit,Decrypted payload attributed to Lumma Stealer,Decrypted payload attributed to Lumma Stealer (Huntress hedges),2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,b8419a676a3d4af04ea98287a2b85052fae5c06e6278ca9d8bfa4b5b396b39a6,Audit,Decrypted payload attributed to Lumma Stealer,Decrypted payload attributed to Lumma Stealer (Huntress hedges),2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,42527a4388ef4ade6f4eaf52706f0ab31cb4e9ced3a56a6b15402551f9f01208,Audit,Decrypted payload attributed to Lumma Stealer,Decrypted payload attributed to Lumma Stealer (Huntress hedges),2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,408b7fc4f08f2a9044046025f05995e8cbd5c96c39844aaa8a7eb8ee4697ea89,Audit,Decrypted payload attributed to Lumma Stealer,Decrypted payload attributed to Lumma Stealer (Huntress hedges),2027-04-29T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True

Column names and allowed values are from Microsoft's documented parameter table. Check each expirationTime before importing: an indicator whose date has passed is already expired. Download the sample CSV from the Import page to confirm the column order before a bulk import. Each file takes at most 500 indicators. Learn describes the import per entity type, so if a mixed file is rejected, split it by indicatorType. An imported indicator does nothing unless the matching Advanced features are on (for example Custom network indicators and Allow or block file).

SentinelOne IOC importnot included

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.

Behavioral Signaturesdurable, outlives the domains
Doina via Amazon-themed ClickFix - behavioral signatures

B1  finger.exe executed, or any process connecting to 79/tcp from a workstation
B2  cmd.exe command line with finger letters padded by , ^ - _ and a user@host argument
B3  curl.exe fetching IronPython.3.4.2.zip; tar.exe extracting a .pdf archive
B4  ipyw32.exe running from a net462 folder under a user profile with an inline base64/zlib script
B5  ipyw32.exe making network connections to the staging domain
B6  node.exe running index.js from C:\ProgramData\NodeView
B7  Client32.exe running from C:\ProgramData\Prodclear (or any ProgramData folder)
B8  Client32.exe or any process connecting out on 725/tcp
B9  Referrer chain with aclk / gclid ad-click markers ending at a Google Sites sign-in page

KEY INSIGHT: every executable in the chain is legitimate. Detect the behavior and location, never the binary name alone.
NO PERSISTENCE reported by Huntress: absence of a scheduled task or Run key does not clear a host.
Named Artifactscontext for triage
Finger target       : user account on grillrecipespro[.]com, TCP 79 (plaintext)
.plan script        : hidden below 68 extra carriage returns
Archive             : IronPython.3.4.2.zip saved in the user Temp directory with a .pdf extension
Interpreter         : ipyw32.exe from the \net462 folder of the unpacked IronPython
Stage URLs          : /90e4a147-1234-505c-a024-062e543b5df8/timer6 and /v6 on grillmasterchef[.]com
Node package path   : /KsxmmKiN5N0j/sqr-viewertr6 (kiriosyka[.]com), /sqr-viewertr6z (liokida[.]com)
Node install folder : C:\ProgramData\NodeView (node.exe + index.js)
NetSupport folder   : C:\ProgramData\Prodclear (Client32.exe), 725/tcp, /fakeurl.htm
Loader behaviors    : timer6 = Cyrillic-substituted Base64 Python, 19-byte XOR shellcode key;
                      v6 = RC4, key in the first 64 bytes; payload files AES-256-GCM
Attribution         : none. Doina (vendor consensus); Lumma Stealer is hedged ("allegedly")
Control Auditverify hardening state
# Run dialog removed for the user?
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer' -Name NoRun -ErrorAction SilentlyContinue
# Outbound finger / NetSupport port rules present?
Get-NetFirewallRule -DisplayName 'HuntPack Block Outbound TCP 79','HuntPack Block Outbound TCP 725' -ErrorAction SilentlyContinue | Select-Object DisplayName, Enabled, Action
# Command-line process auditing on (needed for native 4688 hunts)?
Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit' -Name ProcessCreationIncludeCmdLine_Enabled -ErrorAction SilentlyContinue
# Any chain folders present? (read-only)
Test-Path 'C:\ProgramData\NodeView'; Test-Path 'C:\ProgramData\Prodclear' 
11

Detection Validation Gates

Work these in order. A query that has not cleared gate 2 has no business being an alert.

GateWhat to proveHowPass criteria
G1 · Telemetry readyThe events each query depends on arrive in your tenantRun each filter alone over 24h with count(). Confirm process creation with command line, network connections with a populated remote port, DNS requests with process name (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceNetworkEvents), and RunMRU registry writes (Q12).Non-zero counts and populated fields. A zero RunMRU count means the telemetry is not collected.
G2 · Benign baselineYou know what normal looks likeRun Q1 to Q14 over 30 days and classify every hit. Expect developer hosts on Q5, Q6, Q9 and a sanctioned NetSupport estate on Q10.Every recurring hit is explained and excluded, or escalated.
G3 · Positive testThe query fires on the behavior it claims to detectOn an isolated test host in a change window: run finger.exe against a local lab host (Q1, Q3); copy a harmless executable renamed to client32.exe into a throwaway ProgramData folder and start it (Q10). Do not use real malware or the clipboard command.The matching query fires.
G4 · Negative testYour exclusions did not blind the queryRe-run G3 with the tuning exclusions applied.Test events still fire.
G5 · PromotionSafe to alertCustom IOA in Monitor mode for one business week on a pilot policy.Zero unexplained detections.
G6 · Response readinessThe team can act on a hitTabletop the section 14 runbook.Analyst states the credential, session and wallet reset step without prompting.
12

Hardening: Tiered

Controls are ordered by leverage against this chain. It needs a Run dialog, an open path to 79/tcp, a user-writable place to run an interpreter, and no one watching ProgramData. Authority is MITRE mitigations plus the platform source named in each control. These are organization-level hardening controls and are separate from any Falcon prevent policy.

Immediate: deploy this week

I1 · Block outbound 79/tcp (and 725/tcp) at the host and perimeter firewall

Finger has no business use on modern endpoints and the stage-1 fetch needs it. The NetSupport C2 used 725/tcp.
Authority: MITRE M1037 (Filter Network Traffic); advice to block outbound finger on port 79 appears in the Security Online and BlueTeamCoolTeam write-ups. Windows Defender Firewall outbound rule. Verify: Get-NetFirewallRule (P1). Risk: low; inventory any legacy finger use first.

I2 · Remove the Run dialog for users who do not need it

ClickFix needs the victim to paste into Run. Huntress notes it does not stop variants that use PowerShell, a command prompt or the Explorer address bar, so treat this as partial.
Authority: MITRE M1042 (Disable or Remove Feature or Program). GPO Remove Run menu from Start Menu (NoRun). Verify: P2. Risk: medium; exempt IT and power users.

I3 · Turn on command-line process auditing

Without it, native 4688 hunts and many SIEM detections see no command line.
Authority: MS Security Baseline (Audit Process Creation, include command line). Verify: P3. Risk: low; raises log volume and may log secrets passed on command lines.

Near term: 1 to 4 weeks, pilot first

N1 · Application control in audit mode for finger.exe and ProgramData executables

Audit, then enforce, execution of finger.exe, executables under ProgramData and IronPython folders under user profiles.
Authority: MITRE M1038 (Execution Prevention); ASD Essential Eight application control; AppLocker or WDAC. Verify: P4 plus AppLocker audit events. Risk: medium; software installed under ProgramData needs allow rules.

N2 · Egress filtering: default-deny on nonstandard outbound ports for user workstations

Catches finger (79), NetSupport (725) and similar one-offs together. Authority: MITRE M1037. Risk: medium; needs an application port inventory.

N3 · Web filtering for IronPython release downloads from non-developer groups

The chain fetches IronPython.3.4.2.zip from the public GitHub release URL. Alert or block that path for users who do not develop on .NET. Authority: MITRE M1021 (Restrict Web-Based Content). Risk: low for non-developers.

Strategic: 1 to 3 months

S1 · Allow-list based application control (WDAC) for standard users

Removes the entire class of unsigned and user-writable interpreters and unexpected node.exe or Client32.exe copies. Authority: MITRE M1038; Microsoft WDAC guidance; CIS Controls v8 2.5 and 2.7. Risk: high effort.

S2 · Paid-search and malvertising controls plus ClickFix user awareness

No legitimate CAPTCHA asks anyone to paste text into an operating system command prompt. Teach that rule, and where a managed browser policy exists, funnel brand logins through bookmarks or a password manager rather than search ads. Report ad-click identifiers (aclk, gclid) to the ad platform. Authority: MITRE M1017 (User Training). ⚠ best-practice, no formal benchmark for the browser-policy half.

S3 · Credential hygiene for stealer exposure

Phishing-resistant MFA, no browser-stored passwords or wallets on managed endpoints, and short session lifetimes limit what an infostealer takes. Authority: MITRE M1032 (Multi-factor Authentication), M1027 (Password Policies).

13

Deployable Playbooks

Test every playbook on a pilot ring before fleet deployment. Each lists its prerequisites, reboot requirement and rollback.

P1 · Block outbound 79/tcp and 725/tcp (Windows Defender Firewall)

# Prerequisites: local administrator or GPO; confirm no legacy finger use and no sanctioned NetSupport estate on 725/tcp
# Reboot required: no
# Rollback: Remove-NetFirewallRule -DisplayName 'HuntPack Block Outbound TCP 79','HuntPack Block Outbound TCP 725'

New-NetFirewallRule -DisplayName 'HuntPack Block Outbound TCP 79' -Direction Outbound -Protocol TCP -RemotePort 79 -Action Block -Profile Any
New-NetFirewallRule -DisplayName 'HuntPack Block Outbound TCP 725' -Direction Outbound -Protocol TCP -RemotePort 725 -Action Block -Profile Any

# Verify
Get-NetFirewallRule -DisplayName 'HuntPack Block Outbound TCP 79','HuntPack Block Outbound TCP 725' | Select-Object DisplayName, Enabled, Action

P2 · Remove the Run dialog (per-user policy)

# Prerequisites: run as the target user, or push through GPO / logon script. Pilot ring first; exempt IT staff.
# Reboot required: no (sign out and back in, or restart Explorer)
# Rollback: Remove-ItemProperty -Path $k -Name NoRun   then sign out and back in

$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

P3 · Include the command line in process-creation events

# Prerequisites: local administrator; Audit Process Creation (Success) must also be enabled by audit policy
# Reboot required: no
# Rollback: Remove-ItemProperty -Path $k -Name ProcessCreationIncludeCmdLine_Enabled

$k = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit'
if (-not (Test-Path $k)) { New-Item -Path $k -Force | Out-Null }
New-ItemProperty -Path $k -Name ProcessCreationIncludeCmdLine_Enabled -PropertyType DWord -Value 1 -Force | Out-Null
auditpol /set /subcategory:"Process Creation" /success:enable

# Verify
Get-ItemProperty -Path $k -Name ProcessCreationIncludeCmdLine_Enabled

P4 · AppLocker audit-only rule for finger.exe

# Prerequisites: local administrator; Application Identity service running. Audit mode logs to
#   Applications and Services Logs > Microsoft > Windows > AppLocker > EXE and DLL. Nothing is blocked.
# Reboot required: no
# Rollback: Set-AppLockerPolicy -XmlPolicy "$env:TEMP\applocker-backup.xml"

Get-AppLockerPolicy -Local -Xml | Out-File "$env:TEMP\applocker-backup.xml" -Encoding utf8
$x = @'
<AppLockerPolicy Version="1">
  <RuleCollection Type="Exe" EnforcementMode="AuditOnly">
    <FilePathRule Id="7b2c1d10-4a1e-4d6b-9a52-0d3f6a1c9e01" Name="Allow all (audit baseline)" Description="" UserOrGroupSid="S-1-1-0" Action="Allow">
      <Conditions><FilePathCondition Path="*" /></Conditions>
    </FilePathRule>
    <FilePathRule Id="7b2c1d10-4a1e-4d6b-9a52-0d3f6a1c9e02" Name="Audit finger.exe" Description="Doina ClickFix hunt" UserOrGroupSid="S-1-1-0" Action="Deny">
      <Conditions><FilePathCondition Path="%SYSTEM32%\finger.exe" /></Conditions>
    </FilePathRule>
  </RuleCollection>
</AppLockerPolicy>
'@
$p = "$env:TEMP\huntpack-finger-audit.xml"
$x | Out-File $p -Encoding utf8
Set-AppLockerPolicy -XmlPolicy $p -Merge

# Verify
Get-AppLockerPolicy -Effective -Xml | Select-String 'finger.exe'

P5 · Read-only host check for chain folders

# Prerequisites: run as administrator on the suspect host; read-only, changes nothing
# Reboot required: no
# Rollback: none required, no state is changed

$paths = 'C:\ProgramData\NodeView','C:\ProgramData\Prodclear'
foreach ($p in $paths) { if (Test-Path $p) { Get-ChildItem $p -Recurse -Force -ErrorAction SilentlyContinue | Select-Object FullName, Length, LastWriteTime } }
Get-ChildItem "$env:TEMP" -Filter 'IronPython*' -Force -ErrorAction SilentlyContinue | Select-Object FullName, Length, LastWriteTime
Get-ChildItem "$env:LOCALAPPDATA" -Recurse -Filter 'ipyw32.exe' -ErrorAction SilentlyContinue | Select-Object FullName
14

Containment Runbook

Sequencing rule: the stealer takes credentials, browser sessions and wallet data in the first minutes. Isolate the host, but do not let endpoint work delay credential, session and wallet resets for the user.

PhaseActionsOwnerEvidence to capture
C0 · Triage
0 to 15 min
Confirm which query fired. Identify the user, host and time. Check whether Q1, Q3, Q6, Q9 and Q10 also fired on the same aid; run Q14.SOC L1Process tree; triggering query output; aid and ComputerName
Isolate · C1
15 to 30 min
Network-contain the host in Falcon. Do not power off: Doina, the shellcode and the stealer run in memory. Run P5 and capture a memory image if policy allows.SOC L2Containment timestamp; memory image; P5 output
Isolate: by platformCrowdStrike: network-contain the host. SentinelOne: network quarantine (Disconnect from Network; confirm the label in your console version). Microsoft Defender: Isolate device (full network isolation). Keep the host powered on for memory capture on all of them.SOC L2Containment timestamp; memory image; P5 output
C2 · Credentials
in parallel with C1
Reset the user's passwords and revoke browser and SaaS sessions and tokens; rotate saved password-manager master secrets if the manager ran on the host; move crypto-wallet funds and rotate seeds for wallets (Electrum, Ledger, Atomic Wallet) that were installed; reset email-client credentials. These are the application classes named in the report.IAM / IdentityReset and revocation log
C3 · Network blockAdd the section 10 domains and the IP to DNS and proxy blocklists, and block 79/tcp and 725/tcp egress (P1). Search N2, N4 and N6 for other hosts.Network teamHunt results across the estate
C4 · EradicatePreferred: reimage. The chain places two memory-resident loaders, a Node.js stage and a remote-management client, so cleanup of one host cannot prove a clean state. If reimage is not possible, stop node.exe and Client32.exe running from the chain folders, preserve then remove C:\ProgramData\NodeView and C:\ProgramData\Prodclear, and remove the IronPython folder and .pdf archive from the user profile. Huntress reports no persistence mechanism; still check run keys, scheduled tasks and services.SOC L2 / ITFile hashes; removal log
C5 · RecoverRejoin only after reimage or verified clean scan, with credentials already reset. Watch the host 14 days with Q14 and Q13. Apply I1 to I3.IT14-day clean report
C6 · ReportReport the sponsored ad and the Google Sites page to the providers; share new domains with your intel provider. Update the ticket and this pack.SOC leadTicket, report receipts
15

Detection Coverage Map

TechniqueBehaviorCQLIOAHardeningCrowdStrike coverageSentinelOneDefender XDR
T1204.004Run-dialog paste of an obfuscated finger commandQ2, Q12Yes (Q2)I2, S2GOOD (Q12 depends on RunMRU capture)Good, with assumptionsGood, with assumptions
T1218 / T1105finger.exe fetch of the .plan script over 79/tcpQ1, Q3, Q4Yes (Q1)I1, N1, N2GOODGood, with assumptionsGood, with assumptions
T1105 / T1036.008curl IronPython download, tar unpack of a .pdfQ5NoN3PARTIAL (developer FP)Partial: same limit as CrowdStrikePartial: same limit as CrowdStrike
T1059.006ipyw32.exe with an inline encoded scriptQ6, Q7, Q8Yes (Q7)N1, S1GOODGood, with assumptionsPartial: Q8 telemetry gap
T1059.007node.exe running index.js from ProgramData\NodeViewQ9Yes (Q9)N1, S1PARTIAL (folder-name dependent)Partial: same limit as CrowdStrikePartial: same limit as CrowdStrike
T1219Pirated NetSupport Client at ProgramData\Prodclear, 725/tcpQ10, Q11Yes (Q10)I1, N2GOODGood, with assumptionsGood, with assumptions
T1071.001C2 and delivery domainsQ13IOC MgmtN2GOOD (perishable; operators rotate names)Good, with assumptionsGood, with assumptions
Multi-stageChain tools co-occurring on one hostQ14NoS1GOODGood, with assumptionsGood, with assumptions
T1583.008Sponsored ad to spoofed Amazon sign-inNoneNoS2GAP (outside endpoint telemetry; native hunt N1)GAPGAP
T1620 / T1055.012Reflective loading of Doina; sRDI and process hollowing of the stealerNoneNoS1GAP (in-memory; rely on the sensor behavioral engine)GAPGAP
T1555.003 / T1005Credential and wallet theft, HTTPS and WebSocket exfilNoneNoS3GAP (handled by response; WebSocket content is outside endpoint telemetry)GAPGAP

Gap summary

  • The ad and lure page have no endpoint signal. Use proxy and browser history (N1).
  • The in-memory stages are not hunted. Doina and the stealer are injected; this pack detects the loaders and consequences, not the injection.
  • Indicators are perishable and single-lineage. The operators keep adding barbecue-themed domains.
  • No persistence is claimed because Huntress reports none.

Validation: gates G1 to G6 in section 11 govern promotion. No query proceeds to alert before clearing G2, and none recommends blocking a legitimate binary.

16

Hunt Summary Ticket

TITLE:      Amazon-themed ClickFix to Doina via finger.exe .plan, IronPython, Node.js stage, suspected Lumma, NetSupport
SEVERITY:   High - Huntress report 2026-10-21; at least three Huntress customers affected; no named actor
SCOPE:      All Windows endpoints with interactive users. Priority: users who search for Amazon business
            sign-in pages and users who store browser credentials or crypto wallets.

HYPOTHESIS: A user followed a sponsored result to a spoofed Amazon sign-in, passed a fake CAPTCHA and pasted an
            obfuscated command into Run. finger.exe fetched a .plan script from an attacker domain over 79/tcp;
            curl and tar unpacked IronPython; ipyw32.exe loaded timer6 and then Doina in memory; a Node.js stage
            injected a suspected Lumma Stealer; a pirated NetSupport Client was installed.

QUERIES:    Q1  finger.exe execution                          CONF high | FP low  | COST low
            Q2  obfuscated finger in cmd.exe                  CONF high | FP low  | COST low
            Q3  outbound TCP/79                               CONF high | FP low  | COST low
            Q4  finger.exe DNS lookup                         CONF high | FP low  | COST low
            Q5  curl IronPython / tar on .pdf                 CONF med  | FP med  | COST low
            Q6  ipyw32.exe execution                          CONF high | FP med  | COST low
            Q7  IronPython inline encoded script              CONF high | FP low  | COST low
            Q8  IronPython network / DNS                      CONF high | FP low  | COST low
            Q9  node.exe index.js in ProgramData              CONF high | FP med  | COST low
            Q10 Client32.exe in ProgramData                   CONF high | FP med  | COST low
            Q11 NetSupport C2 IP / port 725                   CONF high | FP low  | COST low
            Q12 RunMRU finger-shaped entry                    CONF med  | FP low  | COST low
            Q13 campaign domain DNS sweep                     CONF high | FP low  | COST med
            Q14 multi-tool correlation on one host            CONF high | FP low  | COST med

DO FIRST:   1. Q1, Q3 and Q14 across 30 days (finger is near-zero FP on a modern fleet)
            2. Q13 retrospective sweep (perishable)
            3. Q6 to Q10 on any host with a Q1 or Q3 hit
            4. Native hunt N1 (proxy ad-click markers) and N2 (firewall 79/725)

FINDINGS:   [ ] Q1 hits: ______    [ ] Q3 hits: ______    [ ] Q13 hits: ______
            [ ] Q9 hits: ______    [ ] Q10 hits: ______
            [ ] Hosts with 2+ chain tools (Q14): ______
            [ ] Users requiring credential, session and wallet reset: ______

GAPS:       - Sponsored ad and lure page: outside endpoint telemetry (native hunt N1)
            - In-memory Doina, shellcode and stealer injection not hunted
            - Credential theft covered by response, not detection
            - Indicators single-lineage (Huntress), so all ship detect; Lumma identification is hedged
            - No persistence reported by Huntress; none claimed

ACTIONS:    [ ] Promote Q1, Q2, Q7, Q9, Q10 to Custom IOA (Monitor mode, pilot policy, 1 week)
            [ ] Import the section 10 CSV into Falcon IOC Management (detect)
            [ ] Deploy Immediate hardening: I1 egress 79/725, I2 Run dialog, I3 command-line auditing
            [ ] Confirm DnsRequest process attribution and RunMRU capture (gate G1)

OWNER:      ______________________
VERSION:    v0.1 - 2026-10-29
17

Changelog

v0.1 2026-10-29 Initial draft. Built from the Huntress report of 2026-10-21 with Security Online, the SigmaHQ finger.exe network rule and BlueTeamCoolTeam (a separate campaign, behavior only) as corroboration. Fourteen CQL hunt queries, 18 detect-only atomic indicators, no prevent actions, no attribution. Lumma Stealer identification kept hedged as in the source; no persistence claimed. SentinelOne PowerQuery and Microsoft Defender KQL tabs added to Q1-Q14: SIEM Query Rosetta release 0.1.0 (public-beta; static-reviewed translations).
18

References

TierSourceUsed forAccessed
1Huntress: Amazon-Themed ClickFix Campaign Serves Up Finger-Licking MalwarePrimary report: chain, infrastructure, hashes2026-10-29
2Security Online: Amazon ClickFix Campaign Abuses Windows Finger CommandCorroboration of chain, no-attribution statement, port 79 control2026-10-29
2SigmaHQ: Network Connection Initiated via Finger.EXEIndependent detection logic for finger.exe network activity2026-10-29
3BlueTeamCoolTeam: Seven layers of obfuscation, one 1970s LOLBINIndependent confirmation of the technique (different campaign; no indicators used)2026-10-29
refMITRE ATT&CKTechnique IDs in section 6 and mitigation M-numbers in section 122026-10-29

Provenance statement. Every campaign domain, address and hash is reproduced from the Huntress report snapshot saved with this pack. The BlueTeamCoolTeam post describes a different finger and IronPython campaign and contributes no indicator. Search summaries were not used as a value source. The obfuscated ClickFix command is not published by the source and is not reproduced here.