ShellterLoader — Windows Downloader / Dropper
Executive Summary
ShellterLoader is a Windows downloader/dropper reported by CYFIRMA in its Weekly Intelligence Report dated 2026-10-01. It is not itself a data-theft tool: its job is to establish an initial foothold and retrieve a second-stage payload, making the visible sample only one link in a longer chain. On startup it creates two named mutexes (ChromeProcessSingletonStartup! and OMADM_NAMED_MUTEX) to enforce a single running instance, then runs basic environment checks and may alter its behavior or terminate if the host looks unsuitable for continued execution (analysis evasion). It masquerades as, or runs from paths and under names associated with, Chrome, Edge, and Windows system binaries (chrome.exe, msedge.exe, BackgroundTaskHost.exe, RuntimeBroker.exe) and mimics Chromium user-data artifacts. It uses reflective loading and in-memory execution, with memory and thread manipulation consistent with code injection into another process's context, to retrieve and stage its next-stage payload over a websocket channel at wss.scriptlab.cc. CYFIRMA's own narrative also describes the loader communicating with, or masquerading traffic as, the legitimate comScore analytics domain sb.scorecardresearch.com during payload retrieval.
Single-source caveat: as of this pack's build date, CYFIRMA is the only source located for ShellterLoader under this name. A targeted search (threat name, sample hashes, named mutexes) found no independent corroboration. Per this pipeline's two-source rule, every indicator in this pack ships at action=detect only — nothing is promoted to Prevent or Critical. Treat any hit as a precursor to a broader compromise: the second-stage payload is not described in the available reporting.
Defender priority: sb.scorecardresearch.com is a legitimate third-party comScore analytics domain. CYFIRMA's own text frames ShellterLoader as masquerading as, or abusing, traffic to it — not owning it. Do not block this domain. The actionable, low-noise signals are path/name anomalies on Chrome/Edge/system-binary masquerades and the dedicated scriptlab.cc C2 domain.
Source Review & Web Hunter Notes
| Tier | Source | Key Finding | Carry Fwd |
|---|---|---|---|
| 1 | CYFIRMA — Weekly Intelligence Report, 1 Oct 2026, "Active Malware of the Week: ShellterLoader" | Full attack-method narrative, two named mutexes, masquerading paths, command-line fragment, reflective-load/injection description, YARA rule with 3 sample hashes and 16 strings, MITRE ATT&CK table | yes |
Web-hunter note: This is a single-source pack. A targeted search for independent corroboration (the exact name "ShellterLoader", the sample SHA-256, and the mutex name ChromeProcessSingletonStartup!) returned no second report on this family. Search results instead surfaced an unrelated story — the legitimate commercial Shellter AV/EDR evasion framework being abused by infostealer actors after a leaked license (SecurityWeek, BleepingComputer, Elastic Security Labs, CrowdStrike blog, mid-2025). That campaign is a different tool, a different timeframe, and uses none of ShellterLoader's hashes, mutexes, or C2 infrastructure — it is explicitly excluded from this pack's indicators per the dedupe-by-TTP rule. All atomic indicators below trace only to the CYFIRMA snapshot in ShellterLoader-Hunt-sources/01-cyfirma-weekly.txt.
Hunt Brief & Attack Chain
Hunt hypotheses (ordered by fidelity)
- H1 (high): A binary named
chrome.exeexecutes from a user-writableAppData\Local\Chromium\Applicationpath rather than a real browser install location. → Q1 - H2 (medium):
msedge.exeruns with the first-run-suppression flag combo from a non-interactive parent. → Q2 - H3 (high):
RuntimeBroker.exe/BackgroundTaskHost.exeexecute from outsideSystem32. → Q3 - H4 (medium):
RuntimeBroker.exe/BackgroundTaskHost.exeare spawned by a non-svchost.exeparent even when the path looks standard. → Q4 - H5 (medium): The
--no-first-run --no-default-browser-checkflag combo appears on a process whose name is notchrome.exe/msedge.exe(a renamed loader carrying the same flags). → Q5 - H6 (high): A host resolves the known C2 domain
scriptlab.cc. → Q6 - H7 (high): Execution of a known ShellterLoader sample hash. → Q7
- H8 (low, hunt-only): A non-browser process contacts
sb.scorecardresearch.com— legitimate infrastructure named in the reporting as abused/masqueraded for payload retrieval; context-only, never a block candidate. → Q8
Attack chain
| Step | Behavior | Telemetry | Hunt Angle |
|---|---|---|---|
| 1 · Guardrail | Create ChromeProcessSingletonStartup! + OMADM_NAMED_MUTEX; enforce single instance | Not CQL-queryable (s7) | Behavioral only — gap |
| 2 · Evasion | Basic environment/host-suitability checks; may alter behavior or terminate | Not CQL-queryable (s7) | Behavioral only — gap |
| 3 · Masquerade | Run as/mimic chrome.exe, msedge.exe, BackgroundTaskHost.exe, RuntimeBroker.exe; mimic Chromium user-data artifacts | ProcessRollup2 (FileName, FilePath, CommandLine, ParentBaseFileName) | Q1, Q2, Q3, Q4, Q5 |
| 4 · Reflective load / injection | Memory and thread manipulation consistent with code injection into another process | Not CQL-queryable (s7) | Behavioral only — gap |
| 5 · Payload staging / C2 | Retrieve next-stage payload over websocket to scriptlab.cc; traffic masquerading as/abusing sb.scorecardresearch.com | DnsRequest | Q6, Q8 |
| 6 · Known sample | Execution of the published SHA-256/SHA1/MD5 | ProcessRollup2 (hash fields) | Q7 |
| 7 · Unknown next stage | Second-stage payload — not described in the available reporting | Unassessed | Treat as precursor; widen the hunt, do not close on loader removal alone |
Consolidated IOC Table
Single-source (CYFIRMA, 2026-10-01). Every indicator below ships for detection only — see s11 for the promotion criteria.
| Type | Value | Conf | Action | Context |
|---|---|---|---|---|
| sha256 | 594033ed58e27b42bb1bef7e5b21eac87f0d660c7cc3d48881a2e5575e3ac811 | high | detect | ShellterLoader sample (CYFIRMA YARA rule) |
| sha1 | dd39fafbdba994169991cea092c6428e1d3b1539 | high | detect | ShellterLoader sample (CYFIRMA YARA rule) |
| md5 | d3cea61538aa5030e90a1d38cca762b4 | high | detect | ShellterLoader sample (CYFIRMA YARA rule) |
| domain | wss.scriptlab.cc | high | detect | C2 / payload-staging websocket endpoint |
| url | wss.scriptlab.cc/api/splitChanges/850ec405 | medium | detect | C2 websocket path (YARA string) |
| mutex | ChromeProcessSingletonStartup! | high | hunt | Single-instance guardrail (not CQL-queryable, see s7) |
| mutex | OMADM_NAMED_MUTEX | high | hunt | Single-instance guardrail (not CQL-queryable, see s7) |
| behavior | chrome.exe at C:\Users\<USER>\AppData\Local\Chromium\Application\chrome.exe | high | detect | Masquerading path — Q1 |
| behavior | msedge.exe at C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe with --no-first-run --no-default-browser-check | medium | detect | Legitimate install path; flag+parent anomaly needed — Q2 |
| behavior | C:\Windows\system32\BackgroundTaskHost.exe -ServerName:BackgroundTaskHost.WebAccountProvider | high | detect | Masquerade when path is NOT System32 — Q3 |
| behavior | C:\Windows\System32\RuntimeBroker.exe -Embedding | high | detect | Masquerade when path is NOT System32 — Q3 |
| file path | ...\AppData\Local\Chromium\User Data\Crashpad\settings.dat | medium | hunt | Chromium user-data artifact mimicry (not CQL-queryable, see s7) |
| file path | ...\AppData\Local\Chromium\User Data\BrowserMetrics\BrowserMetrics-6AB8F3B2-122C.pma | medium | hunt | Chromium user-data artifact mimicry (not CQL-queryable, see s7) |
| file path | ...\AppData\Local\Chromium\User Data\lockfile | medium | hunt | Chromium user-data artifact mimicry (not CQL-queryable, see s7) |
| file path | ...\AppData\Local\Chromium\User Data\Variations | medium | hunt | Chromium user-data artifact mimicry (not CQL-queryable, see s7) |
| domain (legitimate — do not block) | sb.scorecardresearch.com | low | context only | Legitimate comScore analytics infrastructure. CYFIRMA describes ShellterLoader as masquerading as/abusing traffic to this domain during payload retrieval. Never ship as prevent/block — Q8 |
Affected Surface & Telemetry Matrix
| Surface | Required Telemetry | Priority | Gap Risk |
|---|---|---|---|
| Windows endpoints (initial loader execution) | Process creation with image path, command line and parent CrowdStrike: ProcessRollup2 · SentinelOne: Process Creation · Defender: DeviceProcessEvents | Critical | Low — masquerading paths are specific and well covered by Q1–Q5 |
| DNS / network egress | DNS lookups with the requesting process CrowdStrike: DnsRequest · SentinelOne: DNS Resolved · Defender: DeviceEvents (DnsQueryResponse), see the Q6 and Q8 assumptions | High | Low — scriptlab.cc is a dedicated, low-noise domain |
| Process-memory / injection layer | No Falcon CQL event documented for mutex creation, RWX allocation, or remote-thread creation (see s7). The SentinelOne and Defender tabs do not query this layer either. | High | High — in Falcon this layer depends on the on-sensor ML/IOA engine, not LogScale-queryable telemetry |
| Downstream / second-stage payload | Unknown — the single available source does not describe the staged payload | Critical | Unassessed — treat any confirmed hit as a precursor to a broader compromise, not an isolated event |
ATT&CK Mapping
| Tactic | Technique | Observed Behavior | Query / Control |
|---|---|---|---|
| Execution | T1047 — Windows Management Instrumentation | Listed in CYFIRMA's TTP table; not elaborated with atomic detail in the attack-method narrative for this sample | Behavioral (gap) — pair with your existing WMI-execution hunts |
| Execution | T1059 — Command and Scripting Interpreter | Listed in CYFIRMA's TTP table; not elaborated with atomic detail | Behavioral (gap) |
| Execution | T1129 — Shared Modules | Reflective/in-memory loading of staged components | Behavioral (gap, s7) |
| Defense Evasion | T1027.002 — Obfuscated Files or Information: Software Packing | Execution chain designed to reduce visibility and complicate static analysis | Behavioral (gap) |
| Defense Evasion | T1036.005 — Masquerading: Match Legitimate Name or Location | chrome.exe / msedge.exe / BackgroundTaskHost.exe / RuntimeBroker.exe path and name mimicry (analyst-mapped from the reported strings) | Q1, Q2, Q3, Q4, Q5 |
| Defense Evasion | T1218 — System Binary Proxy Execution | Masquerading as legitimate Chromium, Edge, and Windows system binaries | Q1–Q5 |
| Defense Evasion | T1497 — Virtualization/Sandbox Evasion | Mutex-gated single-instance check plus "basic environment checks"; may alter behavior or terminate | Behavioral (gap, s7) |
| Defense Evasion | T1564 — Hide Artifacts | Chromium user-data artifact mimicry (settings.dat, lockfile, Variations, BrowserMetrics file) | Behavioral (gap, s7) |
| Defense Evasion | T1055 — Process Injection (analyst-added) | "Memory and thread manipulation consistent with code injection into alternate process contexts" per CYFIRMA | Q3, Q4 (masquerade precursor only); injection itself is a gap (s7) |
| Discovery | T1012 / T1033 / T1057 / T1082 / T1083 / T1518.001 | Listed in CYFIRMA's TTP table as generic environment/host checks; no atomic command or registry key published | Behavioral (gap, s7) — pair with existing discovery-chain hunts |
| Collection | T1185 — Browser Session Hijacking | Listed in CYFIRMA's TTP table under Collection; not elaborated in the attack-method narrative for this sample | Not built — no corroborating atomic detail, flagged for completeness only |
| Command and Control | T1071 / T1071.001 — Application Layer Protocol / Web Protocols | Websocket C2 to scriptlab.cc | Q6 |
| Command and Control | T1573 — Encrypted Channel | wss:// (TLS) C2 channel | Q6 |
| Command and Control | T1102.002 — Web Service: Bidirectional Communication (analyst-added, low confidence) | Traffic masquerading as/abusing the legitimate sb.scorecardresearch.com during payload retrieval | Q8 — hunt/context only, legitimate domain, never block |
| Impact | T1485 / T1486 — Data Destruction / Data Encrypted for Impact | Listed in CYFIRMA's weekly TTP table; the ShellterLoader attack-method narrative describes only delivery/staging behavior, not destructive or encryption impact. This pair appears to reflect the week's broader ransomware coverage (Qilin, The Gentlemen) rather than ShellterLoader itself. | Not corroborated for this family — excluded from scope, no hunt built |
Native Audit-Log Hunts (non-CQL)
The behaviors below are described in the source reporting but are not exposed as queryable fields in Falcon's documented LogScale event model (crowdstrike-logscale-v3 reference set). They are listed here as honest gaps with the best available compensating approach, rather than being forced into a fabricated CQL field.
- Mutex creation (
ChromeProcessSingletonStartup!,OMADM_NAMED_MUTEX): Falcon's CQL/LogScale event model does not expose named kernel-object creation as a queryable event. This guardrail is visible to Falcon's on-sensor ML/behavioral detection engine but not as raw telemetry you can hunt with CQL. Validate presence of these objects via Falcon Real Time Response (RTR) on hosts already flagged by Q1–Q5, or a live-response handle enumeration during IR. - Reflective loading / in-memory execution / thread or memory manipulation consistent with injection: no Falcon CQL field directly exposes RWX memory allocations or remote-thread creation. Rely on Falcon's built-in IOA/ML detections (console-side, not LogScale-queryable) for this layer, and use RTR to inspect the loaded-module list of hosts already flagged by Q1–Q5 for threads whose start address does not map to a known module.
- Chromium user-data artifact mimicry (
settings.dat,lockfile,Variations,BrowserMetrics-6AB8F3B2-122C.pmaunder a masqueradingUser Datatree): these are non-executable data-file writes. Falcon's documented event catalog (PeFileWritten,NewExecutableWritten,ZipFileWritten) covers executables and archives, not arbitrary data files, so this artifact set is not reliably CQL-queryable today. If your environment layers Sysmon, hunt Event ID 11 (FileCreate) for these exact filenames under a path that fails theFilePathanchoring used in Q1. - Environment / host-suitability checks (generic discovery before ShellterLoader decides whether to run): the source reporting describes these only generically — no atomic registry key, command, or API was published. Treat as a documented gap rather than building a hunt on an assumption; pair any Q1–Q5 hit with the discovery-chain hunts already in your library (for example
systeminfo.exe/tasklist.exe/wmic.exespawned immediately after a masquerading process).
Hunt Queries: CrowdStrike CQL, SentinelOne PowerQuery and Defender XDR KQL
Use your tenant's own address. SentinelOne does not document a link that pre-fills a query, so each "Copy & open SentinelOne" button copies the query and opens this console: paste it into PowerQuery.
Pick your portal. Microsoft documents a Share link in advanced hunting but not its URL format, so each "Copy & open Defender" button copies the query and opens Advanced hunting: paste it into the editor.
Looks for: a basename matching chrome.exe running from AppData\Local\Chromium\Application — a user-writable path, not a real browser install location — with the reported suppression flags. FP: low; legitimate Google Chrome installs under Program Files/Google\Chrome\Application, not a user-profile Chromium folder.
Known limitations and deployment notes
- PowerQuery: A browser launched by a process the agent never observed starting is not captured.
- PowerQuery assumes: tgt.process.image.sha256 is the Process Creation hash field that the independent pySigma backend maps; whether a tenant populates it is unproven, which the readiness test shows.
- PowerQuery assumes: String matches is case-insensitive by default, which reproduces the CQL /i intent.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: FolderPath holds the full image path of the created process.
- KQL – Defender XDR assumes: Both suppression flags are matched as plain substrings.
// HUNT: chrome.exe executing from a user-writable Chromium path (masquerading) // MITRE: T1036.005, T1218 CONF: high FP: low COST: low | REQUIRES: ProcessRollup2 #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | FileName=/^chrome(\.exe)?$/i | FilePath=/\\AppData\\Local\\Chromium\\Application\\/i | CommandLine=/--no-first-run|--no-default-browser-check/i | table([ComputerName, UserName, ParentBaseFileName, FilePath, CommandLine, SHA256HashData], limit=200)
5 required fields · View requirements
Required telemetry
- SentinelOne Deep Visibility endpoint events
Required fields
tgt.process.name: Created process nametgt.process.image.path: Created process pathtgt.process.cmdline: Created command lineevent.time: Event timeevent.type: Event type
Recommended fields
src.process.name: Creating process
Optional fields
tgt.process.image.sha256: Hash. Mapped by the pySigma backend; unproven on a tenant.
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.name = * tgt.process.image.path = * tgt.process.cmdline = * | columns event.time, tgt.process.name, tgt.process.image.path, tgt.process.cmdline | limit 5
// HUNT: chrome.exe executing from a user-writable Chromium path (masquerading) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1036.005, T1218 // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same Process Creation predicate: chrome by name, the AppData Chromium path, and either suppression flag. The parent is src.process on creation events, so the projected parent column is src.process.name. // REQUIRES: SentinelOne process-creation telemetry with command lines // TUNING: Exclude sanctioned portable Chromium builds by path after a baseline review. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No custom detection or lookup objects required. // KNOWN GAPS: A browser launched by a process the agent never observed starting is not captured. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches "^chrome(\\.exe)?$" tgt.process.image.path matches "\\\\AppData\\\\Local\\\\Chromium\\\\Application\\\\" (tgt.process.cmdline contains '--no-first-run' or tgt.process.cmdline contains '--no-default-browser-check') | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.image.path, tgt.process.cmdline, tgt.process.image.sha256 | limit 200
Automated validation: harness-generated
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameFolderPath: Created process pathProcessCommandLine: Created command line
Recommended fields
InitiatingProcessFileName: Initiating process
Optional fields
SHA256: Hash. SHA256 is often unpopulated in DeviceProcessEvents; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, FolderPath, ProcessCommandLine | take 5
// HUNT: chrome.exe executing from a user-writable Chromium path (masquerading)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1036.005, T1218
// CONF: high | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: chrome by name, the AppData Chromium path, and either suppression flag. contains is case-insensitive, which reproduces the CQL /i intent. The parent is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude sanctioned portable Chromium builds by FolderPath after a baseline review.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required. To alert on it, create a custom detection rule from this query after removing the Timestamp filter, the sort and the final take: the service applies the rule's lookback itself, and the query already returns Timestamp, ReportId and DeviceId.
// KNOWN GAPS: A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: harness-generated; static=passed; fixtures=not executed (2 generated)
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where FileName in~ ("chrome.exe", "chrome")
| where FolderPath contains "\\AppData\\Local\\Chromium\\Application\\"
| where ProcessCommandLine contains "--no-first-run" or ProcessCommandLine contains "--no-default-browser-check"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FolderPath, ProcessCommandLine, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: msedge.exe launched with --no-first-run --no-default-browser-check by a parent that is not a normal interactive launcher. This hits the real default Edge install path, so path alone cannot discriminate — behavior and lineage carry the signal. FP: medium; deployment/automation tooling (SCCM, Intune, browser test harnesses) legitimately passes these flags.
Known limitations and deployment notes
- PowerQuery: A parent the agent did not record leaves src.process.name null, and the negation then keeps the row.
- PowerQuery assumes: The parent allowlist negation depends on src.process.name being the creator on Process Creation events, which the field model attests.
- PowerQuery assumes: tgt.process.image.sha256 is the Process Creation hash field that the independent pySigma backend maps; whether a tenant populates it is unproven, which the readiness test shows.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: A parent the sensor did not record leaves InitiatingProcessFileName empty, and the negation then keeps the row, as the CQL does.
// HUNT: msedge.exe launched with first-run-suppression flags by a non-interactive parent // MITRE: T1036.005 CONF: medium FP: medium COST: low | REQUIRES: ProcessRollup2 // TUNING: exclude known deployment/automation parents (SCCM, Intune, chromedriver.exe, msedgedriver.exe, GPO logon scripts) before promoting beyond hunt #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | FileName=/^msedge(\.exe)?$/i | CommandLine=/--no-first-run/i | CommandLine=/--no-default-browser-check/i | ParentBaseFileName!=/^(explorer|userinit|msedge|RuntimeBroker|SearchApp|StartMenuExperienceHost)\.exe$/i | table([ComputerName, UserName, ParentBaseFileName, FilePath, CommandLine, SHA256HashData], limit=200)
5 required fields · View requirements
Required telemetry
- SentinelOne Deep Visibility endpoint events
Required fields
tgt.process.name: Created process nametgt.process.cmdline: Created command linesrc.process.name: Creating process nameevent.time: Event timeevent.type: Event type
Recommended fields
tgt.process.image.path: Created process path
Optional fields
tgt.process.image.sha256: Hash. Mapped by the pySigma backend; unproven on a tenant.
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.name = * tgt.process.cmdline = * src.process.name = * | columns event.time, tgt.process.name, tgt.process.cmdline, src.process.name | limit 5
// HUNT: msedge.exe launched with first-run-suppression flags by a non-interactive parent // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1036.005 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: msedge with both first-run suppression flags launched by a parent outside the interactive allowlist. On creation events the parent is src.process. // REQUIRES: SentinelOne process-creation telemetry with command lines // TUNING: Extend the parent allowlist with sanctioned installers or deployment agents after a baseline review. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No custom detection or lookup objects required. // KNOWN GAPS: A parent the agent did not record leaves src.process.name null, and the negation then keeps the row. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches "^msedge(\\.exe)?$" tgt.process.cmdline contains '--no-first-run' tgt.process.cmdline contains '--no-default-browser-check' !(src.process.name matches "^(explorer|userinit|msedge|RuntimeBroker|SearchApp|StartMenuExperienceHost)\\.exe$") | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.image.path, tgt.process.cmdline, tgt.process.image.sha256 | limit 200
Automated validation: harness-generated
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: Created command lineInitiatingProcessFileName: Initiating process
Optional fields
SHA256: Hash. SHA256 is often unpopulated in DeviceProcessEvents; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: msedge.exe launched with first-run-suppression flags by a non-interactive parent
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1036.005
// CONF: medium | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: msedge with both first-run suppression flags launched by a parent outside the interactive allowlist. The parent is InitiatingProcessFileName, the same creator-versus-created lineage as the CQL.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Extend the parent allowlist with sanctioned installers or deployment agents after a baseline review.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required. This is a hunt in this pack: run it on demand, do not schedule it as a detection.
// KNOWN GAPS: A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: harness-generated; static=passed; fixtures=not executed (3 generated)
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where FileName in~ ("msedge.exe", "msedge")
| where ProcessCommandLine contains "--no-first-run" and ProcessCommandLine contains "--no-default-browser-check"
| where InitiatingProcessFileName !in~ ("explorer.exe", "userinit.exe", "msedge.exe", "RuntimeBroker.exe", "SearchApp.exe", "StartMenuExperienceHost.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FolderPath, ProcessCommandLine, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: a process named RuntimeBroker.exe or BackgroundTaskHost.exe whose FilePath is not under System32/SysWOW64. Both binaries only ever ship from those directories on a standard Windows build, so a path mismatch is a strong masquerading signal. FP: low.
Known limitations and deployment notes
- PowerQuery: A renamed binary that is not named RuntimeBroker or BackgroundTaskHost is outside this predicate.
- PowerQuery assumes: A null image path satisfies the negation and keeps the row, matching the CQL != behaviour on a missing field.
- PowerQuery assumes: tgt.process.image.sha256 is the Process Creation hash field that the independent pySigma backend maps; whether a tenant populates it is unproven, which the readiness test shows.
- KQL – Defender XDR: A renamed binary that is not named RuntimeBroker or BackgroundTaskHost is outside this predicate.
- KQL – Defender XDR assumes: An empty FolderPath satisfies the negation and keeps the row, matching the CQL != behaviour on a missing field.
// HUNT: RuntimeBroker.exe / BackgroundTaskHost.exe executing outside System32 (masquerading) // MITRE: T1036.005, T1055, T1218 CONF: high FP: low COST: low | REQUIRES: ProcessRollup2 #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | FileName=/^(RuntimeBroker|BackgroundTaskHost)(\.exe)?$/i | FilePath!=/\\Windows\\(System32|SysWOW64)\\/i | table([ComputerName, UserName, ParentBaseFileName, FilePath, CommandLine, SHA256HashData], limit=200)
4 required fields · View requirements
Required telemetry
- SentinelOne Deep Visibility endpoint events
Required fields
tgt.process.name: Created process nametgt.process.image.path: Created process pathevent.time: Event timeevent.type: Event type
Recommended fields
tgt.process.cmdline: Created command line
Optional fields
tgt.process.image.sha256: Hash. Mapped by the pySigma backend; unproven on a tenant.
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.name = * tgt.process.image.path = * | columns event.time, tgt.process.name, tgt.process.image.path | limit 5
// HUNT: RuntimeBroker.exe / BackgroundTaskHost.exe executing outside System32 (masquerading) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1036.005, T1055, T1218 // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a system process name executing from outside System32 and SysWOW64. // REQUIRES: SentinelOne process-creation telemetry with image paths // TUNING: Allowlist sanctioned side-by-side servicing paths after a baseline review. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No custom detection or lookup objects required. // KNOWN GAPS: A renamed binary that is not named RuntimeBroker or BackgroundTaskHost is outside this predicate. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches "^(RuntimeBroker|BackgroundTaskHost)(\\.exe)?$" !(tgt.process.image.path matches "\\\\Windows\\\\(System32|SysWOW64)\\\\") | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.image.path, tgt.process.cmdline, tgt.process.image.sha256 | limit 200
Automated validation: harness-generated
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameFolderPath: Created process path
Recommended fields
InitiatingProcessFileName: Initiating processProcessCommandLine: Created command line
Optional fields
SHA256: Hash. SHA256 is often unpopulated in DeviceProcessEvents; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, FolderPath | take 5
// HUNT: RuntimeBroker.exe / BackgroundTaskHost.exe executing outside System32 (masquerading)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1036.005, T1055, T1218
// CONF: high | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a system process name executing from outside System32 and SysWOW64.
// REQUIRES: Defender for Endpoint process-creation telemetry with image paths (DeviceProcessEvents)
// TUNING: Allowlist sanctioned side-by-side servicing paths after a baseline review.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required. To alert on it, create a custom detection rule from this query after removing the Timestamp filter, the sort and the final take: the service applies the rule's lookback itself, and the query already returns Timestamp, ReportId and DeviceId.
// KNOWN GAPS: A renamed binary that is not named RuntimeBroker or BackgroundTaskHost is outside this predicate.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: harness-generated; static=passed; fixtures=not executed (2 generated)
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where FileName in~ ("RuntimeBroker.exe", "BackgroundTaskHost.exe", "RuntimeBroker", "BackgroundTaskHost")
| where not (FolderPath contains "\\Windows\\System32\\" or FolderPath contains "\\Windows\\SysWOW64\\")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FolderPath, ProcessCommandLine, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: the same two binaries, running from the legitimate System32/SysWOW64 path, but spawned by something other than svchost.exe — the only legitimate launcher for these DCOM-activated services. FP: medium; some AppX/UWP hosting edge cases spawn these via taskhostw.exe or dllhost.exe.
Known limitations and deployment notes
- PowerQuery: Hollowing or injection into a correctly parented process does not change the creator and is not detected here.
- PowerQuery assumes: The creator is src.process on Process Creation events, which the field model attests.
- PowerQuery assumes: tgt.process.image.sha256 is the Process Creation hash field that the independent pySigma backend maps; whether a tenant populates it is unproven, which the readiness test shows.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: An empty InitiatingProcessFileName keeps the row, as the CQL does.
// HUNT: RuntimeBroker.exe / BackgroundTaskHost.exe with a non-svchost parent // MITRE: T1036.005, T1055 CONF: medium FP: medium COST: low | REQUIRES: ProcessRollup2 // TUNING: baseline legitimate parents in your fleet (svchost.exe is standard; some AppX/UWP hosts spawn via taskhostw.exe/dllhost.exe) before promoting past hunt #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | FileName=/^(RuntimeBroker|BackgroundTaskHost)(\.exe)?$/i | FilePath=/\\Windows\\(System32|SysWOW64)\\/i | ParentBaseFileName!=/^svchost\.exe$/i | table([ComputerName, UserName, ParentBaseFileName, FilePath, CommandLine, SHA256HashData], limit=200)
5 required fields · View requirements
Required telemetry
- SentinelOne Deep Visibility endpoint events
Required fields
tgt.process.name: Created process nametgt.process.image.path: Created process pathsrc.process.name: Creating process nameevent.time: Event timeevent.type: Event type
Recommended fields
tgt.process.cmdline: Created command line
Optional fields
tgt.process.image.sha256: Hash. Mapped by the pySigma backend; unproven on a tenant.
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.name = * tgt.process.image.path = * src.process.name = * | columns event.time, tgt.process.name, tgt.process.image.path, src.process.name | limit 5
// HUNT: RuntimeBroker.exe / BackgroundTaskHost.exe with a non-svchost parent // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1036.005, T1055 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the genuine binary name and path, but a creator other than svchost.exe. On creation events the creator is src.process. // REQUIRES: SentinelOne process-creation telemetry with image paths // TUNING: Allowlist sanctioned broker parents after a baseline review. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No custom detection or lookup objects required. // KNOWN GAPS: Hollowing or injection into a correctly parented process does not change the creator and is not detected here. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches "^(RuntimeBroker|BackgroundTaskHost)(\\.exe)?$" tgt.process.image.path matches "\\\\Windows\\\\(System32|SysWOW64)\\\\" !(src.process.name matches "^svchost\\.exe$") | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.image.path, tgt.process.cmdline, tgt.process.image.sha256 | limit 200
Automated validation: harness-generated
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameFolderPath: Created process pathInitiatingProcessFileName: Initiating process
Recommended fields
ProcessCommandLine: Created command line
Optional fields
SHA256: Hash. SHA256 is often unpopulated in DeviceProcessEvents; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, FolderPath, InitiatingProcessFileName | take 5
// HUNT: RuntimeBroker.exe / BackgroundTaskHost.exe with a non-svchost parent
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1036.005, T1055
// CONF: medium | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the genuine system binaries started by something other than svchost.exe. The parent is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Baseline legitimate parents in your fleet (taskhostw.exe and dllhost.exe start some AppX hosts) before promoting past hunt.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required. This is a hunt in this pack: run it on demand, do not schedule it as a detection.
// KNOWN GAPS: A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: harness-generated; static=passed; fixtures=not executed (2 generated)
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where FileName in~ ("RuntimeBroker.exe", "BackgroundTaskHost.exe", "RuntimeBroker", "BackgroundTaskHost")
| where FolderPath contains "\\Windows\\System32\\" or FolderPath contains "\\Windows\\SysWOW64\\"
| where InitiatingProcessFileName !~ "svchost.exe"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FolderPath, ProcessCommandLine, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: the exact --no-first-run --no-default-browser-check flag combo on a process whose basename is not chrome.exe/msedge.exe — a renamed or relocated loader still carrying the same embedded launch string. FP: medium; browser-automation harnesses pass these flags too.
Known limitations and deployment notes
- PowerQuery: Other Chromium builds that legitimately accept these flags will match until excluded.
- PowerQuery assumes: contains is a case-insensitive substring match, so the flags match regardless of case.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: Both flags are matched as plain substrings anywhere on the command line.
// HUNT: browser first-run-suppression flag combo on a non-browser image (renamed loader) // MITRE: T1036.005, T1027.002 CONF: medium FP: medium COST: low | REQUIRES: ProcessRollup2 // TUNING: exclude approved test/automation harnesses (Selenium, Puppeteer, chromedriver.exe, msedgedriver.exe) that legitimately pass these flags #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | CommandLine=/--no-first-run/i | CommandLine=/--no-default-browser-check/i | FileName!=/^(chrome|msedge)(\.exe)?$/i | table([ComputerName, UserName, FileName, FilePath, ParentBaseFileName, CommandLine], limit=200)
4 required fields · View requirements
Required telemetry
- SentinelOne Deep Visibility endpoint events
Required fields
tgt.process.name: Created process nametgt.process.cmdline: Created command lineevent.time: Event timeevent.type: Event type
Recommended fields
src.process.name: Creating process name
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.name = * tgt.process.cmdline = * | columns event.time, tgt.process.name, tgt.process.cmdline | limit 5
// HUNT: browser first-run-suppression flag combo on a non-browser image (renamed loader) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1036.005, T1027.002 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: both suppression flags on an image that is not Chrome or Edge. // REQUIRES: SentinelOne process-creation telemetry with command lines // TUNING: Exclude other Chromium-based browsers you sanction, such as Brave, after a baseline review. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No custom detection or lookup objects required. // KNOWN GAPS: Other Chromium builds that legitimately accept these flags will match until excluded. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.cmdline contains '--no-first-run' tgt.process.cmdline contains '--no-default-browser-check' !(tgt.process.name matches "^(chrome|msedge)(\\.exe)?$") | columns event.time, endpoint.name, src.process.user, tgt.process.name, tgt.process.image.path, src.process.name, tgt.process.cmdline | limit 200
Automated validation: harness-generated
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: Created command line
Recommended fields
InitiatingProcessFileName: Initiating processFolderPath: Created process path
Optional fields
SHA256: Hash. SHA256 is often unpopulated in DeviceProcessEvents; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, ProcessCommandLine | take 5
// HUNT: browser first-run-suppression flag combo on a non-browser image (renamed loader)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1036.005, T1027.002
// CONF: medium | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: both suppression flags on a process whose image is not Chrome or Edge.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude approved test and automation harnesses (Selenium, Puppeteer, chromedriver.exe, msedgedriver.exe) that legitimately pass these flags.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required. This is a hunt in this pack: run it on demand, do not schedule it as a detection.
// KNOWN GAPS: A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: harness-generated; static=passed; fixtures=not executed (2 generated)
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine contains "--no-first-run" and ProcessCommandLine contains "--no-default-browser-check"
| where FileName !in~ ("chrome.exe", "msedge.exe", "chrome", "msedge")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FolderPath, ProcessCommandLine, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: DNS resolution of the scriptlab.cc apex or any subdomain (covers the reported wss.scriptlab.cc host). FP: low — dedicated, single-purpose domain.
Known limitations and deployment notes
- PowerQuery: A tenant that populates dns.request but not event.dns.request returns no rows; confirm with the readiness test.
- PowerQuery assumes: event.dns.request is the attested field and dns.request is documented by the vendor; the field model records an unresolved conflict about which one a tenant populates.
- PowerQuery assumes: The acting process on a DNS event is src.process.
- KQL – Defender XDR: A lookup answered from the local resolver cache may not generate an event.
- KQL – Defender XDR: If DnsQueryResponse is not populated on your tenant, the fallback is DeviceNetworkEvents on RemoteUrl, which finds connections to the host rather than lookups.
- KQL – Defender XDR assumes: Microsoft's DeviceEvents reference does not list ActionType values or the JSON keys inside AdditionalFields. DnsQueryResponse is attested only in community and tooling sources, and the key that holds the queried name is DnsQueryString in some of them and QueryName in others; the query reads whichever is present.
- KQL – Defender XDR assumes: Run the readiness test first: it prints the raw AdditionalFields so you can confirm the key on your tenant before trusting a zero-row result.
// HUNT: DNS resolution of the ShellterLoader scriptlab.cc C2 infrastructure // MITRE: T1071.001, T1573 CONF: high FP: low COST: low | REQUIRES: DnsRequest #event_simpleName=DnsRequest | DomainName=/(^|\.)scriptlab\.cc$/i | table([ComputerName, ContextBaseFileName, DomainName, aid], limit=200)
3 required fields · View requirements
Required telemetry
- SentinelOne Deep Visibility endpoint events
Required fields
event.dns.request: DNS query nameevent.time: Event timeevent.type: Event type
Recommended fields
src.process.name: Resolving process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * | columns event.time, event.dns.request, src.process.name | limit 5
// HUNT: DNS resolution of the ShellterLoader scriptlab.cc C2 infrastructure // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1071.001, T1573 // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same domain predicate on DNS Resolved events. The substring clause carries the stable literal and the anchored regex restores the CQL boundary so a lookalike suffix does not match. // REQUIRES: SentinelOne DNS resolution telemetry // TUNING: Domain is single-sourced; keep this as detect until a second source corroborates it. // LOOKBACK: 30d; extend to the retention window for a historic sweep // CONFIGURATION: No custom detection or lookup objects required. // KNOWN GAPS: A tenant that populates dns.request but not event.dns.request returns no rows; confirm with the readiness test. // VALIDATION LEVEL: static-reviewed event.type = 'DNS Resolved' event.dns.request contains 'scriptlab.cc' event.dns.request matches "(^|\\.)scriptlab\\.cc$" | columns event.time, endpoint.name, src.process.name, event.dns.request | limit 200
Automated validation: harness-generated
3 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: Event action typeAdditionalFields: Event details (JSON)
Recommended fields
InitiatingProcessFileName: Initiating process
Fallbacks
DeviceEvents DnsQueryResponse→DeviceNetworkEvents RemoteUrl: Finds connections to the host, not DNS lookups.DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields | take 5
// HUNT: DNS resolution of the ShellterLoader scriptlab.cc C2 infrastructure // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1071.001, T1573 // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a lookup of scriptlab.cc or any subdomain. Defender has no first-class DNS table, so this reads DNS events from DeviceEvents, which depends on the assumptions below. // REQUIRES: Defender for Endpoint DNS events in DeviceEvents (ActionType DnsQueryResponse) // TUNING: Any hit is high value: the domain is the campaign's C2. Pivot on DeviceId into process activity in Q1 to Q5. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. This is a hunt in this pack: run it on demand, do not schedule it as a detection. // KNOWN GAPS: A lookup answered from the local resolver cache may not generate an event. If DnsQueryResponse is not populated on your tenant, the fallback is DeviceNetworkEvents on RemoteUrl, which finds connections to the host rather than lookups. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: harness-generated; static=passed; fixtures=not executed (3 generated) DeviceEvents | where Timestamp >= ago(7d) | where ActionType == "DnsQueryResponse" | extend QueryName = tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])) | where QueryName matches regex @"(?i)(^|\.)scriptlab\.cc\.?$" | project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessFileName, QueryName | sort by Timestamp desc | take 200
Looks for: execution of the published SHA-256, SHA1, or MD5 for the sample CYFIRMA analyzed. Exact match — promote straight to a Custom IOC (Detect) per s9/s11.
Known limitations and deployment notes
- PowerQuery: The CQL also matches SHA1 dd39fafbdba994169991cea092c6428e1d3b1539 and MD5 d3cea61538aa5030e90a1d38cca762b4. They are not queried in this tab: hunt them on the CQL tab, or add arms for tgt.process.image.sha1 and tgt.process.image.md5 once a readiness test shows your tenant populates them.
- PowerQuery: If the SHA256 field is unpopulated the query returns nothing, which is indistinguishable from a clean estate.
- PowerQuery assumes: tgt.process.image.sha256 is the Process Creation hash field that the independent pySigma backend maps; whether a tenant populates it is unproven, which the readiness test shows.
- PowerQuery assumes: The hash is stored lowercase, so equality is used.
- KQL – Defender XDR: A repacked sample with a different hash is not caught; Q1 to Q5 cover the behaviour.
- KQL – Defender XDR assumes: SHA256 can be empty on some events; the SHA1 and MD5 branches cover that.
// HUNT: known ShellterLoader sample hash execution // CONF: high FP: low COST: low | REQUIRES: ProcessRollup2 #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | SHA256HashData=/^594033ed58e27b42bb1bef7e5b21eac87f0d660c7cc3d48881a2e5575e3ac811$/i OR SHA1HashData=/^dd39fafbdba994169991cea092c6428e1d3b1539$/i OR MD5HashData=/^d3cea61538aa5030e90a1d38cca762b4$/i | table([ComputerName, UserName, FileName, FilePath, CommandLine, SHA256HashData, SHA1HashData, MD5HashData], limit=200)
3 required fields · View requirements
Required telemetry
- SentinelOne Deep Visibility endpoint events
Required fields
tgt.process.image.sha256: Created process hashevent.time: Event timeevent.type: Event type
Recommended fields
tgt.process.name: Created process name
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.image.sha256 = * | columns event.time, tgt.process.name, tgt.process.image.sha256 | limit 5
// HUNT: known ShellterLoader sample hash execution // SCHEMA PROFILE: sentinelone-endpoint-ocsf // CONF: high | FP: low // EQUIVALENCE: telemetry-gap - Only the SHA-256 branch of the CQL is translated here. The CQL also matches a SHA-1 and an MD5, which this query does not, so this is a labelled partial pivot rather than an equivalent translation. // REQUIRES: SentinelOne process-creation telemetry with the image SHA256 populated // TUNING: Hash matches are high fidelity; promote to detect only after the SHA256 population is confirmed. // LOOKBACK: 30d; hashes persist, so sweep the full retention window // CONFIGURATION: No custom detection or lookup objects required. // KNOWN GAPS: The CQL also matches SHA1 dd39fafbdba994169991cea092c6428e1d3b1539 and MD5 d3cea61538aa5030e90a1d38cca762b4. They are not queried in this tab: hunt them on the CQL tab, or add arms for tgt.process.image.sha1 and tgt.process.image.md5 once a readiness test shows your tenant populates them. If the SHA256 field is unpopulated the query returns nothing, which is indistinguishable from a clean estate. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.image.sha256 = '594033ed58e27b42bb1bef7e5b21eac87f0d660c7cc3d48881a2e5575e3ac811' | columns event.time, endpoint.name, src.process.user, tgt.process.name, tgt.process.image.path, tgt.process.cmdline, tgt.process.image.sha256 | limit 200
Automated validation: harness-generated
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeSHA256: SHA-256SHA1: SHA-1MD5: MD5
Recommended fields
FileName: Created process nameFolderPath: Created process path
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, SHA256, SHA1, MD5 | take 5
// HUNT: known ShellterLoader sample hash execution // SCHEMA PROFILE: microsoft-defender-xdr // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: execution of a process whose SHA-256, SHA-1 or MD5 is the known ShellterLoader sample. Defender carries all three hashes on DeviceProcessEvents. // REQUIRES: Defender for Endpoint process-creation telemetry with image hashes (DeviceProcessEvents) // TUNING: A hash match is high confidence and needs no tuning. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. The hash is imported as an indicator (s10), so use this query to look back for past execution. // KNOWN GAPS: A repacked sample with a different hash is not caught; Q1 to Q5 cover the behaviour. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: harness-generated; static=passed; fixtures=not executed (2 generated) DeviceProcessEvents | where Timestamp >= ago(7d) | where SHA256 =~ "594033ed58e27b42bb1bef7e5b21eac87f0d660c7cc3d48881a2e5575e3ac811" or SHA1 =~ "dd39fafbdba994169991cea092c6428e1d3b1539" or MD5 =~ "d3cea61538aa5030e90a1d38cca762b4" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FolderPath, ProcessCommandLine, SHA1, SHA256 | sort by Timestamp desc | take 200
sb.scorecardresearch.com is LEGITIMATE comScore analytics infrastructure, embedded on countless benign sites. Never promote this to a block/prevent list. CYFIRMA's narrative describes ShellterLoader masquerading as, or abusing, traffic to this domain during payload retrieval. This query is context/correlation only — fire it alongside Q1–Q5 hits, never on its own.
Known limitations and deployment notes
- PowerQuery: Embedded browsers and electron apps resolve this domain legitimately and will match until excluded.
- PowerQuery assumes: The acting process on a DNS event is src.process.
- PowerQuery assumes: event.dns.request carries the same attestation caveat as the DNS query above.
- KQL – Defender XDR: A lookup answered from the local resolver cache may not generate an event.
- KQL – Defender XDR: If DnsQueryResponse is not populated on your tenant, the fallback is DeviceNetworkEvents on RemoteUrl, which finds connections to the host rather than lookups.
- KQL – Defender XDR assumes: Microsoft's DeviceEvents reference does not list ActionType values or the JSON keys inside AdditionalFields. DnsQueryResponse is attested only in community and tooling sources, and the key that holds the queried name is DnsQueryString in some of them and QueryName in others; the query reads whichever is present.
- KQL – Defender XDR assumes: Run the readiness test first: it prints the raw AdditionalFields so you can confirm the key on your tenant before trusting a zero-row result.
// HUNT: sb.scorecardresearch.com contacted by a non-browser process (payload-retrieval channel per CYFIRMA reporting) // MITRE: T1102.002 CONF: low FP: high COST: low | REQUIRES: DnsRequest // TUNING: sb.scorecardresearch.com is LEGITIMATE comScore analytics infrastructure; this is a visibility/context query only, never a block-list candidate -- correlate hits with Q1-Q5 before treating as meaningful, and exclude all known browser processes plus any approved analytics/telemetry agent #event_simpleName=DnsRequest | DomainName=/(^|\.)scorecardresearch\.com$/i | ContextBaseFileName!=/^(chrome|msedge|firefox|brave|opera|iexplore)\.exe$/i | table([ComputerName, ContextBaseFileName, DomainName, aid], limit=200)
4 required fields · View requirements
Required telemetry
- SentinelOne Deep Visibility endpoint events
Required fields
event.dns.request: DNS query namesrc.process.name: Resolving processevent.time: Event timeevent.type: Event type
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * src.process.name = * | columns event.time, event.dns.request, src.process.name | limit 5
// HUNT: sb.scorecardresearch.com contacted by a non-browser process (payload-retrieval channel per CYFIRMA reporting) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1102.002 // CONF: low | FP: high // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a legitimate analytics domain resolved by a process that is not a browser. Hunt-only because the domain is shared infrastructure. // REQUIRES: SentinelOne DNS resolution telemetry // TUNING: This domain is legitimate shared infrastructure. Treat hits as enrichment, never a block, and exclude sanctioned non-browser clients. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No custom detection or lookup objects required. // KNOWN GAPS: Embedded browsers and electron apps resolve this domain legitimately and will match until excluded. // VALIDATION LEVEL: static-reviewed event.type = 'DNS Resolved' event.dns.request contains 'scorecardresearch.com' event.dns.request matches "(^|\\.)scorecardresearch\\.com$" !(src.process.name matches "^(chrome|msedge|firefox|brave|opera|iexplore)\\.exe$") | columns event.time, endpoint.name, src.process.name, event.dns.request | limit 200
Automated validation: harness-generated
4 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: Event action typeAdditionalFields: Event details (JSON)InitiatingProcessFileName: Initiating process
Fallbacks
DeviceEvents DnsQueryResponse→DeviceNetworkEvents RemoteUrl: Finds connections to the host, not DNS lookups.DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields, InitiatingProcessFileName | take 5
// HUNT: sb.scorecardresearch.com contacted by a non-browser process (payload-retrieval channel per CYFIRMA reporting)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1102.002
// CONF: low | FP: high
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a lookup of scorecardresearch.com or any subdomain by a process that is not a mainstream browser. Reads DNS events from DeviceEvents, which depends on the assumptions below.
// REQUIRES: Defender for Endpoint DNS events in DeviceEvents (ActionType DnsQueryResponse)
// TUNING: sb.scorecardresearch.com is legitimate analytics infrastructure. This is a context query only, never a block candidate: correlate with Q1 to Q5 before treating a hit as meaningful.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required. This is a hunt in this pack: run it on demand, do not schedule it as a detection.
// KNOWN GAPS: A lookup answered from the local resolver cache may not generate an event. If DnsQueryResponse is not populated on your tenant, the fallback is DeviceNetworkEvents on RemoteUrl, which finds connections to the host rather than lookups.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: harness-generated; static=passed; fixtures=not executed (2 generated)
DeviceEvents
| where Timestamp >= ago(7d)
| where ActionType == "DnsQueryResponse"
| extend QueryName = tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"]))
| where QueryName matches regex @"(?i)(^|\.)scorecardresearch\.com\.?$"
| where InitiatingProcessFileName !in~ ("chrome.exe", "msedge.exe", "firefox.exe", "brave.exe", "opera.exe", "iexplore.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessFileName, QueryName
| sort by Timestamp desc
| take 200Detection Rules by Platform
CrowdStrike: Custom IOA
| IOA Name | Pattern | Exclusions | Deployment |
|---|---|---|---|
| LOADER — Chromium path masquerade | chrome.exe from AppData\Local\Chromium\Application | Approved portable/dev Chromium hash allowlist, if any exists in your fleet | Promote Q1 → Custom IOA (Detect, High) |
| LOADER — System32 binary masquerade | RuntimeBroker.exe / BackgroundTaskHost.exe outside System32 | None — System32 is immutable under standard builds | Promote Q3 → Custom IOA (Detect, High) |
| LOADER — known sample hash | SHA256 / SHA1 / MD5 match (s4) | None | Q7 → Custom IOC (Detect only — single-source, do not set Prevent/Critical until corroborated) |
Do not create a Custom IOA/IOC for sb.scorecardresearch.com. It is legitimate infrastructure; Q8 stays a hunt/context query only.
SentinelOne: custom detection rules
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| LOADER — Chromium path masquerade | Q1, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| LOADER — System32 binary masquerade | Q3, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
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
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| LOADER — Chromium path masquerade | Q1, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | The 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 |
| LOADER — System32 binary masquerade | Q3, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | The 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 |
| LOADER — known sample hash | Q7, KQL – Defender XDR tab | Indicator, not a rule (s10) | Import at Audit first, as the pack ships every indicator at detect unless s10 says otherwise |
Q2, Q4, Q5, Q6 and Q8 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.
Machine-Readable IOC Appendix
type,value,action,severity,expiration,description,tags sha256,594033ed58e27b42bb1bef7e5b21eac87f0d660c7cc3d48881a2e5575e3ac811,detect,high,2027-04-01,ShellterLoader sample (CYFIRMA 2026-10-01),campaign:ShellterLoader sha1,dd39fafbdba994169991cea092c6428e1d3b1539,detect,high,2027-04-01,ShellterLoader sample (CYFIRMA 2026-10-01),campaign:ShellterLoader md5,d3cea61538aa5030e90a1d38cca762b4,detect,high,2027-04-01,ShellterLoader sample (CYFIRMA 2026-10-01),campaign:ShellterLoader domain,wss.scriptlab.cc,detect,medium,2026-11-16,ShellterLoader C2 / payload-staging infrastructure (CYFIRMA 2026-10-01),campaign:ShellterLoader
indicatorType,indicatorValue,action,title,description,expirationTime,severity,recommendedActions,rbacGroups,category,mitretechniques,GenerateAlert FileSha256,594033ed58e27b42bb1bef7e5b21eac87f0d660c7cc3d48881a2e5575e3ac811,Audit,ShellterLoader sample,ShellterLoader sample (CYFIRMA 2026-10-01),2027-04-01T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,dd39fafbdba994169991cea092c6428e1d3b1539,Audit,ShellterLoader sample,ShellterLoader sample (CYFIRMA 2026-10-01),2027-04-01T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,wss.scriptlab.cc,Audit,ShellterLoader C2 / payload-staging infrastructure,ShellterLoader C2 / payload-staging infrastructure (CYFIRMA 2026-10-01),2026-11-16T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True
Column names and allowed values are from Microsoft's documented parameter table. Left out because this block maps only SHA-1, SHA-256, IPv4, domain and URL indicators: md5 1. 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).
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.
# Guardrail mutexes (single-instance check; see s7) ChromeProcessSingletonStartup! OMADM_NAMED_MUTEX # Masquerading paths / command lines (YARA strings, CYFIRMA 2026-10-01) C:\Users\<USER>\AppData\Local\Chromium\Application\chrome.exe --no-first-run --no-default-browser-check C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe --no-first-run --no-default-browser-check C:\Windows\system32\BackgroundTaskHost.exe -ServerName:BackgroundTaskHost.WebAccountProvider C:\Windows\System32\RuntimeBroker.exe -Embedding # Chromium user-data artifact mimicry ...\AppData\Local\Chromium\User Data\Crashpad\settings.dat ...\AppData\Local\Chromium\User Data\BrowserMetrics\BrowserMetrics-6AB8F3B2-122C.pma ...\AppData\Local\Chromium\User Data\lockfile ...\AppData\Local\Chromium\User Data\Variations # Technique (not CQL-queryable; Falcon on-sensor ML/IOA only -- see s7) Reflective loading / in-memory execution; memory and thread manipulation consistent with code injection into another process's context
# C2 / payload staging -- safe to hunt and block wss.scriptlab.cc wss.scriptlab.cc/api/splitChanges/850ec405 # LEGITIMATE third-party infrastructure referenced in the reporting -- DO NOT BLOCK # ShellterLoader masquerades as/abuses traffic to this domain during payload retrieval. sb.scorecardresearch.com
# Do NOT promote any indicator in this pack to Prevent or Critical until: 1. A second independent source corroborates ShellterLoader by name, hash, mutex, or C2 infrastructure (none found as of 2026-10-02) 2. Q2/Q4/Q5/Q8 have been baselined for 7-14 days in your tenant (s11) 3. Any confirmed hit has been treated as a precursor and the environment has been widened-hunted for an unknown second-stage payload (s14)
Detection Validation Gates
- Telemetry ready: confirm ProcessRollup2 is capturing
FilePathandCommandLine, and thatDnsRequestis flowing, before relying on Q1–Q8. - Benign baseline: run Q2, Q4, Q5, and Q8 for 7–14 days; catalog legitimate automation/deployment parents and any approved analytics agents; build exclusions before promoting past hunt.
- Positive tests: stage a disposable test binary named
chrome.exeunder a throwawayAppData\Local\Chromium\Applicationpath to confirm Q1 fires; launchmsedge.exe --no-first-run --no-default-browser-checkfrom a non-interactive script to confirm Q2 fires only with the parent anomaly engaged. - Single-source caveat: do not promote any indicator to Prevent/Critical until a second independent source corroborates ShellterLoader; re-run this pipeline's provenance and coverage gates on any re-hunt before promotion.
- Promotion: Q1, Q3, and Q7 → Custom IOA/IOC at Detect first; Q2/Q4/Q5 stay hunt-only until baselined; Q8 never promotes beyond hunt/context.
Hardening — Tiered & Deployable
- Import the detect-only IOC set (M1049 Antivirus/Antimalware): load the s10 Falcon CSV (hashes + scriptlab.cc) at action=detect; do not set Prevent/Critical on a single source.
- Confirm Falcon behavioral prevention is enabled (M1040 Behavior Prevention on Endpoint): verify process-injection and reflective-loading ML/IOA detections are active in your prevention policy — this is the only layer that currently covers the mutex-guardrail and injection steps (s7).
- Block the dedicated C2 domain at DNS/proxy (M1031 Network Intrusion Prevention): deny
scriptlab.ccand subdomains. Never addsb.scorecardresearch.comto this block list — it is legitimate third-party infrastructure.
- Application control deny rules (M1038 Execution Prevention): block execution of
chrome.exe/msedge.exe-named binaries from user-writableAppDatapaths, andRuntimeBroker.exe/BackgroundTaskHost.exe-named binaries from anywhere outsideSystem32/SysWOW64, via AppLocker or WDAC (CIS Microsoft Windows Benchmark application-control guidance; Microsoft Security Baseline AppLocker recommendations). - Audit SeDebugPrivilege assignment (M1026 Privileged Account Management): review and restrict which accounts/processes can acquire debug rights, as defense-in-depth against the injection step described in s7.
- Formal WDAC code-integrity policy (M1038 Execution Prevention) fleet-wide, moving beyond the targeted deny rules above to full allowlisting of signed, approved binaries.
- Reduce the phishing delivery surface (M1017 User Training): CYFIRMA's own tactical recommendations call for password resets and MFA verification on any confirmed hit — fold this into standard phishing-awareness training given the unknown second-stage payload.
- Periodic RTR sweep for the two named mutexes (⚠ best-practice, no formal benchmark): schedule a recurring Falcon Real Time Response check for
ChromeProcessSingletonStartup!/OMADM_NAMED_MUTEXand anomalous thread context on hosts previously flagged by Q1–Q5, since this layer has no CQL-queryable equivalent.
Deployable Playbooks
1 · AppLocker deny rules for masquerading binaries
Prerequisites: Application Identity service (AppIDSvc) running; GPO/AppLocker infrastructure in place; test in Audit enforcement mode before switching to Enforce.
Reboot required: No — apply with gpupdate /force and an AppIDSvc restart.
Rollback: Remove the two deny rules (or switch enforcement back to Audit) and run gpupdate /force.
<!-- AppLocker path-rule fragment: deny browser-named EXE from a user-writable Chromium path -->
<FilePathRule Id="b1d6e2b2-23b4-4b9a-9a1a-ShellterLoaderQ1" Name="Deny chrome.exe-named binary under user AppData Chromium path"
Description="Blocks masquerading chrome.exe per ShellterLoader reporting (CYFIRMA 2026-10-01)"
UserOrGroupSid="S-1-1-0" Action="Deny">
<Conditions>
<FilePathCondition Path="%LOCALAPPDATA%\Chromium\Application\chrome.exe" />
</Conditions>
</FilePathRule>
<!-- Deny RuntimeBroker.exe / BackgroundTaskHost.exe anywhere except the real System32 locations -->
<FilePathRule Id="c2e7f3c3-34c5-4c0b-9b2b-ShellterLoaderQ3" Name="Deny RuntimeBroker/BackgroundTaskHost outside System32"
Description="Blocks masquerading RuntimeBroker.exe/BackgroundTaskHost.exe per ShellterLoader reporting"
UserOrGroupSid="S-1-1-0" Action="Deny">
<Conditions>
<FilePathCondition Path="*\RuntimeBroker.exe" />
<FilePathCondition Path="*\BackgroundTaskHost.exe" />
</Conditions>
<Exceptions>
<FilePathCondition Path="%WINDIR%\System32\RuntimeBroker.exe" />
<FilePathCondition Path="%WINDIR%\SysWOW64\RuntimeBroker.exe" />
<FilePathCondition Path="%WINDIR%\System32\BackgroundTaskHost.exe" />
<FilePathCondition Path="%WINDIR%\SysWOW64\BackgroundTaskHost.exe" />
</Exceptions>
</FilePathRule>
2 · Push the detect-only IOC set via the Falcon Indicator API
Prerequisites: Falcon API client with the iocs:write scope.
Reboot required: No.
Rollback: Delete the imported indicators from Endpoint Security → IOC Management, or call the delete-indicator endpoint with the same IDs.
# PowerShell -- import the s10 hash IOCs at action=detect (never prevent, single source)
$headers = @{ Authorization = "Bearer $FalconToken"; "Content-Type" = "application/json" }
$body = @{
indicators = @(
@{ type="sha256"; value="594033ed58e27b42bb1bef7e5b21eac87f0d660c7cc3d48881a2e5575e3ac811"; action="detect"; severity="high"; platforms=@("windows") },
@{ type="sha1"; value="dd39fafbdba994169991cea092c6428e1d3b1539"; action="detect"; severity="high"; platforms=@("windows") },
@{ type="md5"; value="d3cea61538aa5030e90a1d38cca762b4"; action="detect"; severity="high"; platforms=@("windows") },
@{ type="domain"; value="wss.scriptlab.cc"; action="detect"; severity="medium"; platforms=@("windows") }
)
} | ConvertTo-Json -Depth 4
Invoke-RestMethod -Method Post -Uri "https://api.crowdstrike.com/iocs/entities/indicators/v1" -Headers $headers -Body $body
3 · Block the scriptlab.cc C2 at the proxy (Squid example)
Prerequisites: proxy/firewall admin access; deploy in log/monitor mode first to confirm no legitimate traffic references the domain.
Reboot required: No — reload the proxy configuration.
Rollback: Remove the ACL line and reload the proxy configuration.
# /etc/squid/shellterloader.acl acl shellterloader_c2 dstdomain .scriptlab.cc http_access deny shellterloader_c2 # Do NOT add sb.scorecardresearch.com here -- it is legitimate comScore infrastructure.
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-contain any host matching Q1/Q3/Q4/Q5/Q7; capture volatile memory before any reboot (reflective loading leaves minimal disk artifact) | SOC / IR | Falcon detections, memory image |
| Isolate: by platform | CrowdStrike: 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 / IR | Falcon detections, memory image |
| Eradicate | Remove the masquerading binary and any Chromium user-data artifact tree created outside a real browser install. Treat the environment as exposed to an unknown second-stage payload (the single available source does not describe it) and widen the hunt rather than closing the case on loader removal alone | IR | Removed artifacts, hunt results across Q1–Q8 |
| Hunt replay | Run the s7 RTR-based manual checks for the two named mutexes and for threads with no backing module on the affected host; expand Q6/Q8 across the environment, not just the flagged host | IR | RTR output, DNS logs |
| Recover | Rebuild hosts where a second-stage payload cannot be ruled out; re-image rather than clean where injection into RuntimeBroker.exe/BackgroundTaskHost.exe is confirmed; deploy the s13 AppLocker rules before returning the host to production | Endpoint | Rebuild records |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | CrowdStrike coverage | SentinelOne | Defender XDR |
|---|---|---|---|---|---|---|
| T1036.005 / T1218 | Masquerading as chrome/msedge/RuntimeBroker/BackgroundTaskHost | Q1, Q2, Q3, Q4, Q5 | Q1, Q3 | Good | Good, with assumptions | Good, with assumptions |
| T1071.001 / T1573 | scriptlab.cc websocket/TLS C2 | Q6 | domain IOC (s9) | Good | Good, with assumptions | Good, with assumptions |
| T1102.002 | sb.scorecardresearch.com traffic masquerade (legitimate domain, hunt-only) | Q8 | — (never promoted) | Partial — deliberately capped at hunt/context | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| (known sample) | SHA256 / SHA1 / MD5 execution | Q7 | Q7 | Good | Partial: Q7 telemetry gap | Good, with assumptions |
| T1497 | Mutex-gated sandbox/environment evasion | — | — | GAP (s7) | GAP | GAP |
| T1055 | Process injection into RuntimeBroker/BackgroundTaskHost | Q3, Q4 (masquerade precursor only) | — | Partial — precursor covered, injection itself not CQL-visible (s7) | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1129 / T1027.002 | Reflective in-memory loading / packing | — | — | GAP (s7) | GAP | GAP |
| T1564 | Chromium user-data artifact mimicry | — | — | GAP (s7 — Sysmon EID 11 suggested) | GAP | GAP |
| T1012 / T1033 / T1057 / T1082 / T1083 / T1518.001 | Generic environment/host checks | — | — | GAP — no atomic detail published; pair with existing discovery-chain hunts | GAP | GAP |
| T1185, T1485, T1486 | Listed in vendor TTP table, not corroborated by the attack-method narrative for this family | — | — | Not in scope — excluded, see s6 | Not in scope | Not in scope |
Validation: the masquerading + C2 layer is well covered and promotable at Detect. The memory/injection layer and the generic-discovery TTPs remain gaps pending either richer telemetry (RTR/Sysmon) or a second independent source. Nothing in this pack should be promoted to Prevent/Critical on single-source reporting alone.
Hunt Summary Ticket
TITLE: ShellterLoader - Windows downloader/dropper with reflective loading and process masquerade
SEVERITY: High (loader risk; unknown second-stage payload) - Confidence Medium (single source, CYFIRMA, no independent corroboration found)
SCOPE: Windows endpoints; DNS/network egress; downstream blast radius unassessed pending second-stage identification
HYPOTHESIS: ShellterLoader enforces single-instance via two named mutexes, masquerades as chrome.exe/msedge.exe/
BackgroundTaskHost.exe/RuntimeBroker.exe to blend in, reflectively loads and stages a second payload over
a scriptlab.cc websocket channel (possibly fronted through legitimate sb.scorecardresearch.com traffic),
then hands off to an unknown follow-on payload
QUERIES: Q1 Chromium path masquerade | Q2 Edge flag+parent anomaly | Q3 System32 path anomaly |
Q4 RuntimeBroker/BackgroundTaskHost parent anomaly | Q5 suppression-flag combo on renamed binary |
Q6 scriptlab.cc C2 DNS | Q7 known hash | Q8 scorecardresearch.com hunt-only (legitimate, never block)
DO FIRST: Run Q1, Q3, Q6, Q7 (lowest FP); baseline Q2/Q4/Q5/Q8 for 7-14 days before promoting
GAPS: mutex creation, reflective-load/injection memory layer, generic discovery TTPs, Chromium artifact-file
writes -- all behavioral-only, see s7/s15
ACTIONS: Import the detect-only IOC CSV (s10); do not set any indicator to Prevent/Critical pending a second
source; treat any hit as a precursor to a broader compromise, not an isolated event
OWNER: <analyst>
VERSION: v1.2 · 2026-10-09
Changelog
References
| Tier | Source | Used For | Access Date |
|---|---|---|---|
| 1 | CYFIRMA — Weekly Intelligence Report, 1 Oct 2026 | Full technical profile, attack method, IOCs, YARA rule, MITRE ATT&CK mapping | 2026-10-02 |
| Ref | MITRE ATT&CK T1036.005 — Masquerading: Match Legitimate Name or Location | Technique mapping (Q1–Q5) | 2026-10-02 |
| Ref | MITRE ATT&CK T1055 — Process Injection | Technique mapping (s7, Q3/Q4) | 2026-10-02 |
| Ref | MITRE ATT&CK T1071.001 — Application Layer Protocol: Web Protocols | Technique mapping (Q6) | 2026-10-02 |
No independent corroboration of "ShellterLoader" by this name was found as of 2026-10-02 (searched: threat name, sample hashes, named mutexes). A search for the commercial Shellter AV-evasion framework surfaced an unrelated 2025 infostealer campaign that abused a leaked license — a different tool, timeframe, and infrastructure, excluded from this pack. This pack therefore ships as single-source; see s2 and s11 for the operational implications.
Generated: 2026-10-02 · HuntPack pipeline v8.28.26 · Single-source pack (CYFIRMA only) — all Falcon-import indicators ship as action=detect.