HollowFrame & Matryoshka — Layered Loader and Nested Backdoors

Go-based modular loader framework delivering a two-variant Rust backdoor family via LNK phishing, Defender tampering and a chained DLL side-load. Reported by Blackpoint Cyber APG, 2026-07-30.
Threat
HollowFrame / Matryoshka
Severity
ACTIVE INTRUSION
Type
Loader framework + modular backdoor
Access
Spear-phishing link → encrypted archive → LNK
Version
v0.1 · 2026-08-01
Author
HuntPack
Confidence
High (single primary vendor report, corroborated)
01

Executive Summary

The attacker's objective was durable, deniable remote command execution inside a professional-services network, reached by walking malicious code through a chain of increasingly trusted components until the final implant ran inside a signed Microsoft process. Blackpoint Cyber's Adversary Pursuit Group documented the chain across two endpoints: a spear-phishing link, an attacker-controlled redirector, a Mega-hosted encrypted archive, a shortcut named to look like case documents, an XOR-obfuscated PowerShell downloader, a staged Python package, a fake python311.dll, the HollowFrame Go loader framework, and finally the Matryoshka Rust backdoor family in two variants.

Two properties make this pack worth running even if these exact indicators never appear in your environment. First, the actor prepared the ground before the payload arrived: PowerShell requested elevation, created %LOCALAPPDATA%\Programs\Python\Python311-Brief, then added Microsoft Defender exclusions for both that directory and the process name python.exe — all before a single executable was downloaded. Second, every executable stage ran under a name Windows expects: python.exe loading an adjacent rogue python311.dll, then a OneDrive updater.exe loading an adjacent rogue version.dll, then a Rust wtsapi32.dll proxying 41 genuine Terminal Services exports.

The highest-value defensive angle is therefore not the hashes. It is the ordering: a Defender exclusion for a user-writable directory, followed minutes later by a signed binary executing from that same directory and loading a same-directory dependency. Either event alone is common. The pair, in that order, on that path, is the intrusion. Queries Q3, Q4, Q6 and Q7 in this pack are built to be joined on host and time for exactly that reason.

The GitHub variant deserves separate attention. Matryoshka GitHub uses the GitHub Contents API against a private repository as a dead drop, with one directory per victim host holding beacon.json, cmd.json and result.json. Blocking api.github[.]com outright is not a viable control on most estates. Constraining which processes and which hosts may reach it is, and that is what the hardening section recommends.

Defender priority: hunt Defender exclusion changes first (Q3, Q4). The exclusions were added before the payloads landed, they persist after the malware is removed, and they are the one stage in this chain that leaves an obvious, durable, high-signal artifact on disk and in the registry.

02

Source Review & Web Hunter Notes

Two sources were fetched and saved verbatim as snapshots alongside this pack. Every atomic indicator shipped below traces to one of them. A third intended source could not be retrieved and is recorded here rather than silently dropped.

TierSourceKey findingCarry forward
1Blackpoint Cyber APG — "Nested Trust: HollowFrame's Layered Loader and Matryoshka Backdoors" (Nevan Beal, Sam Decker, 2026-07-30)Full technical chain, loader internals, both backdoor variants, complete file and network IOC tables, six defender recommendations.Yes — sole origin of every atomic indicator in this pack.
2The Hacker News — "HollowFrame Loader Deploys Matryoshka Backdoor in Spear-Phishing Attack on Law Firm" (Ravie Lakshmanan, 2026-07-31)Independent restatement of the chain and both C2 endpoints. Adds one detail absent from the primary report: the GitHub account was created 2023-01-06 and its profile was updated as recently as 2026-06-07.Partial — corroboration and account-age context only.
SC Media — "New HollowFrame loader and Matryoshka malware family discovered"Returned HTTP 403 on two separate retrieval attempts from two different fetchers. No snapshot exists.No — not cited, and no indicator in this pack depends on it.

Research notes and judgement calls

  • No actor attribution exists. The primary report states it is not known who is behind the activity. The Go build path Project220Rebr is explicitly assessed by the researchers as an internal build-directory name, not a malware family or an actor handle. Do not treat it as attribution.
  • Three of the eleven published hashes are legitimate host binaries — the bundled python.exe, vcruntime140.dll and the OneDrive updater.exe. They are the trusted halves of the side-load pairs, not malware. They are kept out of the block list and routed to a separate context-only block in section 10. Blocking them would break Python and OneDrive on clean hosts.
  • One published hash is missing: the report records "hash not recovered" for Case Documents.lnk. That row is shipped as a labelled placeholder, never as an invented value.
  • Only one search hit added anything. Every other result for this campaign was a syndicated republication of the trade-press article. Nothing independent of Blackpoint's telemetry has been published, so overall confidence rests on a single primary reporter — high on internal consistency, unconfirmed by a second sensor network.
  • Infrastructure perishability. Both IP addresses and the phishing redirector are single-campaign infrastructure with a short useful life. They are shipped with a three-month expiry; the hashes and the behavioural content are the durable half of this pack.
03

Hunt Brief & Attack Chain

Attack chain

#StepTelemetryHunt angle
1Spear-phishing email to multiple recipients; embedded link routes through an attacker-controlled redirector to a Mega-hosted encrypted archive.Mail gateway, proxy, DNSGateway search for the redirector host; proxy search for cloud-storage downloads of password-protected archives.
2Archive contains a shortcut named to look like case documents. User double-clicks it.ZipFileWritten, ProcessRollup2Archive written to a download path, followed shortly by an explorer.exe-parented script interpreter.
3Shortcut writes a Base64 blob and a companion command script into %TEMP%, then calls certutil.exe -decode to rebuild the next stage.ProcessRollup2Q1 — certutil decoding content inside a user temp path.
4Decoded script launches PowerShell, which retrieves an in-memory stage from a bare-IP HTTP server.ProcessRollup2, NetworkConnectIP4Q8 — known delivery IP. Behavioural: PowerShell reaching a bare IPv4 literal over plain HTTP.
5In-memory stage holds a 16-character key and a long hex payload; each byte is hex-decoded, XORed against the repeating key, and executed through Invoke-Expression.Script Block Logging (4104), ScriptControlScanTelemetryNative hunt: 4104 blocks containing a long hex literal plus Invoke-Expression.
6Stage checks for administrative rights; if absent it writes a temp script and relaunches PowerShell with -Verb RunAs -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden.ProcessRollup2Q2 — self-elevation relaunch with a hidden window and a policy bypass.
7Creates a staging directory under %LOCALAPPDATA%\Programs\Python and adds Defender exclusions for that directory and for the process name python.exe — before any payload is downloaded.ProcessRollup2, RegGenericValueUpdate, Defender 5007Q3 and Q4 — the highest-signal, longest-lived artifact in the whole chain.
8Downloads an archive named to imitate a Python embeddable distribution but carrying a non-standard architecture suffix; validates size and ZIP signature; extracts python.exe, python311.dll, vcruntime140.dll.ZipFileWritten, PeFileWrittenQ5 and Q7.
9Launches python.exe with no script, no module argument and no interactive console. It imports only Py_Main from the adjacent DLL, which is a 64-bit Go DLL exporting four Python-compatible names.ProcessRollup2Q6 — a Python host with nothing to interpret is a side-load, not a script run.
10HollowFrame decrypts an interleaved region (even offsets only) with XChaCha20-Poly1305 plus zlib to recover an AMD64 executable, then runs sandbox gates on uptime, installed memory, user-profile file count and cursor movement.None on the sensorGAP — in-process cryptography and evasion gates produce no distinct endpoint telemetry.
11Persists via an on-logon scheduled task with highest privileges and a 30-second delay, a permanent WMI event subscription on new logon-session instances, and a Startup-folder copy.ScheduledTaskRegistered, AsepValueUpdate, WMI-Activity 5861Q11 plus the native WMI subscription hunt in section 7.
12A second embedded container yields a native dropper, which stages a genuine OneDrive updater beside a rogue version.dll.PeFileWritten, ProcessRollup2Q7 — side-load DLL names written outside the system directories.
13Matryoshka HTTP runs inside the updater process, decodes its C2 endpoint from an XOR-encoded byte array, resolves WinHTTP at runtime and exchanges JSON tasking over plaintext HTTP. Commands run through cmd.exe /c with merged output.NetworkConnectIP4, ProcessRollup2Q8, Q9, Q12.
14Matryoshka GitHub proxies genuine Terminal Services exports while polling a private repository through the GitHub Contents API, one mailbox directory per victim host, using a spoofed OneDrive user agent.DnsRequest, proxy logsQ10 plus the proxy hunts in section 7.
15Built-in reconnaissance enumerates network configuration, local token and privilege detail, domain controllers, domain computers, privileged group membership and installed software; payloads are written, launched, or executed in memory via module overloading or an allocate-write-protect-execute sequence.ProcessRollup2, UserLogonPost-compromise: pivot on the discovery burst and on the merged-output shell pattern.

Hunt hypotheses (ordered by fidelity)

  1. H1 — Pre-staged Defender exclusion. A non-management process added a Defender path or process exclusion covering a user-writable directory, and executable content appeared under that path afterwards. Confidence: high. FP: medium (IT and line-of-business installers do this legitimately). Requires: ProcessRollup2, RegGenericValueUpdate.
  2. H2 — Python host with nothing to interpret. python.exe executed from a user-writable path with no script path, no -m module and no interactive flag. Confidence: high. FP: low. Requires: ProcessRollup2.
  3. H3 — Side-load DLL name in the wrong place. A file named python311.dll, version.dll or wtsapi32.dll was written outside a system or vendor-install directory. Confidence: high. FP: medium (genuine Python installs and application installers write these names). Requires: PeFileWritten.
  4. H4 — Shortcut-driven decode chain. certutil.exe -decode ran against content in a user temp path with a script interpreter or shell in the ancestry. Confidence: high. FP: medium. Requires: ProcessRollup2.
  5. H5 — Self-elevating hidden PowerShell. PowerShell relaunched itself with an elevation verb, a hidden window and an execution-policy bypass. Confidence: high. FP: low. Requires: ProcessRollup2.
  6. H6 — Trusted host talking to the internet. A Python host or an application updater opened outbound connections to endpoints outside its vendor's own infrastructure. Confidence: medium. FP: high on developer and engineering estates. Requires: NetworkConnectIP4.
  7. H7 — GitHub as a dead drop. The GitHub API was resolved and contacted by a process that has no development role, at a beacon-like cadence, with an application user agent that does not match the process. Confidence: medium. FP: high without a process allowlist. Requires: DnsRequest plus proxy logs.
  8. H8 — Logon-triggered persistence into a user path. A scheduled task or WMI subscription was registered to run a payload stored under a user profile or temp directory at logon. Confidence: high. FP: medium. Requires: ScheduledTaskRegistered, WMI-Activity operational log.
04

Consolidated IOC Table

Read the Action column before importing anything. Three of the published file hashes belong to legitimate signed binaries that the actor abused as side-load hosts. They are listed for context and retrospective search only. Setting them to prevent will break Python and OneDrive on clean endpoints.

TypeValueConfActionContextExpiry
sha25655ed788ca7130089c4262cda8f0cb936eab9244bea68eeebe863842ba368e270highdetectInitial phishing archive (avvoalert.zip)2027-02-01
sha256cb6b6289698f53111bb026ad5e95f841a03cf690bda670bb551e416e8cda77d3highdetectStaged payload archive imitating a Python embeddable distribution2027-02-01
sha256b2123d476646459234ab3083b79d13690d3864f9f5a9aa2b1272dfd502d0d3e2highdetectHollowFrame Go side-load DLL (python311.dll)2027-02-01
sha256d3bf01fce1f97f86aa58e9220e6dc1dae90005e5d7552f06192393d370355ed9highdetectHollowFrame Go loader, recovered from the encrypted region2027-02-01
sha256f882d0a0bf6f7fc687b9be6c7991d0bce4b60e81b742f5919933d07de37d625chighdetectNative dropper (loader_panda.exe) staging the second side-load2027-02-01
sha256f59f32c9af4fa8a5dbd4668df8893593bc0c4324816cbf9b956acedcbfb8cdb6highdetectMatryoshka HTTP backdoor (version.dll)2027-02-01
sha256f96ff2f3abbff7f382ace509b90e54853b4b61c402ecde27d82f1c17b414867bhighdetectMatryoshka GitHub backdoor (wtsapi32.dll)2027-02-01
sha25614a89eda72e385f76bf15a7c4fd539c48837cf5df444a16f28c5b94f29799550mediumpivotLegitimate Python interpreter used as the side-load host. Retrospective search only — do not block.2026-11-01
sha256d66c3b47091ceb3f8d3cc165a43d285ae919211a0c0fcb74491ee574d8d464f8mediumpivotLegitimate Visual C++ runtime bundled with the staged archive. Do not block.2026-11-01
sha256015d7b212d20681d346e690159e7f4cd9e88b51de27e84b514fce865deef3a5cmediumpivotLegitimate OneDrive updater used as the second side-load host. Do not block.2026-11-01
sha256REPLACE_WITH_LNK_SHA256n/aenrichThe malicious shortcut. The primary report records the hash as not recovered; no value is invented here.
ipv42.26.252.84highdetectPowerShell payload delivery server, reached over plaintext HTTP2026-11-01
ipv4 : port45.158.196.184 : 8888highdetectMatryoshka HTTP C22026-11-01
domainavvoalert[.]infohighdetectAttacker-controlled phishing redirector2026-11-01
url hostmega[.]nzlowpivotHosted the encrypted archive. A legitimate global file-sharing service — never block wholesale; use the specific file link for retrospective mail and proxy search only.2026-09-01
domainapi.github[.]comlowenrichMatryoshka GitHub dead-drop channel. Legitimate on developer estates — alert on the process and host context, not the domain.
uri pattern/repos/adioziaete/memio/contents/highdetectPer-victim mailbox path on the private dead-drop repository2026-11-01
user-agentOneDrive/24.170.0825.0001mediumhuntSpoofed agent used by the GitHub variant. Legitimate OneDrive never talks to the GitHub API — the pair is the signal.2026-11-01
filenameloader_panda.exemediumhuntNative dropper file name2026-11-01
filepath%LOCALAPPDATA%\Programs\Python\Python311-BriefhighhuntStaging directory created and Defender-excluded before payload delivery2026-11-01
stringlooks like a sandbox, exitingmediumhuntHollowFrame anti-analysis failure message — useful for retro-hunting recovered samples2026-11-01
stringpongv2mediumenrichMatryoshka GitHub health-check response value2026-11-01
05

Affected Surface & Telemetry Matrix

SurfaceRequired telemetryPriorityGap risk
Windows endpoints (all user workstations, especially those handling external document flow)ProcessRollup2 / SyntheticProcessRollup2 with command linesCriticalLow — this is baseline Falcon Insight telemetry.
Microsoft Defender configuration stateRegGenericValueUpdate, Defender operational log event 5007CriticalMedium — the Defender operational log is not forwarded by default in many estates.
File writes into user-writable pathsPeFileWritten, NewExecutableWritten, ZipFileWrittenHighLow.
Outbound network from endpointsNetworkConnectIP4, DnsRequestHighMedium — DNS visibility is lost where endpoints use DNS-over-HTTPS to a third-party resolver.
Web proxy / egressFull URI, user agent, and initiating host for outbound HTTP and HTTPSHighHigh — without URI-level logging the dead-drop repository path is invisible, and the domain alone is unusable as a signal.
Scheduled task and WMI persistenceScheduledTaskRegistered, ScheduledTaskModified, AsepValueUpdate, WMI-Activity operational log 5857/5861HighMedium — WMI subscription creation via API leaves no process-execution trace, so the operational log is the only source.
PowerShell execution contentScript Block Logging (4104), module logging, transcriptionHighHigh — commonly unconfigured; without it the XOR downloader stage is opaque.
Mail gatewayURL rewriting and click telemetry, attachment and archive inspection verdictsMediumMedium — encrypted archives are frequently passed through uninspected by policy.
Active DirectoryUserLogon, domain controller and privileged-group enumeration telemetryMediumMedium — the recon burst is the earliest sign the operator moved past initial access.
In-memory execution (module overloading, manual PE mapping, process ghosting)MediumGAP — no first-class sensor event; rely on the behavioural preconditions and on Falcon's own memory-scanning detections.
06

ATT&CK Mapping

TacticTechniqueObserved behaviorQuery / control
Initial AccessT1566.002 — Phishing: Spearphishing LinkMail to multiple recipients with a link through an attacker-controlled redirector.Section 7 gateway hunt; hardening H3
ExecutionT1204.001 / T1204.002 — User Execution: Malicious Link / Malicious FileUser opens an encrypted archive and double-clicks a shortcut named as case documents.Q1; hardening H3, H9
Defense EvasionT1027 — Obfuscated Files or InformationPassword-protected archive; Base64 blob; repeating-key XOR over a hex payload.Q1; Script Block Logging hunt
Defense EvasionT1140 — Deobfuscate/Decode Files or Informationcertutil.exe -decode reconstructs the next command stage from a temp file.Q1
ExecutionT1059.001 — Command and Scripting Interpreter: PowerShellHidden, policy-bypassed PowerShell running an in-memory decoded stage via Invoke-Expression.Q2; hardening H6
ExecutionT1059.003 — Windows Command ShellOperator commands executed through cmd.exe /c with merged standard output and error.Q12
Privilege EscalationT1548 — Abuse Elevation Control MechanismScript relaunches itself with an elevation verb when not already administrative.Q2; hardening H10
Defense EvasionT1562.001 — Impair Defenses: Disable or Modify ToolsDefender path and process-name exclusions added before payload delivery.Q3, Q4; hardening H2
Command and ControlT1105 — Ingress Tool TransferStaged archive and follow-on payloads pulled from a bare-IP HTTP server and from the dead-drop repository.Q5, Q8
Defense EvasionT1574.002 — Hijack Execution Flow: DLL Side-LoadingTwo chained side-loads: a Python host with a rogue runtime DLL, then an application updater with a rogue version DLL. A third rogue DLL proxies 41 Terminal Services exports.Q6, Q7; hardening H5
Defense EvasionT1036.005 — Masquerading: Match Legitimate Name or LocationMalicious DLLs carry the exact names of expected system and runtime dependencies; the staged archive imitates an official Python distribution.Q5, Q7
Defense EvasionT1497.001 / T1497.003 — Virtualization/Sandbox Evasion: System Checks / Time Based EvasionGates on system uptime, installed physical memory and user-profile file count.GAP — no endpoint telemetry
Defense EvasionT1497.002 — User Activity Based ChecksCursor-movement gate before payload execution.GAP — no endpoint telemetry
PersistenceT1053.005 — Scheduled Task/Job: Scheduled TaskOn-logon task with highest privileges and a 30-second delay.Q11; hardening H8
PersistenceT1546.003 — Event Triggered Execution: WMI Event SubscriptionPermanent subscription triggered by new logon-session instances; prior filters, consumers and bindings of the same name are removed first.Section 7 WMI hunt; hardening H8
PersistenceT1547.001 — Boot or Logon Autostart: Registry Run Keys / Startup FolderStartup-folder deployment offered as a lower-complexity fallback.Section 7 autorun hunt
Defense EvasionT1055 — Process Injection (process ghosting, module stomping, process-parameter poisoning)Loader offers several execution modes, so the same framework produces different telemetry on different hosts.Partial — Falcon behavioural detections
Defense EvasionT1620 — Reflective Code LoadingManual PE mapping, shellcode execution, and an allocate-write-protect-execute fallback for raw payloads.Partial
Command and ControlT1071.001 — Application Layer Protocol: Web ProtocolsPlaintext HTTP JSON tasking to a hard-coded endpoint on a non-standard port.Q8, Q9
Command and ControlT1102.002 — Web Service: Bidirectional CommunicationPrivate code-hosting repository used as a per-host mailbox for beacons, tasks and results.Q10; hardening H7
Command and ControlT1132.001 — Data Encoding: Standard EncodingInline Base64 content returned by the repository contents API.Section 7 proxy hunt
DiscoveryT1016, T1018, T1069.002, T1082, T1518, T1033Network configuration, domain controllers, domain computers, privileged group membership, installed software, local token and privilege detail.Post-compromise pivots in section 14
ExfiltrationT1567 — Exfiltration Over Web ServiceResult objects and uploaded files written back to the dead-drop repository.Q10; section 7 proxy hunt
07

Native Audit-Log Hunts

Run these where Falcon is absent, where the sensor was installed after the intrusion window, or to recover the stages that produce no sensor event. Each stands alone and needs no CQL.

Microsoft Defender operational log

  • Event ID 5007 — configuration change. Filter for values under the exclusions key. This is the single most durable artifact in the chain: the exclusions were added before the payloads landed and survive removal of the malware.
  • Event ID 5001 / 5010 / 5012 — real-time, antispyware or antivirus scanning disabled.
  • Enumerate current exclusions across the fleet and compare against an approved baseline. Any path under a user profile, and any process-name exclusion for an interpreter, is a finding regardless of this campaign.

PowerShell logging

  • 4104 (Script Block Logging) — search for blocks containing a long unbroken hexadecimal literal together with Invoke-Expression, or containing -Verb RunAs together with -WindowStyle Hidden.
  • 4104 — search for Add-MpPreference or Set-MpPreference with any exclusion parameter.
  • 4103 (module logging) and transcription — recover the decoded stage body where script block logging was truncated.

Task Scheduler operational log

  • 106 (task registered), 140 (task updated), 141 (task deleted). Export every logon-triggered task and review those whose action points into a user profile, temp or programdata path, or that run with highest privileges under a standard user account.
  • Compare C:\Windows\System32\Tasks against a known-good baseline. Pay attention to update-themed task names, which is the naming style the reporting calls out.

WMI-Activity operational log

  • 5857 (provider started), 5860 and 5861 (permanent event consumer registration). A subscription created through the WMI API produces no process-execution telemetry, so 5861 is the only reliable source.
  • Enumerate __EventFilter, CommandLineEventConsumer, ActiveScriptEventConsumer and __FilterToConsumerBinding instances under the subscription namespace on every host, not just suspected ones. Look for filters keyed on logon-session object creation.

Sysmon (where deployed)

  • Event 7 (Image Loaded) — the cleanest possible detection for this chain: a signed executable loading an unsigned or mismatched DLL from its own directory outside Program Files. Filter on the three side-load DLL names.
  • Event 11 (File Create) — archives and PE files written into download and temp paths.
  • Events 19, 20, 21 — WMI filter, consumer and binding activity.
  • Event 1 — carries Signature and SignatureStatus, which the Falcon event stream does not expose as a queryable signer field.

Web proxy / secure web gateway

  • Search full request URIs for the per-victim mailbox path on the dead-drop repository, and for requests to the code-hosting contents API whose response bodies are JSON task objects.
  • Search for the spoofed OneDrive user agent paired with a code-hosting destination. The genuine OneDrive client never contacts the code-hosting API, so that pairing alone is a finding.
  • Search for plaintext HTTP requests to bare IPv4 literals originating from endpoints — the delivery stage used no hostname at all.
  • Search for downloads of password-protected archives from consumer file-sharing services, then correlate against mail-gateway click telemetry for the same user in the same minute.

Mail gateway

  • Retro-hunt for the redirector host across all recipients, not just the ones who clicked, and for any message delivering a link to a consumer file-sharing service with an archive password in the message body.
  • Review policy: encrypted and password-protected archives that bypass content inspection should be quarantined or detonated, not delivered.
08

CrowdStrike LogScale CQL Hunt Queries

Pick your tenant's cloud first — every "Open in Falcon" button below uses this selection.

No query below carries an in-query time filter. Set the window with the console time picker. Each query records its intended lookback as a // LOOKBACK: comment. Start at 30 days for the persistence and Defender queries, 7 days for the network ones.

Q1 · Certutil decoding a staged blob inside a user-writable path
CONF HIGHFP MEDCOST LOW

Looks for: the third link in the chain — the shortcut wrote a Base64 blob and a companion script into a temp path, then used a signed Microsoft utility to reconstruct the next stage. FP: certificate administrators and some software installers legitimately use certutil -decode; the discriminator is the user-writable path plus an interactive ancestor such as explorer.exe.

// HUNT: certutil decoding a staged blob inside a user-writable path
// MITRE: T1140, T1204.002, T1059.003
// CONF: high | FP: medium | COST: low
// REQUIRES: ProcessRollup2 with command lines (Falcon Insight)
// FALSE POSITIVES: certificate tooling, log-packing scripts, some vendor installers
// TUNING: exclude ParentBaseFileName values belonging to your patch and software-deployment agents, and exclude decodes whose target sits under a managed application directory
// LOOKBACK: 30d - set the window with the console time picker
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^certutil\.exe$/i
| CommandLine=/-decode/i
| CommandLine=/\\(Temp|AppData|Downloads|Users\\Public)\\/i
| table([@timestamp, ComputerName, UserName, GrandparentBaseFileName, ParentBaseFileName, FileName, CommandLine, SHA256HashData])
Q2 · PowerShell relaunching itself elevated, hidden and policy-bypassed
CONF HIGHFP LOWCOST LOW

Looks for: the self-elevation step. The decoded stage checked for administrative rights and, when it did not have them, wrote a temp script and relaunched PowerShell with an elevation verb, no profile, a policy bypass and a hidden window. That combination is close to unheard of in benign automation, which normally runs elevated already or does not need to hide.

// HUNT: PowerShell relaunching itself elevated, hidden and policy-bypassed
// MITRE: T1059.001, T1548
// CONF: high | FP: low | COST: low
// REQUIRES: ProcessRollup2 with command lines
// FALSE POSITIVES: a small number of self-elevating vendor install wrappers
// TUNING: if a packaging tool trips this, exclude on the parent binary rather than on the flag combination - the flags are the signal
// LOOKBACK: 30d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^(powershell|powershell_ise|pwsh)\.exe$/i
| CommandLine=/-Verb\s+RunAs/i
| CommandLine=/-w(indowstyle)?\s+hidden/i
| table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine, SHA256HashData])
Q3 · Defender exclusion added for a path or a process name
CONF HIGHFP MEDCOST LOW

Looks for: the pivotal step. The actor excluded the staging directory and the process name python.exe before any executable arrived, which meant nothing that followed was scanned. FP: IT teams and line-of-business software genuinely add exclusions; triage on who ran it and what was excluded. A process-name exclusion for an interpreter, or a path exclusion under a user profile, is a finding on its own merits even outside this campaign.

// HUNT: Defender exclusion added for a path or a process name
// MITRE: T1562.001
// CONF: high | FP: medium | COST: low
// REQUIRES: ProcessRollup2 with command lines
// FALSE POSITIVES: IT-run exclusion scripts, endpoint-management tooling, some application installers
// TUNING: exclude your management agent as ParentBaseFileName and your build or imaging service account as UserName; never exclude on the exclusion value itself, and always triage any exclusion naming an interpreter or a user-profile path
// LOOKBACK: 30d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| CommandLine=/(Add|Set)\-MpPreference/i
| CommandLine=/Exclusion(Path|Process|Extension|IpAddress)/i
| table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine])
Q4 · Defender exclusion key written in the registry
CONF HIGHFP MEDCOST LOW

Looks for: the same tampering seen from the registry rather than the command line. This catches exclusions written directly, by a compiled binary, or by any path that never touches a PowerShell cmdlet — which Q3 would miss entirely. FP: legitimate management tooling writes here too; the discriminator is the writing process and the value content.

// HUNT: Defender exclusion key written in the registry
// MITRE: T1562.001, T1112
// CONF: high | FP: medium | COST: low
// REQUIRES: RegGenericValueUpdate / RegSystemConfigValueUpdate
// FALSE POSITIVES: endpoint-management and antivirus-migration tooling writing approved exclusions
// TUNING: exclude writes whose RegStringValue resolves under Program Files or your managed application root, then review everything that remains by hand - the population should be small enough to read
// LOOKBACK: 30d
#event_simpleName=/^(RegGenericValueUpdate|RegSystemConfigValueUpdate)$/
| RegObjectName=/\\Windows Defender\\Exclusions\\/i
| table([@timestamp, ComputerName, UserName, RegObjectName, RegValueName, RegStringValue])
Q5 · Archive imitating a Python embeddable distribution written to a user path
CONF MEDFP LOWCOST LOW

Looks for: the delivery archive. It was named to pass a glance as an official Python embeddable package but carried an architecture suffix that does not exist in any real Python release. This query deliberately matches the whole -embed- naming family rather than only the one observed suffix, so a re-spun archive still lands.

// HUNT: archive imitating a Python embeddable distribution written to a user path
// MITRE: T1105, T1036.005
// CONF: medium | FP: low | COST: low
// REQUIRES: ZipFileWritten
// FALSE POSITIVES: a developer legitimately downloading an embeddable Python package
// TUNING: real Python embeddable archives end in -embed-amd64, -embed-win32 or -embed-arm64; anything else is worth reading, and any of them landing on a non-developer endpoint is worth reading too
// LOOKBACK: 30d
#event_simpleName=/^ZipFileWritten$/
| TargetFileName=/python\-3[\d.]*\-embed/i
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, TargetFileName, SHA256HashData])
Q6 · Python host executed with nothing to interpret
CONF HIGHFP LOWCOST LOW

Looks for: the clearest single signal in the chain. The actor launched python.exe with no script path, no -m module and no interactive console, purely so that Windows would resolve and load the adjacent rogue runtime DLL. A Python interpreter with nothing to interpret is not running Python — it is a side-load host. The path filter keeps this tight to user-writable locations.

// HUNT: Python host executed with nothing to interpret (side-load tell)
// MITRE: T1574.002, T1036.005
// CONF: high | FP: low | COST: low
// REQUIRES: ProcessRollup2 with command lines
// FALSE POSITIVES: a user opening a bare Python REPL from a portable install under their profile
// TUNING: on developer estates, exclude ImageFileName paths under your sanctioned toolchain roots rather than dropping the path filter; keep the no-argument condition, which is what separates a side-load from a REPL that was actually typed into
// LOOKBACK: 30d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^pythonw?3?\d*\.exe$/i
| ImageFileName=/\\(AppData|Temp|ProgramData|Downloads|Users\\Public)\\/i
| CommandLine!=/\.(py|pyw|pyz)\b/i
| CommandLine!=/\s\-(m|c|i|E|X)\b/i
| table([@timestamp, ComputerName, UserName, ParentBaseFileName, ImageFileName, CommandLine, SHA256HashData])
Q7 · Side-load DLL names written outside the system directories
CONF HIGHFP MEDCOST MED

Looks for: all three side-load DLLs at the moment they hit disk. Two of these names belong to Windows system libraries that should never be written outside the system directories, and the third belongs to a Python runtime that should only ever be written by a Python installer. FP: genuine Python installs, and applications that ship their own copy of a version library, both write these names legitimately — hence the system-path and installer exclusions in the tuning line.

// HUNT: side-load DLL names written outside the system directories
// MITRE: T1574.002, T1036.005
// CONF: high | FP: medium | COST: medium
// REQUIRES: PeFileWritten / NewExecutableWritten
// FALSE POSITIVES: Python installers, application setup routines that bundle their own version library
// TUNING: exclude ContextBaseFileName values of msiexec.exe, TrustedInstaller.exe and your software-deployment agent, and exclude writes landing under Program Files; what should remain is DLLs written into user-writable paths by something that is not an installer
// LOOKBACK: 30d
#event_simpleName=/^(PeFileWritten|NewExecutableWritten)$/
| TargetFileName=/\\(python3\d\d|version|wtsapi32|vcruntime\d+)\.dll$/i
| TargetFileName!=/^[A-Za-z]:\\Windows\\/i
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, TargetFileName, SHA256HashData])
Q8 · Known HollowFrame and Matryoshka network infrastructure
CONF HIGHFP LOWCOST LOW

Looks for: direct contact with the two published endpoints — the plaintext HTTP payload-delivery server and the Matryoshka HTTP C2 on its non-standard port. Run this first as a fast yes-or-no answer for the reporting window, then move to the behavioural queries, because this infrastructure has a short useful life and its absence proves nothing.

// HUNT: known HollowFrame and Matryoshka network infrastructure
// MITRE: T1071.001, T1105
// CONF: high | FP: low | COST: low
// REQUIRES: NetworkConnectIP4
// FALSE POSITIVES: none expected - these are single-campaign endpoints
// TUNING: none needed; a hit here is an incident, not a tuning exercise
// LOOKBACK: 90d - go as far back as retention allows, the report window opens well before disclosure
#event_simpleName=/^NetworkConnectIP4$/
| in(RemoteAddressIP4, values=["2.26.252.84", "45.158.196.184"])
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, RemoteAddressIP4, RemotePort_decimal, Protocol_decimal])
Q9 · Trusted side-load hosts opening outbound connections
CONF MEDFP HIGHCOST MED

Looks for: the durable version of Q8. Once the implant is running inside a Python host or an application updater, its network activity is attributed to that trusted process. This groups by process and destination so a small number of repeated destinations stands out from ordinary traffic. FP: high — Python legitimately reaches the internet constantly on developer and data-science endpoints, and updaters legitimately reach their own vendor. Read it as a ranked list, not as an alert.

// HUNT: trusted side-load hosts opening outbound connections
// MITRE: T1071.001, T1574.002
// CONF: medium | FP: high | COST: medium
// REQUIRES: NetworkConnectIP4
// FALSE POSITIVES: package installs and API calls from developer Python, and genuine updater traffic to vendor infrastructure
// TUNING: run this scoped to non-developer host groups first; then exclude vendor destination ranges for the updater and your internal package mirror for Python, and read what is left - a single stable destination on a non-standard port from an updater process is the shape you want
// LOOKBACK: 7d
#event_simpleName=/^NetworkConnectIP4$/
| ContextBaseFileName=/^(python|pythonw|updater|loader_panda)\.exe$/i
| groupBy([aid, ComputerName, ContextBaseFileName, RemoteAddressIP4, RemotePort_decimal], function=count(as=Connections))
| sort(Connections, order=desc, limit=200)
Q10 · Code-hosting API resolved by non-browser, non-developer processes
CONF MEDFP HIGHCOST MED

Looks for: the dead-drop channel. Matryoshka GitHub polls a private repository through the contents API, so the endpoint resolution is the only piece visible on the sensor. FP: high by construction — this destination is entirely normal on engineering estates, and the query is only meaningful once you have scoped it. Treat the process list as the finding, not the domain: an updater, an interpreter with no script, or an unsigned binary resolving a code-hosting API is worth a look; a code editor doing it is not.

// HUNT: code-hosting API resolved by non-browser, non-developer processes
// MITRE: T1102.002, T1567
// CONF: medium | FP: high | COST: medium
// REQUIRES: DnsRequest
// FALSE POSITIVES: every developer tool, package manager, CI agent and IDE extension host on the estate
// TUNING: this query is unusable estate-wide - scope it to host groups with no development role first, then build the ContextBaseFileName exclusion list from what your own baseline shows, and finally pivot every survivor to proxy logs for the request URI, because the repository path and the user agent are what actually confirm it
// LOOKBACK: 7d
#event_simpleName=/^DnsRequest$/
| DomainName=/^api\.github\.com$/i
| ContextBaseFileName!=/^(chrome|msedge|firefox|brave|iexplore|code|devenv|git|git-remote-https|gh|node|npm|yarn|dotnet|java|curl|wget|OneDrive)\.exe$/i
| groupBy([aid, ComputerName, ContextBaseFileName], function=count(as=Lookups))
| sort(Lookups, order=desc, limit=200)
Q11 · Logon-triggered scheduled task pointing at a user-profile payload
CONF HIGHFP MEDCOST LOW

Looks for: the primary persistence mechanism — an on-logon task running with highest privileges after a short delay, whose action points into a user-writable directory. The reporting notes the operator favoured update-themed task names, so read the task name column rather than filtering on it. FP: some user-scoped software genuinely registers logon tasks under a profile path; the count should be small enough to review by hand.

// HUNT: logon-triggered scheduled task pointing at a user-profile payload
// MITRE: T1053.005
// CONF: high | FP: medium | COST: low
// REQUIRES: ScheduledTaskRegistered / ScheduledTaskModified
// FALSE POSITIVES: user-scoped auto-update helpers and sync clients that install under a profile
// TUNING: exclude the specific TaskName values your known user-scoped applications register, one by one, and keep a standing review of anything new; do not exclude the whole user-profile path, which is the entire point of the query
// LOOKBACK: 30d
#event_simpleName=/^(ScheduledTaskRegistered|ScheduledTaskModified)$/
| TaskExecutable=/\\(Users|AppData|ProgramData|Temp|Downloads)\\/i
| table([@timestamp, ComputerName, UserName, TaskName, TaskAuthor, TaskExecutable])
Q12 · Command shell spawned by a side-load host with merged-output capture
CONF HIGHFP LOWCOST LOW

Looks for: the operator actually typing. Both backdoor variants execute tasking through a command shell and capture merged standard output and error so the result can be returned over the C2 channel; the code-page switch appears on the GitHub variant. A Python host or an application updater is never a legitimate parent for a command shell, which is what makes this card high-confidence despite the generic child process.

// HUNT: command shell spawned by a side-load host with merged-output capture
// MITRE: T1059.003, T1071.001
// CONF: high | FP: low | COST: low
// REQUIRES: ProcessRollup2 with command lines
// FALSE POSITIVES: build scripts that shell out from a Python parent on developer endpoints
// TUNING: on developer estates exclude Python parents whose ImageFileName sits under a sanctioned toolchain root, and keep updater parents unexcluded - an application updater spawning a shell has no benign explanation
// LOOKBACK: 30d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^(cmd|powershell|pwsh)\.exe$/i
| ParentBaseFileName=/^(python|pythonw|updater|loader_panda)\.exe$/i
| table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine, SHA256HashData])

Correlation beats any single card. Run Q3 or Q4 first, take the host and the timestamp, then re-run Q5, Q6, Q7 and Q11 scoped to that host across the following two hours. The chain compresses into minutes on a live intrusion, so an exclusion followed inside the same hour by a PE write into the excluded path and a no-argument interpreter launch is a confirmed sequence, not a coincidence.

09

CrowdStrike Custom IOA Recommendations

Four of the twelve queries are strong enough to promote to Custom IOAs. The rest stay as scheduled hunts because their false-positive profile depends on estate composition and cannot be tuned generically.

IOA nameType / patternExclusionsSeverityAction
IOA — Defender exclusion added by a non-management processProcess Creation. Image: .*\\powershell(_ise)?\.exe or .*\\pwsh\.exe. Command line: .*(Add|Set)-MpPreference.*Exclusion(Path|Process).*Exclude the image path of your endpoint-management agent and the grandparent process of your imaging pipeline.HighDetect first for two weeks, then Prevent once the benign population is empty.
IOA — Interpreter launched with no script argument from a user pathProcess Creation. Image: .*\\AppData\\.*\\python\d*\.exe (repeat for the temp and programdata roots). Command line: negative match on \.py and on the module and interactive switches.Exclude sanctioned portable-toolchain roots on developer host groups only. Do not apply the exclusion estate-wide.CriticalPrevent on non-developer host groups; Detect on developer groups.
IOA — Command shell spawned by an application updaterProcess Creation. Parent image: .*\\updater\.exe. Image: .*\\(cmd|powershell|pwsh)\.exeNone. An application updater spawning an interactive shell has no benign explanation in a managed estate.CriticalPrevent.
IOA — Certutil decoding content in a user-writable pathProcess Creation. Image: .*\\certutil\.exe. Command line: .*-decode.*\\(Temp|AppData|Downloads)\\.*Exclude your patch-management and certificate-enrolment agents as parent image.HighDetect, then Prevent after baseline.

Stay as scheduled hunts

  • Q9 and Q10 — false-positive rate is a function of how many developers you have. Promoting either to an IOA before scoping produces an unusable alert stream and trains analysts to close the whole rule.
  • Q7 — legitimate installers write these DLL names often enough that a prevent action risks blocking a Python or application install. Run weekly, review by hand.
  • Q8 — atomic infrastructure belongs in Falcon IOC Management, not in an IOA. Import the CSV in section 10 instead.
  • Q11 — task persistence is better served by a scheduled search with a review queue, because the finding is usually "which task is this" rather than "block it now".

Deployment path

  1. Create a Custom IOA Rule Group scoped to a pilot host group of 20 to 50 endpoints spanning your real mix of roles.
  2. Add each rule in Detect mode with the exclusions above. Leave it for a full business cycle, including a patch window and a month-end.
  3. Review every detection. Convert anything benign into a named exclusion; do not broaden the pattern.
  4. Promote to Prevent only for the rules whose benign population reached zero, and only on the host groups where that was true.
  5. Record the pilot outcome in the changelog and bump this pack to v1.0.
10

Machine-Readable IOC Appendix

The import block below contains malicious artifacts only. The three legitimate host binaries the actor abused are in a separate context-only block and are deliberately not importable. Importing them as blocks would break Python and the OneDrive updater across the estate.

Falcon IOC Management CSVbulk import
type,value,action,severity,expiration,description,tags
sha256,55ed788ca7130089c4262cda8f0cb936eab9244bea68eeebe863842ba368e270,prevent,critical,2027-02-01,HollowFrame initial phishing archive,campaign:HollowFrame
sha256,cb6b6289698f53111bb026ad5e95f841a03cf690bda670bb551e416e8cda77d3,prevent,critical,2027-02-01,HollowFrame staged payload archive,campaign:HollowFrame
sha256,b2123d476646459234ab3083b79d13690d3864f9f5a9aa2b1272dfd502d0d3e2,prevent,critical,2027-02-01,HollowFrame Go side-load DLL,campaign:HollowFrame
sha256,d3bf01fce1f97f86aa58e9220e6dc1dae90005e5d7552f06192393d370355ed9,prevent,critical,2027-02-01,HollowFrame Go loader payload,campaign:HollowFrame
sha256,f882d0a0bf6f7fc687b9be6c7991d0bce4b60e81b742f5919933d07de37d625c,prevent,critical,2027-02-01,HollowFrame native dropper,campaign:HollowFrame
sha256,f59f32c9af4fa8a5dbd4668df8893593bc0c4324816cbf9b956acedcbfb8cdb6,prevent,critical,2027-02-01,Matryoshka HTTP backdoor DLL,campaign:Matryoshka
sha256,f96ff2f3abbff7f382ace509b90e54853b4b61c402ecde27d82f1c17b414867b,prevent,critical,2027-02-01,Matryoshka GitHub backdoor DLL,campaign:Matryoshka
sha256,REPLACE_WITH_LNK_SHA256,detect,high,2027-02-01,Malicious shortcut - hash not recovered by the reporting vendor,campaign:HollowFrame
ipv4,2.26.252.84,detect,high,2026-11-01,HollowFrame PowerShell payload delivery server,campaign:HollowFrame
ipv4,45.158.196.184,detect,high,2026-11-01,Matryoshka HTTP C2 on port 8888,campaign:Matryoshka
domain,avvoalert.info,detect,high,2026-11-01,Attacker-controlled phishing redirector,campaign:HollowFrame
Trusted host binaries — DO NOT BLOCKretro-search only
# These three hashes are LEGITIMATE SIGNED BINARIES abused as side-load hosts.
# Use them for retrospective search and for scoping. Never set them to prevent.
# python.exe        14a89eda72e385f76bf15a7c4fd539c48837cf5df444a16f28c5b94f29799550
# vcruntime140.dll  d66c3b47091ceb3f8d3cc165a43d285ae919211a0c0fcb74491ee574d8d464f8
# updater.exe       015d7b212d20681d346e690159e7f4cd9e88b51de27e84b514fce865deef3a5c
#
# Pivot instead on WHERE they ran from and WHAT loaded beside them:
#   - any of these executing from a user-writable path
#   - a same-directory DLL whose name matches a system or runtime library
#   - the interpreter running with no script, module or interactive argument
Behavioral signaturesdurable — survives infrastructure churn
B1  Defender exclusion added for a user-writable DIRECTORY and for a PROCESS NAME,
    minutes apart, by the same process, before any executable is written there.
B2  Interpreter host executed with no script path, no module switch and no
    interactive flag, from a user-writable directory.
B3  A DLL bearing the name of a system or runtime library written into the same
    directory as a signed executable, outside Program Files and outside Windows.
B4  Signed utility used to decode content in a user temp path, with an interactive
    shell or the desktop shell in the ancestry.
B5  PowerShell relaunching itself with an elevation verb plus a hidden window plus
    an execution-policy bypass.
B6  Archive named to imitate an official runtime distribution but carrying an
    architecture suffix that no real release uses.
B7  On-logon scheduled task, highest privileges, short start delay, action path
    inside a user profile or temp directory.
B8  Permanent WMI event subscription whose filter keys on logon-session object
    creation, where prior same-named filters and consumers were deleted first.
B9  Application updater or interpreter process opening a command shell.
B10 Beacon-cadence requests to a code-hosting contents API from a process with no
    development role, with an application user agent that does not match the
    process making the request.
B11 Plaintext HTTP to a bare IPv4 literal with no hostname, from an endpoint,
    fetching an archive.
B12 Repeated GET-then-PUT pairs against the same small set of JSON objects under
    one repository path, one path per host.
Named tooling & artifactsstring hunt
HollowFrame        Go modular loader and persistence framework
Matryoshka HTTP    Rust backdoor, plaintext HTTP JSON tasking
Matryoshka GitHub  Rust backdoor, private repository dead drop
loader_panda.exe   native dropper staging the second side-load
Project220Rebr     Go build directory name - NOT a family or actor name
looks like a sandbox, exiting     anti-analysis failure message
pongv2                            health-check response value
/repos/adioziaete/memio/contents/ per-victim mailbox path
OneDrive/24.170.0825.0001         spoofed user agent
beacon.json / cmd.json / result.json   per-host tasking objects
<computer>_<username>             per-victim directory naming scheme
%LOCALAPPDATA%\Programs\Python\Python311-Brief   staging directory
Defender & ASR auditrun on every endpoint
# Dump every current Defender exclusion and the tamper-protection state.
# Anything under a user profile, or any process-name exclusion for an
# interpreter, is a finding regardless of this campaign.
$p = Get-MpPreference
[PSCustomObject]@{
  Host            = $env:COMPUTERNAME
  ExclusionPath   = ($p.ExclusionPath   -join '; ')
  ExclusionProcess= ($p.ExclusionProcess-join '; ')
  ExclusionExt    = ($p.ExclusionExtension -join '; ')
  TamperProtection= (Get-MpComputerStatus).IsTamperProtected
  RealTimeDisabled= $p.DisableRealtimeMonitoring
  ASRRules        = ($p.AttackSurfaceReductionRules_Ids -join '; ')
  ASRActions      = ($p.AttackSurfaceReductionRules_Actions -join '; ')
}

# Logon-triggered tasks whose action points into a user-writable path.
Get-ScheduledTask | Where-Object {
  $_.Triggers.CimClass.CimClassName -contains 'MSFT_TaskLogonTrigger'
} | ForEach-Object {
  [PSCustomObject]@{
    TaskName = $_.TaskName
    RunLevel = $_.Principal.RunLevel
    Action   = ($_.Actions.Execute -join '; ')
  }
} | Where-Object { $_.Action -match 'AppData|\\Temp\\|ProgramData|\\Users\\' }

# Permanent WMI event subscriptions - the mechanism that leaves no process trace.
Get-WmiObject -Namespace root\subscription -Class __EventFilter
Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer
Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding
11

Detection Validation Gates

Do not treat a query as deployed until it has cleared all four gates. A query that returns nothing because the telemetry is absent looks identical to a query that returns nothing because the estate is clean.

GateWhat to proveHowFail action
1 · Telemetry readyEach required event type is actually arriving from a representative sample of hosts.For each of ProcessRollup2, RegGenericValueUpdate, PeFileWritten, ZipFileWritten, NetworkConnectIP4, DnsRequest, ScheduledTaskRegistered, run a bare event-name query grouped by host and confirm the host count matches your sensor inventory.Investigate sensor policy and event-collection settings before trusting any empty result. Record the shortfall as a coverage gap.
2 · Benign baselineYou know what each query returns on a clean estate, in normal working hours and during a patch window.Run every query over 30 days with no exclusions. Record the hit count and the distinct process, user and host counts. Q9 and Q10 in particular must be baselined before anyone is asked to triage them.If Q3, Q6 or Q12 returns more than a handful of results per week, tune before deploying — those three are meant to be quiet.
3 · Positive testEach query fires on a controlled, benign reproduction of the behavior it targets.On an isolated lab host: add and immediately remove a Defender path exclusion (Q3, Q4); launch a portable interpreter with no arguments from a profile directory (Q6); copy a harmless renamed DLL beside a signed binary in a temp folder (Q7); register and delete a logon task pointing at a profile path (Q11); spawn a shell from a renamed parent (Q12). Confirm each returns the expected row.A query that does not fire on its own reproduction has a field, path or regex problem. Fix it before it is trusted in production.
4 · PromotionThe rule survives a full business cycle without generating noise the SOC learns to ignore.Pilot the four IOA candidates in Detect mode on 20 to 50 mixed-role hosts for at least one month, covering a patch cycle and a month-end.Any rule whose benign population is not empty at the end of the pilot stays a scheduled hunt. Do not promote on a partial baseline.

Order matters for the reproduction test. Run the Q3 exclusion test and the Q7 DLL-drop test on the same lab host within the same hour, then confirm your correlation logic surfaces the pair. That pairing — not either event alone — is what this pack is really detecting.

12

Hardening — Tiered

Every control below is anchored to a MITRE mitigation (the why) and to a platform benchmark or vendor guidance (the what). The chain has ten links; you do not need to break all of them. Breaking the execution link (user-writable execution) or the tamper link (Defender exclusions) ends the intrusion on its own.

Immediate — deploy this week, no compatibility risk

H1 · Import the malicious hashes and network indicators. Load the section 10 CSV into Falcon IOC Management. Do not import the three trusted host binaries. MITRE M1040 Behavior Prevention on Endpoint. Verify: confirm the indicator count in IOC Management matches the CSV row count minus the placeholder row.

H2 · Enable Defender Tamper Protection everywhere and alert on every exclusion change. Tamper Protection blocks exclusion changes made outside the management channel, which is exactly the step this actor performed first. Pair it with a standing alert on Defender operational event 5007 and on writes to the exclusions registry key. MITRE M1024 Restrict Registry Permissions, M1018 User Account Management. CIS Microsoft Windows Benchmark, Microsoft Security Baseline for Windows. Verify: (Get-MpComputerStatus).IsTamperProtected returns True on a sample of hosts, and a test exclusion added locally is rejected.

H3 · Quarantine or detonate password-protected archives at the mail gateway, and strip shortcut files from archives. An encrypted archive that content inspection cannot open should not be delivered on the assumption that it is benign. A shortcut inside a delivered archive has no legitimate business use in almost every estate. MITRE M1021 Restrict Web-Based Content, M1049 Antivirus/Antimalware. Verify: send yourself a password-protected archive containing a harmless shortcut and confirm it is held.

H4 · Turn on the relevant ASR rules in Block mode. Block executable content from email client and webmail; block execution of potentially obfuscated scripts; block process creations originating from PSExec and WMI commands; block credential stealing from the LSASS subsystem. These four cover the delivery, the obfuscated PowerShell stage, the WMI persistence path and the most likely follow-on tooling. MITRE M1038 Execution Prevention, M1042 Disable or Remove Feature or Program. Verify: read back AttackSurfaceReductionRules_Actions from Get-MpPreference and confirm each is 1 (block).

Near term — 1 to 4 weeks, pilot on a ring first

H5 · Block execution from user-writable paths with WDAC or AppLocker. This single control ends the chain at step 8: the staged interpreter, the loader, the dropper and both backdoors all execute from a user profile directory. Deploy in audit mode first, harvest the legitimate population, then enforce. MITRE M1038 Execution Prevention. CIS Microsoft Windows Benchmark; Microsoft WDAC deployment guidance. Verify: attempt to run a benign executable copied to %LOCALAPPDATA% and confirm it is blocked, with the block logged.

H6 · Constrain and instrument PowerShell. Enable Script Block Logging, module logging and transcription estate-wide; remove PowerShell 2.0; enforce Constrained Language Mode for standard users through WDAC. The XOR downloader stage is invisible without script block logging and largely non-functional under constrained language. MITRE M1042, M1047 Audit. Microsoft Security Baseline. Verify: run a benign script and confirm 4104 events land in your log pipeline; confirm $ExecutionContext.SessionState.LanguageMode returns ConstrainedLanguage for a standard user.

H7 · Constrain code-hosting API access from non-development endpoints. Use the proxy, application control, or identity-aware policy to limit which hosts and which processes may reach the code-hosting API, rather than blocking the service outright. This is the reporting vendor's own recommendation and it is the only practical answer to a dead drop hosted on infrastructure your developers legitimately need. Require full-URI proxy logging on the paths you do allow. MITRE M1037 Filter Network Traffic, M1057 Data Loss Prevention. Verify: from a non-developer host, confirm the API is unreachable; from a developer host, confirm the request URI appears in proxy logs.

H8 · Baseline and monitor scheduled tasks, WMI subscriptions and autoruns. Collect the full task, subscription and Startup-folder inventory from every endpoint, store it, and diff it weekly. HollowFrame offered all three mechanisms and would pick whichever the environment allowed. MITRE M1047 Audit, M1028 Operating System Configuration. Verify: register a benign logon task and confirm it appears in the next diff.

Strategic — 1 to 3 months, architectural

H9 · Enforce Mark-of-the-Web propagation through archive handling. Configure your standard archive tool to propagate the zone identifier to extracted files, and restrict third-party archivers that strip it. Without propagation, a shortcut extracted from a downloaded archive carries no web mark and receives no warning. MITRE M1021 Restrict Web-Based Content, M1038. Flagged: vendor configuration guidance rather than a formal benchmark control. Verify: extract a file from a downloaded archive and confirm the zone identifier stream is present.

H10 · Remove standing local administrator rights. The chain explicitly tested for elevation and relaunched to request it. Without a route to administrator, the actor loses the machine-wide exclusion, the highest-privileges task and the WMI subscription. MITRE M1026 Privileged Account Management, M1018. CIS Microsoft Windows Benchmark. Verify: confirm the local Administrators group on a sample of endpoints contains only the approved management principals.

H11 · Force endpoint egress through an inspecting proxy and deny direct outbound HTTP. Both the delivery stage and the HTTP backdoor used plaintext HTTP straight to an IP address with no hostname and no proxy. Denying direct outbound HTTP from endpoints removes both. MITRE M1037 Filter Network Traffic. Verify: from an endpoint, attempt a plain HTTP request to an external IP literal and confirm it fails and is logged.

H12 · Move Falcon to prevention on the behaviours this pack proves out. Once the section 11 pilot completes, promote the qualifying Custom IOAs to Prevent and raise the sensor policy to block the in-memory execution patterns the loader relies on. MITRE M1040 Behavior Prevention on Endpoint. Verify: re-run the section 11 positive tests and confirm the behaviour is now blocked rather than merely detected.

13

Deployable Playbooks

Playbook 1 — Enforce Tamper Protection and audit Defender exclusions (H2)

Prerequisites: Microsoft Defender Antivirus in active mode; Intune or Configuration Manager for the Tamper Protection setting (it cannot be enabled by local registry edit on a managed device); local administrator for the audit step. Reboot required: no. Rollback: set the Tamper Protection policy back to Not Configured in the management console; the exclusion audit is read-only and needs no rollback. Note that rolling back Tamper Protection re-exposes exactly the tamper path this campaign used, so record a reason if you do it.

1. In Intune: Endpoint security > Antivirus > create a Windows Security Experience
   profile, set "TamperProtection (Device)" to "On", assign to all devices.
   (Tamper Protection is enforced by the cloud-managed policy; a local registry
   write is not a supported enablement path and will be reverted.)

2. Confirm enforcement on a sample of hosts:
   (Get-MpComputerStatus).IsTamperProtected     # expect: True

3. Inventory every existing exclusion across the fleet:
   $p = Get-MpPreference
   $p.ExclusionPath
   $p.ExclusionProcess
   $p.ExclusionExtension

4. Flag for removal any exclusion that:
   - resolves under a user profile, %TEMP%, %APPDATA% or %LOCALAPPDATA%
   - names an interpreter process (python.exe, powershell.exe, wscript.exe, ...)
   - has no owner, ticket or documented business justification

5. Remove a flagged exclusion through your management channel, not locally:
   Remove-MpPreference -ExclusionPath 'C:\Path\To\Remove'
   Remove-MpPreference -ExclusionProcess 'python.exe'

6. Forward Defender operational event 5007 to the SIEM and alert on every
   occurrence whose new value falls under the exclusions key.

Playbook 2 — Attack Surface Reduction rules in Block mode (H4)

Prerequisites: Defender Antivirus active with real-time protection on; Windows 10 1709 or later; a pilot ring of 20 to 50 mixed-role endpoints. Reboot required: no. Rollback: re-run the same commands with -AttackSurfaceReductionRules_Actions Disabled for the specific rule ID, or set the rule to AuditMode to keep visibility while removing enforcement. Roll back per rule, never all four at once, so you keep the coverage you have already proven.

1. Put the four rules in AUDIT first and leave them for one business cycle:
   Add-MpPreference -AttackSurfaceReductionRules_Ids `
     BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550, `   # exec content from mail/webmail
     5BEB7EFE-FD9A-4556-801D-275E5FFC04CC, `   # potentially obfuscated scripts
     D1E49AAC-8F56-4280-B9BA-993A6D77406C, `   # process creation from PSExec/WMI
     9E6C4E1F-7D60-472F-BA1A-A39EF669E4B2 `    # credential theft from LSASS
     -AttackSurfaceReductionRules_Actions AuditMode, AuditMode, AuditMode, AuditMode

2. Review Defender event 1122 (audit) for each rule. Build the exclusion list from
   what you actually see, not from what you expect to see.

3. Add only the exclusions the audit justified:
   Add-MpPreference -AttackSurfaceReductionOnlyExclusions 'C:\Approved\Path'

4. Promote to BLOCK, one rule at a time, a week apart:
   Set-MpPreference -AttackSurfaceReductionRules_Ids BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 `
     -AttackSurfaceReductionRules_Actions Enabled

5. Verify the enforced state:
   $p = Get-MpPreference
   $p.AttackSurfaceReductionRules_Ids
   $p.AttackSurfaceReductionRules_Actions       # expect: 1 = Block, 2 = Audit

Playbook 3 — PowerShell Script Block Logging and transcription (H6)

Prerequisites: Group Policy or Intune for the policy path; a log destination sized for the volume — script block logging is verbose; a write-protected file share for transcripts. Reboot required: no; new PowerShell sessions pick the policy up immediately. Rollback: set both policies back to Not Configured in the GPO, or delete the two registry keys below and run gpupdate /force. Transcripts already written are not removed by rollback — retire them under your normal evidence-retention policy.

1. GPO path:
   Computer Configuration > Administrative Templates > Windows Components >
   Windows PowerShell
     - "Turn on PowerShell Script Block Logging"  = Enabled
     - "Turn on PowerShell Transcription"         = Enabled
       Output directory = \\logserver\ps-transcripts$   (append-only to clients)
     - "Turn on Module Logging"                   = Enabled, module names = *

2. Equivalent registry values if you are deploying outside GPO:
   HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging
     EnableScriptBlockLogging (DWORD) = 1
   HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription
     EnableTranscripting (DWORD) = 1
     OutputDirectory (SZ)        = \\logserver\ps-transcripts$

3. Remove the legacy engine, which ignores these policies entirely:
   Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root

4. Verify: run a benign script and confirm event 4104 appears in
   Microsoft-Windows-PowerShell/Operational and reaches the SIEM.

5. Standing hunts to build on top of it:
   - 4104 containing a long unbroken hex literal together with Invoke-Expression
   - 4104 containing -Verb RunAs together with -WindowStyle Hidden
   - 4104 containing Add-MpPreference or Set-MpPreference with any Exclusion parameter

Playbook 4 — AppLocker audit-then-block for user-writable paths (H5)

Prerequisites: Application Identity service set to Automatic and running on targets; a GPO scoped to a pilot ring; an inventory owner who can adjudicate the audit results. Use WDAC instead of AppLocker if you already run it — the intent is identical. Reboot required: no, but the Application Identity service must be restarted or the host recycled for a first-time enablement. Rollback: unlink the GPO and run gpupdate /force; rules stop being enforced immediately. Keep the audit-mode GPO linked after rolling back enforcement so you do not lose visibility while you re-scope.

1. Ensure the enforcement service will run:
   Set-Service -Name AppIDSvc -StartupType Automatic
   Start-Service -Name AppIDSvc

2. Create the GPO at:
   Computer Configuration > Windows Settings > Security Settings >
   Application Control Policies > AppLocker
   Create default rules for Executable and DLL collections, then set BOTH
   collections to "Audit only".

3. Add a deny rule for user-writable execution (Executable + DLL collections):
   Path condition:  %OSDRIVE%\Users\*\AppData\*
   Path condition:  %OSDRIVE%\Users\*\Downloads\*
   Path condition:  %OSDRIVE%\ProgramData\*
   Path condition:  %OSDRIVE%\Windows\Temp\*
   (The DLL collection is the one that matters here - the side-loaded payloads
   are DLLs, and an executable-only policy would have allowed all three.)

4. Leave in audit for one full business cycle. Harvest results:
   Get-AppLockerFileInformation -EventLog -EventType Audited -Statistics

5. Convert every legitimate hit into a publisher rule - signed by vendor - rather
   than a path exception. Path exceptions are what the actor was exploiting.

6. Flip the collections to "Enforce rules", one collection at a time, a week apart.

7. Verify: copy a benign signed executable to %LOCALAPPDATA% and run it. Expect a
   block, and expect event 8004 (exe) or 8007 (dll) in
   Microsoft-Windows-AppLocker/EXE and DLL.

Playbook 5 — Mark-of-the-Web propagation and shortcut handling (H3, H9)

Prerequisites: control of the standard archive tool deployed to endpoints; mail-gateway policy edit rights. Reboot required: no. Rollback: set the archive tool's zone-propagation value back to its prior setting and re-run the deployment; revert the gateway rule to its previous action. Both are single-value changes with no dependent state.

1. Standard archive tool - propagate the zone identifier to extracted files.
   For 7-Zip, deploy the "Propagate Zone.Id stream" option set to "All files"
   (HKCU\Software\7-Zip\Options : WriteZoneIdExtract (DWORD) = 1) via GPP or Intune.

2. Block or restrict archive tools that cannot propagate the zone identifier,
   using the same AppLocker or WDAC policy built in Playbook 4.

3. Mail gateway - hold, do not deliver, any message whose attachment is a
   password-protected archive that content inspection could not open. Route to
   detonation if your platform supports it, otherwise to a review queue.

4. Mail gateway - strip or quarantine .lnk files found inside delivered archives.
   Confirm with the business first; the legitimate rate is close to zero in most
   estates but is not always exactly zero.

5. Verify: send yourself a password-protected archive containing a harmless
   shortcut, confirm it is held, then extract a file from an ordinary downloaded
   archive and confirm the zone identifier stream is present:
   Get-Item .\extracted-file.txt -Stream Zone.Identifier
14

Containment Runbook

PhaseActionsOwnerEvidence to capture
0 · Triage
15 min
Confirm the hit is genuine before isolating. Pull the full process tree around the trigger. Check whether a Defender exclusion exists for the path involved and when it was created. Determine whether the host is one of several — this actor phished multiple recipients.SOC L2Process tree export; Get-MpPreference output; the triggering query and its time window.
1 · Isolate
Immediate
Network-contain the host in Falcon. Do not power it off — both backdoors hold state in memory and the loader decrypts its payload in process. Preserve the running state for collection. Suspend, do not delete, the user's sessions.SOC L2 / IR leadContainment timestamp; sensor state before containment.
2 · Collect
1 hr
Memory image first, then triage collection: %TEMP%, %LOCALAPPDATA%\Programs, the Startup folder, C:\Windows\System32\Tasks, the WMI subscription namespace, Defender and PowerShell operational logs, and the browser download history. Hash every DLL sitting beside a signed executable outside the system directories.IR / forensicsMemory image; triage package; hash list with paths.
3 · Scope
2–4 hrs
Re-run Q3, Q4, Q6, Q7, Q8, Q11 and Q12 estate-wide over the maximum retention window. Query the mail gateway for every recipient of the lure, not just the ones who clicked. Query the proxy for the repository path and the spoofed user agent. Identify every account that logged onto the affected host since the first Defender exclusion.Threat hunterAffected-host list; recipient list; account list with logon times.
4 · Eradicate
4–8 hrs
Remove all three persistence mechanisms, in this order: the scheduled task, the WMI filter, consumer and binding, then the Startup-folder entry. Remove the staged directory and every side-loaded DLL. Remove the Defender exclusions — they outlive the malware and are the most commonly missed artifact. Block the hashes and network indicators. Re-image if any elevated session was observed, rather than cleaning.IR / endpoint opsBefore-and-after persistence inventory; exclusion removal confirmation.
5 · Credentials
Same day
The backdoors executed with the rights of whoever launched the side-load host, and the GitHub variant enumerated domain controllers, domain computers and privileged group membership. Reset the interactive user's password and any credential cached on or entered into the host during the window. Review privileged group membership against a known-good baseline. Rotate any service account whose credential could have been used from that host.Identity / AD teamReset log; group-membership diff.
6 · Recover
1–3 days
Return the host from a known-good image. Confirm Tamper Protection is on, exclusions are clean, ASR rules are enforced, and the AppLocker or WDAC policy applies. Re-run the section 11 positive tests on the rebuilt host before returning it to the user.Endpoint opsRebuild record; post-rebuild verification output.
7 · Watch
30 days
Keep Q3, Q4, Q6, Q11 and Q12 on a daily schedule scoped to the affected business unit. Keep the network indicators on detect. Re-run the estate-wide scope query weekly, because a second dormant foothold on another endpoint is the expected failure mode for a chain with three persistence options.SOCScheduled search definitions; weekly review notes.

The most commonly missed eradication step is the Defender exclusion. It was created before the payload and it survives every payload removal. A host that is cleaned but keeps a path and process-name exclusion is a host that is pre-prepared for the next attempt.

15

Detection Coverage Map

TechniqueBehaviorCQLIOACoverage
T1566.002Spear-phishing link through an attacker-controlled redirectorPartial gateway and proxy hunts only (section 7)
T1204.002 / T1027Encrypted archive holding a masquerading shortcutPartial archive write is visible; the shortcut itself is not distinguishable on the sensor
T1140Signed utility decoding a staged blob in a temp pathQ1YesGood
T1059.001 / T1548Self-elevating hidden PowerShell with a policy bypassQ2Good
T1562.001Defender path and process-name exclusions added pre-payloadQ3, Q4YesGood — two independent angles, process and registry
T1105Staged archive pulled over plaintext HTTP from a bare IPQ5, Q8Good
T1574.002Chained DLL side-loads through a Python host and an application updaterQ6, Q7YesGood on execution and on file write. The load event itself is only visible via Sysmon event 7
T1036.005Malicious DLLs named as expected system and runtime dependenciesQ5, Q7Good
T1497.001 / .002 / .003Sandbox gates on uptime, installed memory, profile file count, cursor movementGAP — entirely in-process; no endpoint telemetry exists for this
T1053.005On-logon task, highest privileges, short delay, user-path actionQ11Good
T1546.003Permanent WMI subscription on logon-session creationGAP for CQL — created through the WMI API, so no process event fires. Covered only by the WMI-Activity 5861 hunt in section 7
T1547.001Startup-folder fallback persistencePartialAsepValueUpdate and the autorun inventory in section 7
T1055 / T1620Process ghosting, module stomping, parameter poisoning, manual PE mapping, allocate-write-protect-executeGAP for custom content — rely on the sensor's own memory and injection detections. The loader deliberately varies mode per host, so no single pattern holds
T1071.001Plaintext HTTP JSON tasking to a hard-coded endpoint on a non-standard portQ8, Q9Partial — atomic coverage is solid, behavioural coverage is noisy by nature
T1102.002 / T1567Private repository used as a per-host dead drop for tasking and resultsQ10Partial — the sensor sees only the name resolution. Confirmation needs full-URI proxy logs
T1059.003Operator commands through a shell with merged output captureQ12YesGood
T1016 / T1018 / T1069.002 / T1082 / T1518 / T1033Post-access discovery burst against the domainPartial — generic discovery detections apply; nothing campaign-specific was published

Known gaps, stated plainly

  • The anti-analysis gates and the in-memory execution modes cannot be hunted from telemetry. They happen inside one process with no observable side effect. This pack does not pretend otherwise, and no query below claims to cover them.
  • WMI subscription persistence has no CQL angle here because the loader creates it through the WMI API rather than through wmic.exe or a cmdlet. The WMI-Activity operational log is the only source, so if you are not collecting it you have no coverage of one of the three persistence mechanisms.
  • The dead-drop channel is only half-visible on the endpoint. Without full-URI proxy logging you can see that a process resolved a code-hosting API and nothing more, which is not enough to call it.
  • Single-source intelligence. Every atomic indicator here comes from one vendor's telemetry on one intrusion at two endpoints. Treat absence of hits as uninformative rather than reassuring, and lean on the behavioural half of the pack.

All four validation gates in section 11 must pass before any of this coverage is real. In particular, gate 1 — telemetry ready — is what separates a genuine "no hits" from a silently broken query, and gate 2 must be completed for Q9 and Q10 before either is handed to an analyst.

16

Hunt Summary Ticket

TITLE:      HollowFrame loader / Matryoshka backdoor family - proactive hunt
SEVERITY:   High
SCOPE:      All Windows endpoints. Prioritise users who handle inbound external
            documents, and any host group without application allowlisting.

HYPOTHESIS: An operator delivered a shortcut inside an encrypted archive, used
            PowerShell to request elevation and pre-authorise a staging directory
            in Defender, then ran a modular Go loader and a Rust backdoor under
            the names of trusted binaries via two chained DLL side-loads, keeping
            C2 on plaintext HTTP and on a private code-hosting repository.

QUERIES:    Q1  certutil decoding a staged blob in a user-writable path
            Q2  PowerShell relaunching itself elevated, hidden, policy-bypassed
            Q3  Defender exclusion added for a path or a process name
            Q4  Defender exclusion key written in the registry
            Q5  Archive imitating a Python embeddable distribution
            Q6  Python host executed with nothing to interpret
            Q7  Side-load DLL names written outside the system directories
            Q8  Known campaign network infrastructure
            Q9  Trusted side-load hosts opening outbound connections
            Q10 Code-hosting API resolved by non-developer processes
            Q11 Logon-triggered task pointing at a user-profile payload
            Q12 Command shell spawned by a side-load host

DO FIRST:   1. Run Q8 across full retention. A hit is an incident, not a hunt.
            2. Run Q3 and Q4 across 30 days. Review EVERY result by hand.
            3. For each Q3/Q4 host, re-run Q5, Q6, Q7 and Q11 scoped to that host
               across the following two hours. That sequence is the intrusion.
            4. Run Q12. An updater process parenting a shell needs no further
               corroboration before you isolate.

FINDINGS:   [ ] Q8  hits: ____   hosts: ____
            [ ] Q3  hits: ____   unexplained after review: ____
            [ ] Q4  hits: ____   unexplained after review: ____
            [ ] Q6  hits: ____   [ ] Q7 hits: ____   [ ] Q11 hits: ____
            [ ] Q12 hits: ____
            [ ] Estate-wide Defender exclusion audit complete: ____ / ____ hosts
            [ ] WMI subscription inventory complete:            ____ / ____ hosts

GAPS:       - Sandbox-evasion gates and in-memory execution: no telemetry exists.
            - WMI subscription persistence: needs WMI-Activity 5861 collection.
            - Dead-drop channel: needs full-URI proxy logging to confirm.
            - Single-vendor intelligence; absence of hits proves little.

ACTIONS:    [ ] Import section 10 CSV (malicious rows only - NOT the three
                trusted host binaries)
            [ ] Enable Defender Tamper Protection fleet-wide          (H2)
            [ ] Four ASR rules to Audit, then Block                   (H4)
            [ ] Mail gateway: hold password-protected archives        (H3)
            [ ] AppLocker/WDAC audit mode incl. the DLL collection    (H5)
            [ ] PowerShell script block logging + transcription       (H6)
            [ ] Scope code-hosting API access to development hosts    (H7)
            [ ] Pilot the four Custom IOA candidates in Detect mode   (section 9)

OWNER:      ____________________     DUE: ____________
VERSION:    v0.1 - 2026-08-01 - HuntPack
17

Changelog

v0.12026-08-01Initial pack. Built from the Blackpoint Cyber APG primary report (2026-07-30) and independent trade-press corroboration (2026-07-31). Twelve CQL hunt queries, four Custom IOA candidates, twelve tiered hardening controls, five deployable playbooks with rollback, and an eight-phase containment runbook. Three of the eleven published file hashes were identified as legitimate side-load host binaries and routed to a context-only block rather than the import CSV. The unrecovered shortcut hash ships as a labelled placeholder. SC Media returned HTTP 403 on two retrieval attempts and is therefore not cited; no indicator depends on it.
18

References

TierSourceUsed forAccessed
1 · PrimaryBlackpoint Cyber APG — Nested Trust: HollowFrame's Layered Loader and Matryoshka Backdoors (Nevan Beal, Sam Decker, published 2026-07-30)Entire attack chain, loader and backdoor internals, both persistence sets, complete file and network indicator tables, and the six defender recommendations that H2, H5, H7, H8 and the section 7 proxy hunts are built on.2026-08-01
2 · CorroborationThe Hacker News — HollowFrame Loader Deploys Matryoshka Backdoor in Spear-Phishing Attack on Law Firm (Ravie Lakshmanan, published 2026-07-31)Independent restatement of the chain, both C2 endpoints, and the dead-drop repository structure. Sole source for the account-creation and profile-update dates noted in section 2.2026-08-01
FrameworkMITRE ATT&CK — Enterprise matrix and mitigationsTechnique identifiers in section 6 and the M-number anchors on every hardening control in section 12.2026-08-01
VendorCrowdStrike Falcon LogScale event and field documentationEvent names and field names used by all twelve queries in section 8.2026-08-01
BaselineCIS Microsoft Windows Benchmarks; Microsoft Security Baselines; Microsoft ASR, WDAC, AppLocker and Defender configuration documentationPlatform citations for the tiered hardening controls and the five deployable playbooks.2026-08-01
UnavailableSC Media — New HollowFrame loader and Matryoshka malware family discoveredIntended as a third corroborating source. Returned HTTP 403 on two attempts from two different fetchers, so no snapshot exists and it is not cited. No indicator in this pack depends on it.2026-08-01 (failed)

Source snapshots for both cited sources are saved verbatim alongside this file in HollowFrame-Matryoshka-Hunt-sources/. Every atomic indicator shipped in section 10 traces to one of them.

HuntPack · HollowFrame / Matryoshka · v0.1 · Generated 2026-08-01