BRONZE SANDCASTLE: Sandboxie DLL Sideloading and Modified Meterpreter Backdoor
Executive Summary
Sophos Counter Threat Unit and SophosLabs published research on 2026-10-20 on BRONZE SANDCASTLE, a threat group Sophos treats as China-based and distinct from BRONZE PRESIDENT and BRONZE ATLAS [#1]. Sophos observed victims in the Philippines, Taiwan, Afghanistan, Namibia and likely the Republic of Korea between August 2025 and August 2026, with activity concentrated in UTC+8 working hours [#1]. The group's most distinctive technical marker is Sandboxie DLL sideloading: a legitimate Sandboxie executable is placed beside a malicious sbiedll.dll, and the trusted process loads attacker code [#1].
The sideloaded DLL reads an encrypted config.ini, decodes it in memory and runs a Meterpreter-style backdoor (payload versions 1.1.5 and 1.1.7) that profiles the host, enumerates local network and accounts, and can collect keystrokes and screenshots [#1] [#2]. Operators were then seen running Windows net commands, creating Volume Shadow Copies with vssadmin.exe and copying ntds.dit, the Active Directory credential database [#1].
The highest-value defensive angle is behavioral, not file-based. Sophos states that the encrypted payloads are decoded at runtime, so static file detections may be ineffective [#1]. This pack therefore leads with host-executable-in-wrong-folder, sideload DLL staging, child processes of the hosts, the credential-theft sequence, and keeps the vendor hashes and C2 domains as a retro-hunt layer.
Defender priority: hunt Q2, Q3 and Q8 first, then Q9 and Q10 on domain controllers. If ntds.dit was copied anywhere in your estate, treat every domain credential as exposed. All shipped indicators are detect only: every hash and domain traces to Sophos alone, so none meets the two-independent-source bar for prevent.
Source Review & Web Hunter Notes
| # | Tier | Source | Key finding | Carry forward |
|---|---|---|---|---|
| 1 | T1 | Sophos CTU, "BRONZE SANDCASTLE deploys modified Meterpreter shells" (2026-10-20) | Origin of every fact: Table 1 sideload pairs, payload 1.1.5 and 1.1.7, C2 and abused services, GitHub config download, vssadmin and ntds.dit, victimology, UTC+8 | Yes |
| 2 | T2 | The Hacker News (2026-10-21) | Restates [#1]; adds the July 2024 APT41 MoonWalk sbiedll.dll sideload as context and that the GitHub account is no longer accessible | Partial |
| 3 | T2 | SecurityOnline (2026-10-23) | Restates [#1]; adds that renamed legitimate executables are frequently used | Partial |
| 4 | T2 | GBHackers (2026-10-21) | Restates [#1]; adds the aez.zip sample layout and that COFFLoader overlap does not by itself establish Cobalt Strike | Partial |
| 5 | T1 | SophosLabs IoC repository, BRONZESANDCASTLE_Meterpreter_IOCs.csv | 21 samples with MD5, SHA1 and SHA256, plus the two C2 domains | Yes |
Decisions and caveats
- Independence: [#2] [#3] [#4] re-report [#1], and [#5] is Sophos's own appendix. There is no second independent vendor, so confidence is Medium and no indicator ships at prevent.
- Different campaign, excluded: [#2] notes APT41 sideloaded a Sandboxie-signed
taskhost.exewith its ownsbiedll.dllin July 2024 to deploy MoonWalk. That is a separate campaign. None of its indicators are in this pack and the shared DLL name is treated only as a behavioral overlap. - GitHub account: Sophos names
LatonyCharnleyaWas the v1.1.7 config source and says the repository had little history [#1]; it is no longer accessible [#2]. It is recorded as context, not imported as an IOC. - Hosts without a named pair: the IoC file lists loader hashes named
CoreFoundation.dllandMSIMG32.dll[#5]. The reports do not say which host executable pairs with them, and this pack does not guess. - Sophos detection names for cross-reference: ATK/Swrort-Y, ATK/ScLoad-W, -X, -Y, -Z, Troj/Loader-JL, Troj/Loader-JP [#1].
- Library overlap note: the TTP check against published packs found only a shared tooling filename (
NvdaHelperRemote.dll) with an earlier unrelated pack. No shared hash, domain or IP, so this is not a duplicate.
Hunt Brief & Attack Chain
Hypotheses (highest fidelity first)
- H1, signature sideload: SandboxieWUAU.exe runs from, or sbiedll.dll is written to, a folder that is not a Sandboxie install directory. Q2, Q3. Confidence high.
- H2, known samples: a process or PE write carries one of the 21 vendor-listed SHA256 values. Q1. Confidence high, coverage narrow.
- H3, sideload family: the other eight host executables run from user-writable folders, or their paired DLL names appear there on few hosts. Q4, Q5. Confidence medium.
- H4, post-exploitation children: a host executable spawns shells or discovery tools. Q8. Confidence high.
- H5, C2 and tasking: lookups of the v1.1.5 C2 domains, or host processes resolving file.io, gofile.io, ably.net, ably.io or api.github.com. Q6, Q7. Confidence high for C2, medium for services.
- H6, AD database theft: shadow copy creation followed by ntds.dit copy. Q9, Q10. Confidence medium to high.
Attack chain
| Step | Behavior [source] | Telemetry (plain terms, then platforms) | Hunt angle |
|---|---|---|---|
| 1 Staging | Legitimate signed host executable, malicious DLL and encrypted config.ini placed together, sample ZIP aez.zip with javaw.exe, jli.dll, config.ini [#1] [#4] | Executable or DLL written (CrowdStrike: PeFileWritten, NewExecutableWritten. SentinelOne: File Creation. Defender: DeviceFileEvents FileCreated) | Q3, Q4. Initial delivery vector is not stated in the sources. |
| 2 Sideload | Host loads the rogue DLL from its own folder [#1] | Process creation with image path (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | Q2, Q5. Module-load telemetry for the DLL itself is not used here; see gaps. |
| 3 Decode and in-memory run | DLL reads config.ini, decodes it, runs a reflective loader and backdoor in memory [#1] | Memory and behavioral sensor verdicts (outside the CQL telemetry used here) | Gap: no query. Sophos recommends memory-based detection [#1]. |
| 4 C2 and tasking | JSON host profile to C2; contact with file.io, gofile.io, ably.net, ably.io; v1.1.7 pulls encrypted configs via the GitHub API [#1] | DNS lookup with requesting process (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceEvents DnsQueryResponse, no endpoint DNS table) | Q6, Q7 |
| 5 Discovery | Windows net commands for local network and account enumeration [#1] | Process creation with command line and parent (same sources as step 2) | Q8 |
| 6 Credential theft | vssadmin.exe shadow copy, then copy of ntds.dit [#1] | Process creation with command line (same as step 2) | Q9, Q10 |
| 7 Collection | Keylogging and screenshot capture capability [#2] | Not observable as a distinct endpoint event in the sources | Gap |
Consolidated IOC Table
All atomic values below were copied by script from the saved SophosLabs IoC snapshot. Confidence is Medium because the only source of record is Sophos. Every row ships at detect.
| Type | Value | Confidence | Action | Context |
|---|---|---|---|---|
| SHA256 | 7afd292994ff214ca4dd880c834532274c957963e9838c7fa2e4d1318af75756 | MEDIUM | detect | Loader DLL (sbiedll.dll). Sophos IoC file [#5] |
| SHA256 | b39e41be217fe2c690f75e9861cf64df52b302c66619fad608ca60a959288842 | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | 7515417e523a776e371877e868536fa1d1961826d4bc478734be993985d9df03 | MEDIUM | detect | Payload (config.ini). Sophos IoC file [#5] |
| SHA256 | ab200eda30dd1868f597ac42e7876894c5838df84605bbd4fca8dbc91c90ea28 | MEDIUM | detect | Loader DLL (libcef.dll). Sophos IoC file [#5] |
| SHA256 | dd9223c381893f493ca581e5bd35f16f778689e58fc459c1b0c39b0d33b41290 | MEDIUM | detect | Loader DLL (CoreFoundation.dll). Sophos IoC file [#5] |
| SHA256 | 95c6e9447585670b1a50551c36abe22154f6e010bfb23275fc467d2b20a423d9 | MEDIUM | detect | Loader DLL (sbiedll.dll). Sophos IoC file [#5] |
| SHA256 | 548d5add2b27ab8c2d506b81623a37f3d27a0f4e22e6fa938c6a008b70775989 | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | 592a6e74366bcd0c8a47657a88a6e81f99d2876baa6f923bb928bba4477054fc | MEDIUM | detect | Loader DLL (NvdaHelperRemote.dll). Sophos IoC file [#5] |
| SHA256 | 2332d924b1404961bc65280e782c787a4b048da7519fe73ccf4dc687b843d060 | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | 425177b18cb386f359796576e51666b7350489579550e564f51f8973b2f0979b | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | 72259376f63116d1aca64bf2ef42a5d211c1ebdb01516ef3b53778ed1347c238 | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | 2411a678e4de91451e69c27369bab4329c3cd969d4ebd851ba91dcfdba7e7db2 | MEDIUM | detect | Loader DLL (MSIMG32.dll). Sophos IoC file [#5] |
| SHA256 | fdef7b1f4c013d686bf5dbfc92f37191c04beb0dc8b53c608bb8019a8c678052 | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | e50dc9db568c272d7b019ec8e5fb1f111dd071baa4b3a00bc3c8c885ade46fbc | MEDIUM | detect | Loader DLL (snmpapi.dll). Sophos IoC file [#5] |
| SHA256 | 6c5c332428d914fd8eac0164947a70ec3d71bcd3f6cdcccb5e875dcb68ea076d | MEDIUM | detect | Loader DLL (sbiedll.dll). Sophos IoC file [#5] |
| SHA256 | 91ef27b1e83f324348ca51466ab17e2464f927b9c84758898fd7ce7ae6a6008b | MEDIUM | detect | Loader DLL (sbiedll.dll). Sophos IoC file [#5] |
| SHA256 | 437ba4b0db084c261f7843f85329b5204a2dedecdacf29b25a53a90bcf8d7d2e | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | c7f1c6cfd87e4c4f492a6da634ae6a264467aaee5a3eed14e89c2297a58e5d30 | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | c39ac4e1fe11639a9d46e026850cc3146eb809b542daf38e1a00eab11eaa1834 | MEDIUM | detect | Loader DLL (sbiedll.dll). Sophos IoC file [#5] |
| SHA256 | e404b2b9f9f203dad81bdc1ef8bfcbe4f42eb616f113a89ed504202212af1c1e | MEDIUM | detect | Loader DLL (jli.dll). Sophos IoC file [#5] |
| SHA256 | 5e2b035ae40f8eaab40792a92573171df0011c2fbed55582268a824effa7cb91 | MEDIUM | detect | Loader DLL (msvcp140.dll). Sophos IoC file [#5] |
| Domain | dc.cathaypacifice.com | MEDIUM | detect | v1.1.5 C2 server. Sophos blog [#1], IoC file [#5], echoed by [#2] [#4] |
| Domain | net.dpworldto.com | MEDIUM | detect | v1.1.5 C2 server. Sophos blog [#1], IoC file [#5], echoed by [#2] [#4] |
Hunt-only context (not imported)
| Type | Value | Action | Why not an import row |
|---|---|---|---|
| Domain | file[.]io, gofile[.]io, ably[.]net, ably[.]io | hunt | Legitimate services reported as likely tasking channels [#1]. Importing them would alert on legitimate use; Q7 keys on the process instead. |
| Host | api.github.com/repos/LatonyCharnleyaW | hunt | v1.1.7 config source, account no longer accessible [#1] [#2]. GitHub itself is legitimate; Q7 covers the API host from sideload processes. |
| File | config.ini, aez.zip | enrich | Generic names. config.ini is the encrypted payload carrier; aez.zip is a single sample's archive name [#1]. |
| Version | payload 1.1.5, 1.1.7 | enrich | Version labels from the implant, not network or file indicators [#1]. |
Affected Surface & Telemetry Matrix
| Surface | Telemetry (plain terms, then platforms) | Priority | Gap |
|---|---|---|---|
| Windows endpoints and servers running a sideload host | Process creation with path, command line, parent (CrowdStrike: ProcessRollup2, SyntheticProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | HIGH | Renamed host executables evade name-based matching |
| Folders where host and DLL are staged | Executable or DLL written (CrowdStrike: PeFileWritten, NewExecutableWritten. SentinelOne: File Creation. Defender: DeviceFileEvents) | HIGH | Config.ini is not a PE, so its write is not covered |
| DNS egress from those hosts | DNS lookup with requesting process (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceEvents, no endpoint DNS table) | MEDIUM | Defender endpoint DNS coverage is indirect; traffic that bypasses the host resolver is outside endpoint telemetry |
| Domain controllers | Process creation with command line (as above) | HIGH | Direct file access to ntds.dit without a command line is outside endpoint telemetry |
| In-memory loader and backdoor | Memory scanning and behavioral verdicts (sensor feature, not a hunt event) | HIGH | No CQL query; rely on sensor prevention policy and Sophos guidance [#1] |
ATT&CK Mapping
Only T1574.001 is named in the cited coverage [#4]. The other IDs are analyst inference from the behaviors in [#1] and are marked (inferred).
| Tactic | Technique | Behavior | Query / control |
|---|---|---|---|
| Defense Evasion, Persistence, Privilege Escalation | T1574.001 DLL Search Order Hijacking (sideloading) | Rogue sbiedll.dll and eight other DLLs beside signed hosts [#1] [#4] | Q2, Q3, Q4, Q5; Hardening 2 |
| Defense Evasion | T1036.005 Match Legitimate Name or Location (inferred) | Renamed legitimate executables, for example Start.exe [#1] | Q2, Q5 |
| Defense Evasion | T1027 Obfuscated Files or Information (inferred) | Encrypted config.ini and flattened control-flow in the DLL [#1] | Memory sensor (gap) |
| Defense Evasion, Execution | T1620 Reflective Code Loading (inferred) | Position-independent reflective loader runs the backdoor in memory [#1] | Memory sensor (gap) |
| Command and Control | T1102 Web Service (inferred) | Contact with file.io, gofile.io, ably.net, ably.io, GitHub API [#1] | Q7 |
| Command and Control | T1071.001 Web Protocols (inferred) | Host profile sent to C2 domains [#1] | Q6 |
| Discovery | T1087 Account Discovery, T1018 Remote System Discovery (inferred) | Windows net commands [#1] | Q8 |
| Collection | T1056.001 Keylogging, T1113 Screen Capture (inferred) | Payload capability [#2] | Gap |
| Credential Access | T1003.003 NTDS (inferred) | vssadmin shadow copy then copy ntds.dit [#1] | Q9, Q10; Hardening 3 |
Native Audit-Log Hunts
- Sysmon Event ID 7 (image loaded):
sbiedll.dll,jli.dll,Krita.dll,NvdaHelperRemote.dll,Libcef.dll,version.dll,msvcp140.dll,snmpapi.dllloaded from the same folder as the host and not from the product install path or System32. Look for unsigned or invalidly signed images. - Sysmon Event ID 11 (file create): DLL and
config.inicreated together in a user-writable folder, or an archive such as aez.zip extracted there [#1] [#4]. - Sysmon Event ID 22 or DNS server analytic log: queries for the two C2 domains, and for file.io, gofile.io, ably.net, ably.io from the nine host process names.
- Security 4688 with command line (needs the audit and command-line policy, Playbook step 1):
vssadmin create shadow,net user,net group,net view, and any command namingntds.dit. - Security 8222 on domain controllers: "A shadow copy was created" where audit policy provides it. Compare against backup windows.
- Proxy or firewall logs: sessions to file.io, gofile.io, ably.net, ably.io and the GitHub API from servers, or from workstation processes that are not browsers.
- Memory triage on a suspect host: dump the host process and look for a PE header in a non-image memory region, which matches Sophos's guidance on reflective loading and anomalous PE headers in memory [#1].
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.
Ten queries. Regexes match basenames through FileName, ContextBaseFileName or ParentBaseFileName; path tests use a doubled backslash inside the regex. Every event name is a real Falcon event. Set the time window with the console picker (LOOKBACK comments state the intent).
Looks for: Any process start or PE/DLL write whose SHA256 matches the 21 sample hashes in the SophosLabs IoC file (sideloaded loaders and the config.ini payload). Hash matching is brittle by design: Sophos notes the payloads are decoded at runtime, so use this as a retro-hunt, not as the main detection.
Known limitations and deployment notes
- PowerQuery: A sample that was only renamed or moved into place, or executed from a path the sensor did not hash, is not matched.
- PowerQuery assumes: tgt.process.image.sha256 and tgt.file.sha256 are populated on this tenant; both are mapped by the independent sentinel_one_pq backend but population varies, so run the readiness test first.
- PowerQuery assumes: File Creation is the closest event to a PE write; a file renamed into place appears as a different event type and is not matched.
- KQL – Defender XDR: The created-process half of the CQL hash match is not covered: a sample that only ran, without a file event the sensor recorded, is missed.
- KQL – Defender XDR: Advanced Hunting keeps 30 days; the 90d retro-hunt window of the CQL tab is not reachable here.
- KQL – Defender XDR assumes: SHA256 is populated on the file rows of this tenant; Microsoft documents it as often unpopulated, so a clean result is weak evidence until the readiness test shows rows with a value.
// HUNT: BRONZE SANDCASTLE known loader / payload SHA256 (retro-hunt) // MITRE: T1574.001, T1055 // CONF: high FP: low COST: low // REQUIRES: file hashing on process start and PE write (Falcon sensor, default) // FALSE POSITIVES: none expected; hashes are vendor-listed malicious samples // LOOKBACK: 90d (set with the console time picker) #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2|PeFileWritten|NewExecutableWritten)$/ | in(SHA256HashData, values=[ "7afd292994ff214ca4dd880c834532274c957963e9838c7fa2e4d1318af75756", "b39e41be217fe2c690f75e9861cf64df52b302c66619fad608ca60a959288842", "7515417e523a776e371877e868536fa1d1961826d4bc478734be993985d9df03", "ab200eda30dd1868f597ac42e7876894c5838df84605bbd4fca8dbc91c90ea28", "dd9223c381893f493ca581e5bd35f16f778689e58fc459c1b0c39b0d33b41290", "95c6e9447585670b1a50551c36abe22154f6e010bfb23275fc467d2b20a423d9", "548d5add2b27ab8c2d506b81623a37f3d27a0f4e22e6fa938c6a008b70775989", "592a6e74366bcd0c8a47657a88a6e81f99d2876baa6f923bb928bba4477054fc", "2332d924b1404961bc65280e782c787a4b048da7519fe73ccf4dc687b843d060", "425177b18cb386f359796576e51666b7350489579550e564f51f8973b2f0979b", "72259376f63116d1aca64bf2ef42a5d211c1ebdb01516ef3b53778ed1347c238", "2411a678e4de91451e69c27369bab4329c3cd969d4ebd851ba91dcfdba7e7db2", "fdef7b1f4c013d686bf5dbfc92f37191c04beb0dc8b53c608bb8019a8c678052", "e50dc9db568c272d7b019ec8e5fb1f111dd071baa4b3a00bc3c8c885ade46fbc", "6c5c332428d914fd8eac0164947a70ec3d71bcd3f6cdcccb5e875dcb68ea076d", "91ef27b1e83f324348ca51466ab17e2464f927b9c84758898fd7ce7ae6a6008b", "437ba4b0db084c261f7843f85329b5204a2dedecdacf29b25a53a90bcf8d7d2e", "c7f1c6cfd87e4c4f492a6da634ae6a264467aaee5a3eed14e89c2297a58e5d30", "c39ac4e1fe11639a9d46e026850cc3146eb809b542daf38e1a00eab11eaa1834", "e404b2b9f9f203dad81bdc1ef8bfcbe4f42eb616f113a89ed504202212af1c1e", "5e2b035ae40f8eaab40792a92573171df0011c2fbed55582268a824effa7cb91" ]) | table([@timestamp, aid, ComputerName, UserName, FileName, ImageFileName, TargetFileName, SHA256HashData])
4 required fields · View requirements
Required telemetry
- Process Creation
- File Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.image.sha256: Created process image hashtgt.file.sha256: Written file hash
Recommended fields
src.process.name: Creating process
Readiness test
event.type = 'Process Creation' tgt.process.image.sha256 = * | limit 5 | columns event.time, event.type, tgt.process.image.sha256, tgt.file.sha256
// HUNT: BRONZE SANDCASTLE known loader / payload SHA256 (retro-hunt)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1574.001, T1055
// CONF: high | FP: low
// FALSE POSITIVES: none expected; hashes are vendor-listed malicious samples
// EQUIVALENCE: equivalent-with-schema-assumptions - Same SHA256 retro-hunt over both populations the CQL reads: created processes (image hash on a Process Creation event) and written files (file hash on a File Creation event). in:anycase keeps the match independent of hash letter case.
// REQUIRES: SentinelOne Deep Visibility process and file telemetry with SHA256 populated on Process Creation and File Creation events
// TUNING: None needed: the hashes are vendor-listed malicious samples. Add newly reported sample hashes to both lists.
// LOOKBACK: 90d (set with the console time picker)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A sample that was only renamed or moved into place, or executed from a path the sensor did not hash, is not matched.
// VALIDATION LEVEL: static-reviewed
event.type in ('Process Creation', 'File Creation') and (tgt.process.image.sha256 in:anycase (
'7afd292994ff214ca4dd880c834532274c957963e9838c7fa2e4d1318af75756',
'b39e41be217fe2c690f75e9861cf64df52b302c66619fad608ca60a959288842',
'7515417e523a776e371877e868536fa1d1961826d4bc478734be993985d9df03',
'ab200eda30dd1868f597ac42e7876894c5838df84605bbd4fca8dbc91c90ea28',
'dd9223c381893f493ca581e5bd35f16f778689e58fc459c1b0c39b0d33b41290',
'95c6e9447585670b1a50551c36abe22154f6e010bfb23275fc467d2b20a423d9',
'548d5add2b27ab8c2d506b81623a37f3d27a0f4e22e6fa938c6a008b70775989',
'592a6e74366bcd0c8a47657a88a6e81f99d2876baa6f923bb928bba4477054fc',
'2332d924b1404961bc65280e782c787a4b048da7519fe73ccf4dc687b843d060',
'425177b18cb386f359796576e51666b7350489579550e564f51f8973b2f0979b',
'72259376f63116d1aca64bf2ef42a5d211c1ebdb01516ef3b53778ed1347c238',
'2411a678e4de91451e69c27369bab4329c3cd969d4ebd851ba91dcfdba7e7db2',
'fdef7b1f4c013d686bf5dbfc92f37191c04beb0dc8b53c608bb8019a8c678052',
'e50dc9db568c272d7b019ec8e5fb1f111dd071baa4b3a00bc3c8c885ade46fbc',
'6c5c332428d914fd8eac0164947a70ec3d71bcd3f6cdcccb5e875dcb68ea076d',
'91ef27b1e83f324348ca51466ab17e2464f927b9c84758898fd7ce7ae6a6008b',
'437ba4b0db084c261f7843f85329b5204a2dedecdacf29b25a53a90bcf8d7d2e',
'c7f1c6cfd87e4c4f492a6da634ae6a264467aaee5a3eed14e89c2297a58e5d30',
'c39ac4e1fe11639a9d46e026850cc3146eb809b542daf38e1a00eab11eaa1834',
'e404b2b9f9f203dad81bdc1ef8bfcbe4f42eb616f113a89ed504202212af1c1e',
'5e2b035ae40f8eaab40792a92573171df0011c2fbed55582268a824effa7cb91'
) or tgt.file.sha256 in:anycase (
'7afd292994ff214ca4dd880c834532274c957963e9838c7fa2e4d1318af75756',
'b39e41be217fe2c690f75e9861cf64df52b302c66619fad608ca60a959288842',
'7515417e523a776e371877e868536fa1d1961826d4bc478734be993985d9df03',
'ab200eda30dd1868f597ac42e7876894c5838df84605bbd4fca8dbc91c90ea28',
'dd9223c381893f493ca581e5bd35f16f778689e58fc459c1b0c39b0d33b41290',
'95c6e9447585670b1a50551c36abe22154f6e010bfb23275fc467d2b20a423d9',
'548d5add2b27ab8c2d506b81623a37f3d27a0f4e22e6fa938c6a008b70775989',
'592a6e74366bcd0c8a47657a88a6e81f99d2876baa6f923bb928bba4477054fc',
'2332d924b1404961bc65280e782c787a4b048da7519fe73ccf4dc687b843d060',
'425177b18cb386f359796576e51666b7350489579550e564f51f8973b2f0979b',
'72259376f63116d1aca64bf2ef42a5d211c1ebdb01516ef3b53778ed1347c238',
'2411a678e4de91451e69c27369bab4329c3cd969d4ebd851ba91dcfdba7e7db2',
'fdef7b1f4c013d686bf5dbfc92f37191c04beb0dc8b53c608bb8019a8c678052',
'e50dc9db568c272d7b019ec8e5fb1f111dd071baa4b3a00bc3c8c885ade46fbc',
'6c5c332428d914fd8eac0164947a70ec3d71bcd3f6cdcccb5e875dcb68ea076d',
'91ef27b1e83f324348ca51466ab17e2464f927b9c84758898fd7ce7ae6a6008b',
'437ba4b0db084c261f7843f85329b5204a2dedecdacf29b25a53a90bcf8d7d2e',
'c7f1c6cfd87e4c4f492a6da634ae6a264467aaee5a3eed14e89c2297a58e5d30',
'c39ac4e1fe11639a9d46e026850cc3146eb809b542daf38e1a00eab11eaa1834',
'e404b2b9f9f203dad81bdc1ef8bfcbe4f42eb616f113a89ed504202212af1c1e',
'5e2b035ae40f8eaab40792a92573171df0011c2fbed55582268a824effa7cb91'
))
| columns event.time, endpoint.name, src.process.user, event.type, src.process.name, tgt.process.image.path, tgt.process.image.sha256, tgt.file.path, tgt.file.sha256
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceFileEvents
Required fields
Timestamp: Event timeSHA256: File hash
Recommended fields
InitiatingProcessFileName: Writing process
Optional fields
FolderPath: File path. Shown for triage only.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceFileEvents | where Timestamp > ago(1d) | project Timestamp, SHA256, FileName | take 5
// HUNT: BRONZE SANDCASTLE known loader / payload SHA256 (retro-hunt)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1574.001, T1055
// CONF: high | FP: low
// FALSE POSITIVES: none expected; hashes are vendor-listed malicious samples
// EQUIVALENCE: telemetry-gap - A partial pivot: the hash list is matched against files written or touched on endpoints (DeviceFileEvents). The CQL also matches the hash of a created process; that population lives in a different table and one query reads one table.
// REQUIRES: Defender for Endpoint file telemetry (DeviceFileEvents) with SHA256 populated
// TUNING: None needed: the hashes are vendor-listed malicious samples. Add newly reported sample hashes to the list.
// LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 90d)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The created-process half of the CQL hash match is not covered: a sample that only ran, without a file event the sensor recorded, is missed. Advanced Hunting keeps 30 days; the 90d retro-hunt window of the CQL tab is not reachable here.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceFileEvents
| where Timestamp >= ago(30d)
| where SHA256 in~ (
"7afd292994ff214ca4dd880c834532274c957963e9838c7fa2e4d1318af75756",
"b39e41be217fe2c690f75e9861cf64df52b302c66619fad608ca60a959288842",
"7515417e523a776e371877e868536fa1d1961826d4bc478734be993985d9df03",
"ab200eda30dd1868f597ac42e7876894c5838df84605bbd4fca8dbc91c90ea28",
"dd9223c381893f493ca581e5bd35f16f778689e58fc459c1b0c39b0d33b41290",
"95c6e9447585670b1a50551c36abe22154f6e010bfb23275fc467d2b20a423d9",
"548d5add2b27ab8c2d506b81623a37f3d27a0f4e22e6fa938c6a008b70775989",
"592a6e74366bcd0c8a47657a88a6e81f99d2876baa6f923bb928bba4477054fc",
"2332d924b1404961bc65280e782c787a4b048da7519fe73ccf4dc687b843d060",
"425177b18cb386f359796576e51666b7350489579550e564f51f8973b2f0979b",
"72259376f63116d1aca64bf2ef42a5d211c1ebdb01516ef3b53778ed1347c238",
"2411a678e4de91451e69c27369bab4329c3cd969d4ebd851ba91dcfdba7e7db2",
"fdef7b1f4c013d686bf5dbfc92f37191c04beb0dc8b53c608bb8019a8c678052",
"e50dc9db568c272d7b019ec8e5fb1f111dd071baa4b3a00bc3c8c885ade46fbc",
"6c5c332428d914fd8eac0164947a70ec3d71bcd3f6cdcccb5e875dcb68ea076d",
"91ef27b1e83f324348ca51466ab17e2464f927b9c84758898fd7ce7ae6a6008b",
"437ba4b0db084c261f7843f85329b5204a2dedecdacf29b25a53a90bcf8d7d2e",
"c7f1c6cfd87e4c4f492a6da634ae6a264467aaee5a3eed14e89c2297a58e5d30",
"c39ac4e1fe11639a9d46e026850cc3146eb809b542daf38e1a00eab11eaa1834",
"e404b2b9f9f203dad81bdc1ef8bfcbe4f42eb616f113a89ed504202212af1c1e",
"5e2b035ae40f8eaab40792a92573171df0011c2fbed55582268a824effa7cb91"
)
| project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessAccountName, ActionType, FolderPath, FileName, SHA256, InitiatingProcessFileName
| sort by Timestamp desc
| take 200Looks for: SandboxieWUAU.exe, the host Sophos names for the signature sbiedll.dll sideload, running from a path that is not a Sandboxie or Sandboxie-Plus directory.
Known limitations and deployment notes
- PowerQuery: A process the sensor did not observe starting is not captured.
- PowerQuery assumes: tgt.process.image.path holds the full path of the created process.
- PowerQuery assumes: tgt.process.image.sha256 is shown for triage and may be unpopulated.
- 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, including the file name.
// HUNT: SandboxieWUAU.exe executing outside a Sandboxie install directory // MITRE: T1574.001, T1036.005 // CONF: high FP: low COST: low // REQUIRES: process creation with image path (Falcon sensor, default) // FALSE POSITIVES: portable or per-user Sandboxie copies in an unusual folder // LOOKBACK: 30d // NOTE: path exclusion is evadable by naming a folder Sandboxie; pair with Q3 #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^SandboxieWUAU\.exe$/i | ImageFileName!=/\\Sandboxie(-Plus)?\\/i | table([@timestamp, aid, ComputerName, UserName, ImageFileName, CommandLine, ParentBaseFileName, SHA256HashData])
4 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process nametgt.process.image.path: Created process path
Recommended fields
src.process.name: Creating process
Optional fields
tgt.process.image.sha256: Created process hash. Population varies by tenant.
Readiness test
event.type = 'Process Creation' tgt.process.image.path = * | limit 5 | columns event.time, event.type, tgt.process.name, tgt.process.image.path
// HUNT: SandboxieWUAU.exe executing outside a Sandboxie install directory // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1574.001, T1036.005 // CONF: high | FP: low // FALSE POSITIVES: portable or per-user Sandboxie copies in an unusual folder // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a Process Creation event: the created process is named SandboxieWUAU.exe and its image path has no Sandboxie or Sandboxie-Plus directory. The created process is tgt.process.*, its creator src.process.*. matches is case-insensitive, which reproduces the CQL /i intent. // REQUIRES: SentinelOne Process Creation telemetry with the created process image path // TUNING: Exclude portable or per-user Sandboxie copies by image path after a baseline review. The directory exclusion is evadable by naming a folder Sandboxie, so pair it with the sbiedll.dll card. // LOOKBACK: 30d (set with the console time picker) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A process the sensor did not observe starting is not captured. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches '^SandboxieWUAU\\.exe$' tgt.process.image.path = * !(tgt.process.image.path matches '\\\\Sandboxie(-Plus)?\\\\') | columns event.time, endpoint.name, src.process.user, tgt.process.image.path, tgt.process.cmdline, src.process.name, tgt.process.image.sha256 | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameFolderPath: Created process path
Recommended fields
InitiatingProcessFileName: Initiating process
Optional fields
SHA1: 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: SandboxieWUAU.exe executing outside a Sandboxie install directory // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1574.001, T1036.005 // CONF: high | FP: low // FALSE POSITIVES: portable or per-user Sandboxie copies in an unusual folder // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the created process is SandboxieWUAU.exe and its folder path has no Sandboxie or Sandboxie-Plus directory. contains and =~ are case-insensitive, which reproduces the CQL /i intent. The creator is InitiatingProcessFileName. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude portable or per-user Sandboxie copies by FolderPath after a baseline review. The directory exclusion is evadable by naming a folder Sandboxie, so pair it with the sbiedll.dll card. // LOOKBACK: 30d (the CQL tab uses the same window) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A process the sensor did not observe starting is not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(30d) | where FileName =~ "SandboxieWUAU.exe" | where isnotempty(FolderPath) | where not (FolderPath contains "\\Sandboxie\\" or FolderPath contains "\\Sandboxie-Plus\\") | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FolderPath, ProcessCommandLine, InitiatingProcessFileName, SHA1 | sort by Timestamp desc | take 200
Looks for: A PE named sbiedll.dll created anywhere other than a Sandboxie or Sandboxie-Plus directory: the staging step of the group's signature sideload.
Known limitations and deployment notes
- PowerQuery: A DLL that arrives by rename or move rather than creation is not captured.
- PowerQuery assumes: File Creation is the closest event to a PE write; a DLL renamed or moved into place appears as a different event type and is not matched.
- PowerQuery assumes: tgt.file.sha256 is shown for triage and may be unpopulated.
- KQL – Defender XDR: A DLL that arrives by rename is recorded with a different action type and is not captured.
- KQL – Defender XDR assumes: FolderPath holds the full path of the written file, including the file name.
- KQL – Defender XDR assumes: FileCreated is the action type recorded for a newly written file.
// HUNT: sbiedll.dll dropped outside a Sandboxie directory // MITRE: T1574.001 // CONF: high FP: low COST: low // REQUIRES: PE write telemetry (Falcon sensor, default) // FALSE POSITIVES: Sandboxie installer or updater staging into a temp folder // LOOKBACK: 30d #event_simpleName=/^(PeFileWritten|NewExecutableWritten)$/ | FileName=/^sbiedll\.dll$/i | TargetFileName!=/\\Sandboxie(-Plus)?\\/i | table([@timestamp, aid, ComputerName, UserName, TargetFileName, SHA256HashData, ContextBaseFileName])
3 required fields · View requirements
Required telemetry
- File Creation
Required fields
event.time: Event timeevent.type: Event typetgt.file.path: Written file path
Recommended fields
src.process.name: Writing process
Optional fields
tgt.file.sha256: Written file hash. Population varies by tenant.
Readiness test
event.type = 'File Creation' tgt.file.path = * | limit 5 | columns event.time, event.type, tgt.file.path
// HUNT: sbiedll.dll dropped outside a Sandboxie directory // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1574.001 // CONF: high | FP: low // FALSE POSITIVES: Sandboxie installer or updater staging into a temp folder // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a File Creation event: the written file is named sbiedll.dll and its path has no Sandboxie or Sandboxie-Plus directory. The writer is the acting process, src.process.*, on a non-process event. // REQUIRES: SentinelOne File Creation telemetry with the written file path // TUNING: Exclude Sandboxie installer or updater staging folders by path after a baseline review. // LOOKBACK: 30d (set with the console time picker) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A DLL that arrives by rename or move rather than creation is not captured. // VALIDATION LEVEL: static-reviewed event.type = 'File Creation' tgt.file.path matches '(^|\\\\)sbiedll\\.dll$' !(tgt.file.path matches '\\\\Sandboxie(-Plus)?\\\\') | columns event.time, endpoint.name, src.process.user, tgt.file.path, tgt.file.sha256, src.process.name | limit 200
Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceFileEvents
Required fields
Timestamp: Event timeActionType: Action typeFileName: Written file nameFolderPath: Written file path
Recommended fields
InitiatingProcessFileName: Writing process
Optional fields
SHA1: Hash. SHA256 is often unpopulated; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceFileEvents | where Timestamp > ago(1d) | project Timestamp, ActionType, FileName, FolderPath | take 5
// HUNT: sbiedll.dll dropped outside a Sandboxie directory // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1574.001 // CONF: high | FP: low // FALSE POSITIVES: Sandboxie installer or updater staging into a temp folder // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on file creation events: the file is named sbiedll.dll and its folder path has no Sandboxie or Sandboxie-Plus directory. The CQL reads PE write telemetry; DeviceFileEvents with FileCreated covers every file type, so the name predicate does the narrowing. // REQUIRES: Defender for Endpoint file telemetry (DeviceFileEvents) // TUNING: Exclude Sandboxie installer or updater staging folders by FolderPath after a baseline review. // LOOKBACK: 30d (the CQL tab uses the same window) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A DLL that arrives by rename is recorded with a different action type and is not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceFileEvents | where Timestamp >= ago(30d) | where ActionType == "FileCreated" | where FileName =~ "sbiedll.dll" | where not (FolderPath contains "\\Sandboxie\\" or FolderPath contains "\\Sandboxie-Plus\\") | project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessAccountName, FolderPath, SHA1, SHA256, InitiatingProcessFileName | sort by Timestamp desc | take 200
Looks for: DLL names from Sophos Table 1 (jli, Krita, NvdaHelperRemote, Libcef, Version, msvcp140, snmpapi) plus CoreFoundation and MSIMG32 from the IoC file, written under user-writable folders and seen on three or fewer hosts. Rarity stacking cuts the noise from legitimate apps that ship the same DLL names. FP: Electron and Chromium apps legitimately carry libcef.dll and msvcp140.dll under AppData; per-user Java, Krita and LINE installs carry jli.dll, Krita.dll and msvcp140.dll. Exclude known application directories listed in the TUNING line.
Known limitations and deployment notes
- PowerQuery: Only one sample host name is shown per row instead of up to five.
- PowerQuery: A DLL that arrives by rename or move rather than creation is not captured.
- PowerQuery assumes: agent.uuid is populated and stands in for the distinct host count; estimate_distinct is approximate on large result sets.
- PowerQuery assumes: File Creation is the closest event to a PE write; a DLL renamed into place is not matched.
- KQL – Defender XDR: A DLL that arrives by rename is recorded with a different action type and is not captured.
- KQL – Defender XDR assumes: FolderPath holds the full path of the written file, including the file name.
- KQL – Defender XDR assumes: dcount is an estimate; the CQL counts distinct agents exactly.
// HUNT: rare sideload-pair DLL names in user-writable folders (rarity stack) // MITRE: T1574.001 // CONF: medium FP: medium COST: medium // REQUIRES: PE write telemetry (Falcon sensor, default) // FALSE POSITIVES: per-user installs of Java, Krita, NVDA, LINE and Chromium-embedded apps // TUNING: exclude your sanctioned app folders, e.g. add | TargetFileName!=/\\AppData\\Local\\Programs\\Krita\\/i // TUNING: raise the host threshold only after reviewing the stacked output once // LOOKBACK: 30d #event_simpleName=/^(PeFileWritten|NewExecutableWritten)$/ | FileName=/^(jli|krita|nvdahelperremote|libcef|version|msvcp140|snmpapi|corefoundation|msimg32)\.dll$/i | TargetFileName=/\\(ProgramData|Users\\Public|Windows\\Temp|AppData|Perflogs)\\/i | groupBy([FileName, TargetFileName], function=[count(aid, distinct=true, as=Hosts), min(@timestamp, as=FirstSeen), collect(ComputerName, limit=5)], limit=500) | Hosts < 4 | sort(Hosts, order=asc, limit=200)
4 required fields · View requirements
Required telemetry
- File Creation
Required fields
event.time: Event timeevent.type: Event typetgt.file.path: Written file pathagent.uuid: Endpoint identifier
Recommended fields
endpoint.name: Host name
Fallbacks
agent.uuid→endpoint.name: Counts host names instead of agents; renamed hosts count twice.
Readiness test
event.type = 'File Creation' tgt.file.path = * agent.uuid = * | limit 5 | columns event.time, event.type, tgt.file.path, agent.uuid
// HUNT: rare sideload-pair DLL names in user-writable folders (rarity stack) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1574.001 // CONF: medium | FP: medium // FALSE POSITIVES: per-user installs of Java, Krita, NVDA, LINE and Chromium-embedded apps // EQUIVALENCE: approximate-analytic - Same rarity stack: sideload-pair DLL names written under user-writable folders, grouped by written path, kept when fewer than 4 hosts wrote it. The CQL collects up to 5 host names per row; PowerQuery shows one sample host name, and distinct hosts are an estimate. // REQUIRES: SentinelOne File Creation telemetry with the written file path and a stable endpoint identifier // TUNING: Exclude your sanctioned app folders by path, for example a per-user Krita install, after reviewing the stacked output once. Raise the host threshold only after that review. // LOOKBACK: 30d (set with the console time picker) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Only one sample host name is shown per row instead of up to five. A DLL that arrives by rename or move rather than creation is not captured. // VALIDATION LEVEL: static-reviewed event.type = 'File Creation' tgt.file.path matches '\\\\(jli|krita|nvdahelperremote|libcef|version|msvcp140|snmpapi|corefoundation|msimg32)\\.dll$' tgt.file.path matches '\\\\(ProgramData|Users\\\\Public|Windows\\\\Temp|AppData|Perflogs)\\\\' | group hosts=estimate_distinct(agent.uuid), first_seen=min(event.time), sample_host=any(endpoint.name) by tgt.file.path | filter hosts < 4 | sort +hosts | limit 200
Automated validation: static-passed
5 required fields · View requirements
Required telemetry
- DeviceFileEvents
Required fields
Timestamp: Event timeActionType: Action typeFileName: Written file nameFolderPath: Written file pathDeviceId: Device identifier
Recommended fields
DeviceName: Device name
Fallbacks
DeviceId→DeviceName: Counts names instead of devices; renamed devices count twice.
Readiness test
DeviceFileEvents | where Timestamp > ago(1d) | project Timestamp, ActionType, FileName, FolderPath, DeviceId | take 5
// HUNT: rare sideload-pair DLL names in user-writable folders (rarity stack)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1574.001
// CONF: medium | FP: medium
// FALSE POSITIVES: per-user installs of Java, Krita, NVDA, LINE and Chromium-embedded apps
// EQUIVALENCE: equivalent-with-schema-assumptions - Same rarity stack on file creation events: sideload-pair DLL names under user-writable folders, grouped by name and path, kept when fewer than 4 devices wrote it. contains and in~ are case-insensitive, which reproduces the CQL /i intent.
// REQUIRES: Defender for Endpoint file telemetry (DeviceFileEvents)
// TUNING: Exclude your sanctioned app folders by FolderPath, for example a per-user Krita install, after reviewing the stacked output once. Raise the host threshold only after that review.
// LOOKBACK: 30d (the CQL tab uses the same window)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A DLL that arrives by rename is recorded with a different action type and is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceFileEvents
| where Timestamp >= ago(30d)
| where ActionType == "FileCreated"
| where FileName in~ ("jli.dll", "krita.dll", "nvdahelperremote.dll", "libcef.dll", "version.dll", "msvcp140.dll", "snmpapi.dll", "corefoundation.dll", "msimg32.dll")
| where FolderPath contains "\\ProgramData\\" or FolderPath contains "\\Users\\Public\\" or FolderPath contains "\\Windows\\Temp\\" or FolderPath contains "\\AppData\\" or FolderPath contains "\\Perflogs\\"
| summarize Hosts = dcount(DeviceId), FirstSeen = min(Timestamp), SampleHosts = make_set(DeviceName, 5) by FileName, FolderPath
| where Hosts < 4
| sort by Hosts asc
| take 200Looks for: Any of the nine legitimate host executables in Sophos Table 1 (Sandboxie WUAU and renamed Start.exe, javaw, Krita, NvdaHelper, Jcef_helper, Vmmap, LineAppMgr, bginfo64) started from ProgramData, Public, Temp, AppData, Downloads or the Recycle Bin. Sophos says renamed copies are common, so this catches the unrenamed ones and is a known partial. FP: admins run Vmmap and bginfo64 from Downloads; Start.exe is a generic name; per-user Java and Krita installs live under AppData. Exclude by path and by signer hash baseline.
Known limitations and deployment notes
- PowerQuery: A renamed host executable is not matched by name.
- PowerQuery assumes: tgt.process.image.path holds the full path of the created process.
- PowerQuery assumes: tgt.process.image.sha256 is shown for triage and may be unpopulated.
- KQL – Defender XDR: A renamed host executable is not matched by name.
- KQL – Defender XDR assumes: FolderPath holds the full image path of the created process, including the file name.
// HUNT: sideload host executable launched from a user-writable folder // MITRE: T1574.001, T1036.005 // CONF: medium FP: medium COST: low // REQUIRES: process creation with image path (Falcon sensor, default) // FALSE POSITIVES: admin tools run from Downloads, per-user app installs, generic Start.exe // TUNING: exclude sanctioned per-user installs, e.g. | ImageFileName!=/\\AppData\\Local\\Programs\\/i // TUNING: baseline the SHA256 of your own Vmmap.exe and bginfo64.exe and exclude them with !in(SHA256HashData, values=[...]) // LOOKBACK: 30d // GAP: renamed host executables are not matched by name; see Coverage Map #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(javaw|Krita|NvdaHelper|Jcef_helper|Vmmap|LineAppMgr|bginfo64|SandboxieWUAU|Start)\.exe$/i | ImageFileName=/\\(ProgramData|Users\\Public|Windows\\Temp|AppData\\Local\\Temp|Downloads|Perflogs|\$Recycle\.Bin)\\/i | table([@timestamp, aid, ComputerName, UserName, ImageFileName, CommandLine, ParentBaseFileName, SHA256HashData])
4 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process nametgt.process.image.path: Created process path
Recommended fields
src.process.name: Creating process
Optional fields
tgt.process.image.sha256: Created process hash. Population varies by tenant.
Readiness test
event.type = 'Process Creation' tgt.process.image.path = * | limit 5 | columns event.time, event.type, tgt.process.name, tgt.process.image.path
// HUNT: sideload host executable launched from a user-writable folder // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1574.001, T1036.005 // CONF: medium | FP: medium // FALSE POSITIVES: admin tools run from Downloads, per-user app installs, generic Start.exe // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a Process Creation event: the created process is one of the sideload host executables and its image path is under a user-writable folder. The created process is tgt.process.*. matches is case-insensitive, which reproduces the CQL /i intent. // REQUIRES: SentinelOne Process Creation telemetry with the created process image path // TUNING: Exclude sanctioned per-user installs by image path, for example under AppData Local Programs. Baseline the SHA256 of your own Vmmap.exe and bginfo64.exe and exclude them with a negated in list on tgt.process.image.sha256. // LOOKBACK: 30d (set with the console time picker) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed host executable is not matched by name. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches '^(javaw|Krita|NvdaHelper|Jcef_helper|Vmmap|LineAppMgr|bginfo64|SandboxieWUAU|Start)\\.exe$' tgt.process.image.path matches '\\\\(ProgramData|Users\\\\Public|Windows\\\\Temp|AppData\\\\Local\\\\Temp|Downloads|Perflogs|[$]Recycle\\.Bin)\\\\' | columns event.time, endpoint.name, src.process.user, tgt.process.image.path, tgt.process.cmdline, src.process.name, tgt.process.image.sha256 | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameFolderPath: Created process path
Recommended fields
InitiatingProcessFileName: Initiating process
Optional fields
SHA1: 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: sideload host executable launched from a user-writable folder
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1574.001, T1036.005
// CONF: medium | FP: medium
// FALSE POSITIVES: admin tools run from Downloads, per-user app installs, generic Start.exe
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the created process is one of the sideload host executables and its folder path is under a user-writable folder. in~ and contains are case-insensitive, which reproduces the CQL /i intent. The creator is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude sanctioned per-user installs by FolderPath, for example under AppData Local Programs. Baseline the SHA1 of your own Vmmap.exe and bginfo64.exe and exclude them.
// LOOKBACK: 30d (the CQL tab uses the same window)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A renamed host executable is not matched by name.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where FileName in~ ("javaw.exe", "Krita.exe", "NvdaHelper.exe", "Jcef_helper.exe", "Vmmap.exe", "LineAppMgr.exe", "bginfo64.exe", "SandboxieWUAU.exe", "Start.exe")
| where FolderPath contains "\\ProgramData\\" or FolderPath contains "\\Users\\Public\\" or FolderPath contains "\\Windows\\Temp\\" or FolderPath contains "\\AppData\\Local\\Temp\\" or FolderPath contains "\\Downloads\\" or FolderPath contains "\\Perflogs\\" or FolderPath contains "\\$Recycle.Bin\\"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FolderPath, ProcessCommandLine, InitiatingProcessFileName, SHA1
| sort by Timestamp desc
| take 200Looks for: DNS requests for the two C2 domains Sophos attributes to payload version 1.1.5, with the requesting process name for pivoting.
Known limitations and deployment notes
- PowerQuery: A lookup made through a resolver the sensor does not see, such as DNS over HTTPS from a browser, is not captured.
- PowerQuery assumes: The looked-up name is in event.dns.request. Some tenants populate dns.request instead; the readiness test shows which one carries values.
- KQL – Defender XDR: Advanced Hunting keeps 30 days; the 90d window of the CQL tab is not reachable here.
- KQL – Defender XDR: A lookup made through a resolver the sensor does not see is not captured.
- KQL – Defender XDR assumes: DnsQueryResponse is recorded on this tenant, and AdditionalFields carries the name under DnsQueryString or QueryName; the readiness test prints both so a reader can see which key is populated.
// HUNT: BRONZE SANDCASTLE v1.1.5 C2 domain lookups // MITRE: T1071.001, T1102 // CONF: high FP: low COST: low // REQUIRES: DNS request telemetry with process context (Falcon sensor, default) // FALSE POSITIVES: none expected; lookalike domains registered by the actor // LOOKBACK: 90d #event_simpleName=DnsRequest | DomainName=/(^|\.)(cathaypacifice\.com|dpworldto\.com)$/i | table([@timestamp, aid, ComputerName, UserName, DomainName, ContextBaseFileName, ContextProcessId_decimal])
3 required fields · View requirements
Required telemetry
- DNS Resolved
Required fields
event.time: Event timeevent.type: Event typeevent.dns.request: Looked-up name
Recommended fields
src.process.name: Resolving process
Fallbacks
event.dns.request→dns.request: Same value under the older field name; swap it in if only that one is populated.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * | limit 5 | columns event.time, event.type, event.dns.request, src.process.name
// HUNT: BRONZE SANDCASTLE v1.1.5 C2 domain lookups
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1071.001, T1102
// CONF: high | FP: low
// FALSE POSITIVES: none expected; lookalike domains registered by the actor
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a DNS Resolved event: the looked-up name is either C2 domain or any subdomain of it. The explicit list matches the apex name and the matches clause adds subdomains, which reproduces the CQL boundary anchored suffix match. The resolving process is the acting process, src.process.*.
// REQUIRES: SentinelOne DNS Resolved telemetry with the process context
// TUNING: None needed: the domains are actor-registered lookalikes.
// LOOKBACK: 90d (set with the console time picker)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A lookup made through a resolver the sensor does not see, such as DNS over HTTPS from a browser, is not captured.
// VALIDATION LEVEL: static-reviewed
event.type = 'DNS Resolved' and (event.dns.request in:anycase ('cathaypacifice.com', 'dpworldto.com') or event.dns.request matches '\\.(cathaypacifice\\.com|dpworldto\\.com)$')
| columns event.time, endpoint.name, src.process.user, event.dns.request, src.process.name, src.process.pid
| limit 200Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: Action typeAdditionalFields: DNS name container
Recommended fields
InitiatingProcessFileName: Initiating process
Fallbacks
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: BRONZE SANDCASTLE v1.1.5 C2 domain lookups // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1071.001, T1102 // CONF: high | FP: low // FALSE POSITIVES: none expected; lookalike domains registered by the actor // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on endpoint DNS responses: the looked-up name is either C2 domain or any subdomain of it. DnsQueryResponse events on DeviceEvents carry the name inside AdditionalFields, read here by bracket access. =~ and endswith with a leading dot reproduce the CQL boundary anchored suffix match. // REQUIRES: Defender for Endpoint DnsQueryResponse events (DeviceEvents) // TUNING: None needed: the domains are actor-registered lookalikes. // LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 90d) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Advanced Hunting keeps 30 days; the 90d window of the CQL tab is not reachable here. A lookup made through a resolver the sensor does not see is not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceEvents | where Timestamp >= ago(30d) | where ActionType == "DnsQueryResponse" | extend DnsName = tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])) | where DnsName =~ "cathaypacifice.com" or DnsName =~ "dpworldto.com" or DnsName endswith ".cathaypacifice.com" or DnsName endswith ".dpworldto.com" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, DnsName, InitiatingProcessFileName, InitiatingProcessId | sort by Timestamp desc | take 200
Looks for: A sideload host process resolving file.io, gofile.io, ably.net, ably.io (reported as likely tasking channels) or api.github.com (v1.1.7 config download). The services are legitimate, so the signal is the process: none of these hosts normally talks to them. FP: javaw.exe can legitimately reach api.github.com for Java applications; Krita or LINE auto-update checks are not expected to hit these domains.
Known limitations and deployment notes
- PowerQuery: A lookup made through a resolver the sensor does not see is not captured, and a renamed host executable is not matched by name.
- PowerQuery assumes: The looked-up name is in event.dns.request. Some tenants populate dns.request instead; the readiness test shows which one carries values.
- KQL – Defender XDR: A lookup made through a resolver the sensor does not see is not captured, and a renamed host executable is not matched by name.
- KQL – Defender XDR assumes: DnsQueryResponse is recorded on this tenant, and AdditionalFields carries the name under DnsQueryString or QueryName; the readiness test prints both so a reader can see which key is populated.
// HUNT: sideload host processes contacting abused file-sharing, messaging and GitHub API services // MITRE: T1102, T1567, T1105 // CONF: medium FP: medium COST: low // REQUIRES: DNS request telemetry with process context (Falcon sensor, default) // FALSE POSITIVES: Java applications that call the GitHub API from javaw.exe // TUNING: exclude sanctioned Java apps, e.g. | !(ContextBaseFileName=/^javaw\.exe$/i DomainName=/^api\.github\.com$/i) // LOOKBACK: 30d #event_simpleName=DnsRequest | DomainName=/(^|\.)(file\.io|gofile\.io|ably\.net|ably\.io|api\.github\.com)$/i | ContextBaseFileName=/^(javaw|Krita|NvdaHelper|Jcef_helper|Vmmap|LineAppMgr|bginfo64|SandboxieWUAU|Start)\.exe$/i | table([@timestamp, aid, ComputerName, UserName, DomainName, ContextBaseFileName, ContextProcessId_decimal])
4 required fields · View requirements
Required telemetry
- DNS Resolved
Required fields
event.time: Event timeevent.type: Event typeevent.dns.request: Looked-up namesrc.process.name: Resolving process name
Fallbacks
event.dns.request→dns.request: Same value under the older field name; swap it in if only that one is populated.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * src.process.name = * | limit 5 | columns event.time, event.type, event.dns.request, src.process.name
// HUNT: sideload host processes contacting abused file-sharing, messaging and GitHub API services
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1102, T1567, T1105
// CONF: medium | FP: medium
// FALSE POSITIVES: Java applications that call the GitHub API from javaw.exe
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a DNS Resolved event: the looked-up name is one of the abused service domains or a subdomain, and the resolving process is one of the sideload host executables. The explicit list matches apex names and the matches clause adds subdomains. The resolving process is the acting process, src.process.*.
// REQUIRES: SentinelOne DNS Resolved telemetry with the process context
// TUNING: Exclude sanctioned Java applications, for example javaw.exe resolving api.github.com, by negating that process and name pair.
// LOOKBACK: 30d (set with the console time picker)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A lookup made through a resolver the sensor does not see is not captured, and a renamed host executable is not matched by name.
// VALIDATION LEVEL: static-reviewed
event.type = 'DNS Resolved' and (event.dns.request in:anycase ('file.io', 'gofile.io', 'ably.net', 'ably.io', 'api.github.com') or event.dns.request matches '\\.(file\\.io|gofile\\.io|ably\\.net|ably\\.io|api\\.github\\.com)$') and src.process.name matches '^(javaw|Krita|NvdaHelper|Jcef_helper|Vmmap|LineAppMgr|bginfo64|SandboxieWUAU|Start)\\.exe$'
| columns event.time, endpoint.name, src.process.user, event.dns.request, src.process.name, src.process.pid
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: Action typeAdditionalFields: DNS name containerInitiatingProcessFileName: Initiating process
Fallbacks
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: sideload host processes contacting abused file-sharing, messaging and GitHub API services
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1102, T1567, T1105
// CONF: medium | FP: medium
// FALSE POSITIVES: Java applications that call the GitHub API from javaw.exe
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on endpoint DNS responses: the looked-up name is one of the abused service domains or a subdomain, and the initiating process is one of the sideload host executables. DnsQueryResponse events on DeviceEvents carry the name inside AdditionalFields, read here by bracket access.
// REQUIRES: Defender for Endpoint DnsQueryResponse events (DeviceEvents)
// TUNING: Exclude sanctioned Java applications, for example javaw.exe resolving api.github.com, by negating that process and name pair.
// LOOKBACK: 30d (the CQL tab uses the same window)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A lookup made through a resolver the sensor does not see is not captured, and a renamed host executable is not matched by name.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceEvents
| where Timestamp >= ago(30d)
| where ActionType == "DnsQueryResponse"
| where InitiatingProcessFileName in~ ("javaw.exe", "Krita.exe", "NvdaHelper.exe", "Jcef_helper.exe", "Vmmap.exe", "LineAppMgr.exe", "bginfo64.exe", "SandboxieWUAU.exe", "Start.exe")
| extend DnsName = tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"]))
| where DnsName in~ ("file.io", "gofile.io", "ably.net", "ably.io", "api.github.com") or DnsName endswith ".file.io" or DnsName endswith ".gofile.io" or DnsName endswith ".ably.net" or DnsName endswith ".ably.io" or DnsName endswith ".api.github.com"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, DnsName, InitiatingProcessFileName, InitiatingProcessId
| sort by Timestamp desc
| take 200Looks for: A shell or discovery tool spawned by one of the nine host executables. Sophos documents Windows net commands for enumeration and vssadmin before ntds.dit theft; a signed Krita, NVDA or Sandboxie binary has no reason to spawn them. FP: javaw.exe launching cmd.exe is normal for some Java applications, and Start.exe is a generic name. Restrict javaw to the discovery tools, or exclude by the application's working directory.
Known limitations and deployment notes
- PowerQuery: A renamed host executable is not matched by name, and a child launched through a grandchild is not matched.
- PowerQuery assumes: src.process.name is the creator of the new process on a Process Creation event, as the field model attests.
- KQL – Defender XDR: A renamed host executable is not matched by name, and a child launched through a grandchild is not matched.
- KQL – Defender XDR assumes: InitiatingProcessFileName is the direct creator of the process on the row.
// HUNT: shell and discovery tools spawned by sideload host executables // MITRE: T1087, T1018, T1003.003, T1574.001 // CONF: high FP: medium COST: low // REQUIRES: process creation with parent name (Falcon sensor, default) // FALSE POSITIVES: Java applications that shell out, generic Start.exe // TUNING: exclude a known-good Java app with | !(ParentBaseFileName=/^javaw\.exe$/i FileName=/^cmd\.exe$/i) // LOOKBACK: 30d #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ParentBaseFileName=/^(javaw|Krita|NvdaHelper|Jcef_helper|Vmmap|LineAppMgr|bginfo64|SandboxieWUAU|Start)\.exe$/i | FileName=/^(cmd|powershell|net|net1|vssadmin|whoami|ipconfig|nltest|tasklist|systeminfo|esentutl|ntdsutil)\.exe$/i | table([@timestamp, aid, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine, ImageFileName])
4 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typesrc.process.name: Creating process nametgt.process.name: Created process name
Recommended fields
tgt.process.cmdline: Created command line
Readiness test
event.type = 'Process Creation' tgt.process.name = * src.process.name = * | limit 5 | columns event.time, event.type, src.process.name, tgt.process.name
// HUNT: shell and discovery tools spawned by sideload host executables // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1087, T1018, T1003.003, T1574.001 // CONF: high | FP: medium // FALSE POSITIVES: Java applications that shell out, generic Start.exe // EQUIVALENCE: equivalent-with-schema-assumptions - Same lineage predicate on a Process Creation event: the creator is one of the sideload host executables and the created process is a shell or discovery tool. On Process Creation the creator is src.process.* and the created process is tgt.process.*. matches is case-insensitive, which reproduces the CQL /i intent. // REQUIRES: SentinelOne Process Creation telemetry with the creating process name // TUNING: Exclude a known-good Java application by negating the javaw.exe creator and cmd.exe child pair after a baseline review. // LOOKBACK: 30d (set with the console time picker) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed host executable is not matched by name, and a child launched through a grandchild is not matched. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' src.process.name matches '^(javaw|Krita|NvdaHelper|Jcef_helper|Vmmap|LineAppMgr|bginfo64|SandboxieWUAU|Start)\\.exe$' tgt.process.name matches '^(cmd|powershell|net|net1|vssadmin|whoami|ipconfig|nltest|tasklist|systeminfo|esentutl|ntdsutil)\\.exe$' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline, tgt.process.image.path | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeInitiatingProcessFileName: Creating processFileName: Created process name
Recommended fields
ProcessCommandLine: Created command line
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, InitiatingProcessFileName, FileName | take 5
// HUNT: shell and discovery tools spawned by sideload host executables
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1087, T1018, T1003.003, T1574.001
// CONF: high | FP: medium
// FALSE POSITIVES: Java applications that shell out, generic Start.exe
// EQUIVALENCE: equivalent-with-schema-assumptions - Same lineage predicate: the creator is one of the sideload host executables and the created process is a shell or discovery tool. The creator is InitiatingProcessFileName and the created process is FileName. in~ is case-insensitive, which reproduces the CQL /i intent.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude a known-good Java application by negating the javaw.exe creator and cmd.exe child pair after a baseline review.
// LOOKBACK: 30d (the CQL tab uses the same window)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A renamed host executable is not matched by name, and a child launched through a grandchild is not matched.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where InitiatingProcessFileName in~ ("javaw.exe", "Krita.exe", "NvdaHelper.exe", "Jcef_helper.exe", "Vmmap.exe", "LineAppMgr.exe", "bginfo64.exe", "SandboxieWUAU.exe", "Start.exe")
| where FileName in~ ("cmd.exe", "powershell.exe", "net.exe", "net1.exe", "vssadmin.exe", "whoami.exe", "ipconfig.exe", "nltest.exe", "tasklist.exe", "systeminfo.exe", "esentutl.exe", "ntdsutil.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine, FolderPath
| sort by Timestamp desc
| take 200Looks for: vssadmin.exe creating a Volume Shadow Copy, the step Sophos reports before ntds.dit is copied. Most useful on domain controllers, where it should be rare outside backup windows. FP: backup agents and snapshot jobs call vssadmin create shadow on a schedule. Exclude the backup service account and the scheduled parent process.
Known limitations and deployment notes
- PowerQuery: Shadow copies created through WMI or the VSS API without vssadmin.exe are not captured.
- PowerQuery assumes: src.process.user is the account of the creating process and stands in for the user that ran vssadmin.exe.
- KQL – Defender XDR: Shadow copies created through WMI or the VSS API without vssadmin.exe are not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: vssadmin create shadow (precursor to ntds.dit copy) // MITRE: T1003.003, T1490 // CONF: medium FP: medium COST: low // REQUIRES: process creation with command line (Falcon sensor, default) // FALSE POSITIVES: backup and snapshot software, admin maintenance // TUNING: exclude the backup service account, e.g. | UserName!=/^svc-backup$/i // TUNING: scope to domain controllers by hostname pattern once your DC naming is known // LOOKBACK: 30d #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^vssadmin\.exe$/i | CommandLine=/create\s+shadow/i | table([@timestamp, aid, ComputerName, UserName, CommandLine, ParentBaseFileName])
4 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process nametgt.process.cmdline: Created command line
Recommended fields
src.process.name: Creating process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, tgt.process.name, tgt.process.cmdline
// HUNT: vssadmin create shadow (precursor to ntds.dit copy) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1003.003, T1490 // CONF: medium | FP: medium // FALSE POSITIVES: backup and snapshot software, admin maintenance // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a Process Creation event: the created process is vssadmin.exe and its command line contains create followed by whitespace and shadow. The created process is tgt.process.*. matches is case-insensitive, which reproduces the CQL /i intent. // REQUIRES: SentinelOne Process Creation telemetry with the created process command line // TUNING: Exclude the backup service account by src.process.user, and scope to domain controllers by host name once your naming is known. // LOOKBACK: 30d (set with the console time picker) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Shadow copies created through WMI or the VSS API without vssadmin.exe are not captured. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches '^vssadmin\\.exe$' tgt.process.cmdline matches 'create\\s+shadow' | columns event.time, endpoint.name, src.process.user, tgt.process.cmdline, src.process.name | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: Created command line
Recommended fields
InitiatingProcessFileName: Initiating process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, ProcessCommandLine | take 5
// HUNT: vssadmin create shadow (precursor to ntds.dit copy) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1003.003, T1490 // CONF: medium | FP: medium // FALSE POSITIVES: backup and snapshot software, admin maintenance // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the created process is vssadmin.exe and its command line matches create, whitespace, shadow. The case-insensitive regex prefix reproduces the CQL /i intent. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude the backup service account by AccountName, and scope to domain controllers by DeviceName once your naming is known. // LOOKBACK: 30d (the CQL tab uses the same window) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Shadow copies created through WMI or the VSS API without vssadmin.exe are not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(30d) | where FileName =~ "vssadmin.exe" | where ProcessCommandLine matches regex @"(?i)create\\s+shadow" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp desc | take 200
Looks for: Process command lines that name ntds.dit with a copy-capable tool, which is how Sophos describes the Active Directory database theft after the shadow copy. FP: ntdsutil and esentutl are legitimate for IFM media creation and AD maintenance; exclude change-window admin accounts.
Known limitations and deployment notes
- PowerQuery: A copy tool outside the listed names, or an ntds.dit path built at run time, is not matched.
- PowerQuery assumes: src.process.user is the account of the creating process and stands in for the user that ran the tool.
- KQL – Defender XDR: A copy tool outside the listed names, or an ntds.dit path built at run time, is not matched.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: ntds.dit referenced in a command line by a copy-capable tool // MITRE: T1003.003 // CONF: high FP: medium COST: low // REQUIRES: process creation with command line (Falcon sensor, default) // FALSE POSITIVES: ntdsutil IFM creation, AD health tooling, backup software // TUNING: exclude the AD admin accounts that run IFM during change windows, e.g. | UserName!=/^adm-ifm$/i // LOOKBACK: 30d #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | CommandLine=/ntds\.dit/i | FileName=/^(cmd|powershell|pwsh|copy|xcopy|robocopy|esentutl|ntdsutil|vssadmin|7z|rar)\.exe$/i | table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
4 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process nametgt.process.cmdline: Created command line
Recommended fields
src.process.name: Creating process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, tgt.process.name, tgt.process.cmdline
// HUNT: ntds.dit referenced in a command line by a copy-capable tool // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1003.003 // CONF: high | FP: medium // FALSE POSITIVES: ntdsutil IFM creation, AD health tooling, backup software // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on a Process Creation event: the created process is a copy-capable tool and its command line contains ntds.dit. The created process is tgt.process.*. contains and matches are case-insensitive, which reproduces the CQL /i intent. // REQUIRES: SentinelOne Process Creation telemetry with the created process command line // TUNING: Exclude the AD admin accounts that run IFM during change windows by src.process.user. // LOOKBACK: 30d (set with the console time picker) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A copy tool outside the listed names, or an ntds.dit path built at run time, is not matched. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.cmdline contains 'ntds.dit' tgt.process.name matches '^(cmd|powershell|pwsh|copy|xcopy|robocopy|esentutl|ntdsutil|vssadmin|7z|rar)\\.exe$' | columns event.time, endpoint.name, src.process.user, tgt.process.name, tgt.process.cmdline, src.process.name | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: Created command line
Recommended fields
InitiatingProcessFileName: Initiating process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, ProcessCommandLine | take 5
// HUNT: ntds.dit referenced in a command line by a copy-capable tool
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1003.003
// CONF: high | FP: medium
// FALSE POSITIVES: ntdsutil IFM creation, AD health tooling, backup software
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the created process is a copy-capable tool and its command line contains ntds.dit. contains and in~ are case-insensitive, which reproduces the CQL /i intent.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude the AD admin accounts that run IFM during change windows by AccountName.
// LOOKBACK: 30d (the CQL tab uses the same window)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A copy tool outside the listed names, or an ntds.dit path built at run time, is not matched.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where ProcessCommandLine contains "ntds.dit"
| where FileName in~ ("cmd.exe", "powershell.exe", "pwsh.exe", "copy.exe", "xcopy.exe", "robocopy.exe", "esentutl.exe", "ntdsutil.exe", "vssadmin.exe", "7z.exe", "rar.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName
| sort by Timestamp desc
| take 200Detection Rules by Platform
All four rules start at Detect. Promote to a higher action only after 14 days with a measured false-positive rate under 5 percent, and never for rules that match legitimate signed software by name alone.
CrowdStrike: Custom IOA
| IOA name | Type and patterns | Exclusions | Promotes | Deployment |
|---|---|---|---|---|
| Sandboxie WUAU outside install path | Process Creation. Image Filename .*\\SandboxieWUAU\.exe$ | Image path matching .*\\Sandboxie(-Plus)?\\.* | Promote Q2 | Detect, severity High |
| sbiedll.dll dropped outside Sandboxie | File Creation. File name .*\\sbiedll\.dll$ | Target path matching .*\\Sandboxie(-Plus)?\\.* | Promote Q3 | Detect, severity High |
| Sideload host spawns shell or discovery tool | Process Creation. Parent image .*\\(javaw|Krita|NvdaHelper|Jcef_helper|Vmmap|LineAppMgr|bginfo64|SandboxieWUAU)\.exe$; Image .*\\(net1?|vssadmin|whoami|nltest|esentutl|ntdsutil)\.exe$ | Known Java application directories for javaw.exe | Promote Q8 | Detect, severity High, review for 14 days |
| ntds.dit named in a copy command | Process Creation. Command line .*ntds\.dit.* | AD admin accounts running IFM media creation | Promote Q10 | Detect, severity High; scope to domain controller host group |
SentinelOne: custom detection rules
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| Sandboxie WUAU outside install path | Q2, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| sbiedll.dll dropped outside Sandboxie | Q3, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| Sideload host spawns shell or discovery tool | Q8, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| ntds.dit named in a copy command | Q10, 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 |
|---|---|---|---|
| Sandboxie WUAU outside install path | Q2, 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 |
| sbiedll.dll dropped outside Sandboxie | 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 |
| Sideload host spawns shell or discovery tool | Q8, 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 |
| ntds.dit named in a copy command | Q10, 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 |
Q1, Q4, Q5, Q6, Q7 and Q9 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,7afd292994ff214ca4dd880c834532274c957963e9838c7fa2e4d1318af75756,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),campaign:BRONZE-SANDCASTLE sha256,b39e41be217fe2c690f75e9861cf64df52b302c66619fad608ca60a959288842,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,7515417e523a776e371877e868536fa1d1961826d4bc478734be993985d9df03,detect,high,2027-04-25,BRONZE SANDCASTLE Meterpreter-based payload (config.ini),campaign:BRONZE-SANDCASTLE sha256,ab200eda30dd1868f597ac42e7876894c5838df84605bbd4fca8dbc91c90ea28,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (libcef.dll),campaign:BRONZE-SANDCASTLE sha256,dd9223c381893f493ca581e5bd35f16f778689e58fc459c1b0c39b0d33b41290,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (CoreFoundation.dll),campaign:BRONZE-SANDCASTLE sha256,95c6e9447585670b1a50551c36abe22154f6e010bfb23275fc467d2b20a423d9,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),campaign:BRONZE-SANDCASTLE sha256,548d5add2b27ab8c2d506b81623a37f3d27a0f4e22e6fa938c6a008b70775989,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,592a6e74366bcd0c8a47657a88a6e81f99d2876baa6f923bb928bba4477054fc,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (NvdaHelperRemote.dll),campaign:BRONZE-SANDCASTLE sha256,2332d924b1404961bc65280e782c787a4b048da7519fe73ccf4dc687b843d060,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,425177b18cb386f359796576e51666b7350489579550e564f51f8973b2f0979b,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,72259376f63116d1aca64bf2ef42a5d211c1ebdb01516ef3b53778ed1347c238,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,2411a678e4de91451e69c27369bab4329c3cd969d4ebd851ba91dcfdba7e7db2,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (MSIMG32.dll),campaign:BRONZE-SANDCASTLE sha256,fdef7b1f4c013d686bf5dbfc92f37191c04beb0dc8b53c608bb8019a8c678052,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,e50dc9db568c272d7b019ec8e5fb1f111dd071baa4b3a00bc3c8c885ade46fbc,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (snmpapi.dll),campaign:BRONZE-SANDCASTLE sha256,6c5c332428d914fd8eac0164947a70ec3d71bcd3f6cdcccb5e875dcb68ea076d,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),campaign:BRONZE-SANDCASTLE sha256,91ef27b1e83f324348ca51466ab17e2464f927b9c84758898fd7ce7ae6a6008b,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),campaign:BRONZE-SANDCASTLE sha256,437ba4b0db084c261f7843f85329b5204a2dedecdacf29b25a53a90bcf8d7d2e,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,c7f1c6cfd87e4c4f492a6da634ae6a264467aaee5a3eed14e89c2297a58e5d30,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,c39ac4e1fe11639a9d46e026850cc3146eb809b542daf38e1a00eab11eaa1834,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),campaign:BRONZE-SANDCASTLE sha256,e404b2b9f9f203dad81bdc1ef8bfcbe4f42eb616f113a89ed504202212af1c1e,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (jli.dll),campaign:BRONZE-SANDCASTLE sha256,5e2b035ae40f8eaab40792a92573171df0011c2fbed55582268a824effa7cb91,detect,high,2027-04-25,BRONZE SANDCASTLE sideloaded loader (msvcp140.dll),campaign:BRONZE-SANDCASTLE domain,dc.cathaypacifice.com,detect,high,2027-04-25,BRONZE SANDCASTLE v1.1.5 C2 server,campaign:BRONZE-SANDCASTLE domain,net.dpworldto.com,detect,high,2027-04-25,BRONZE SANDCASTLE v1.1.5 C2 server,campaign:BRONZE-SANDCASTLE
indicatorType,indicatorValue,action,title,description,expirationTime,severity,recommendedActions,rbacGroups,category,mitretechniques,GenerateAlert FileSha256,7afd292994ff214ca4dd880c834532274c957963e9838c7fa2e4d1318af75756,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,b39e41be217fe2c690f75e9861cf64df52b302c66619fad608ca60a959288842,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,7515417e523a776e371877e868536fa1d1961826d4bc478734be993985d9df03,Audit,BRONZE SANDCASTLE Meterpreter-based payload,BRONZE SANDCASTLE Meterpreter-based payload (config.ini),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,ab200eda30dd1868f597ac42e7876894c5838df84605bbd4fca8dbc91c90ea28,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (libcef.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,dd9223c381893f493ca581e5bd35f16f778689e58fc459c1b0c39b0d33b41290,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (CoreFoundation.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,95c6e9447585670b1a50551c36abe22154f6e010bfb23275fc467d2b20a423d9,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,548d5add2b27ab8c2d506b81623a37f3d27a0f4e22e6fa938c6a008b70775989,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,592a6e74366bcd0c8a47657a88a6e81f99d2876baa6f923bb928bba4477054fc,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (NvdaHelperRemote.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,2332d924b1404961bc65280e782c787a4b048da7519fe73ccf4dc687b843d060,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,425177b18cb386f359796576e51666b7350489579550e564f51f8973b2f0979b,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,72259376f63116d1aca64bf2ef42a5d211c1ebdb01516ef3b53778ed1347c238,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,2411a678e4de91451e69c27369bab4329c3cd969d4ebd851ba91dcfdba7e7db2,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (MSIMG32.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,fdef7b1f4c013d686bf5dbfc92f37191c04beb0dc8b53c608bb8019a8c678052,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,e50dc9db568c272d7b019ec8e5fb1f111dd071baa4b3a00bc3c8c885ade46fbc,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (snmpapi.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,6c5c332428d914fd8eac0164947a70ec3d71bcd3f6cdcccb5e875dcb68ea076d,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,91ef27b1e83f324348ca51466ab17e2464f927b9c84758898fd7ce7ae6a6008b,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,437ba4b0db084c261f7843f85329b5204a2dedecdacf29b25a53a90bcf8d7d2e,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,c7f1c6cfd87e4c4f492a6da634ae6a264467aaee5a3eed14e89c2297a58e5d30,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,c39ac4e1fe11639a9d46e026850cc3146eb809b542daf38e1a00eab11eaa1834,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (sbiedll.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,e404b2b9f9f203dad81bdc1ef8bfcbe4f42eb616f113a89ed504202212af1c1e,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (jli.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,5e2b035ae40f8eaab40792a92573171df0011c2fbed55582268a824effa7cb91,Audit,BRONZE SANDCASTLE sideloaded loader,BRONZE SANDCASTLE sideloaded loader (msvcp140.dll),2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,dc.cathaypacifice.com,Audit,BRONZE SANDCASTLE v1.1.5 C2 server,BRONZE SANDCASTLE v1.1.5 C2 server,2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,net.dpworldto.com,Audit,BRONZE SANDCASTLE v1.1.5 C2 server,BRONZE SANDCASTLE v1.1.5 C2 server,2027-04-25T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
Column names and allowed values are from Microsoft's documented parameter table. Check each expirationTime before importing: an indicator whose date has passed is already expired. Download the sample CSV from the Import page to confirm the column order before a bulk import. Each file takes at most 500 indicators. Learn describes the import per entity type, so if a mixed file is rejected, split it by indicatorType. An imported indicator does nothing unless the matching Advanced features are on (for example Custom network indicators and Allow or block file).
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.
# MD5 and SHA1 of the same samples, for tooling that does not take SHA256 (Sophos IoC file) sbiedll.dll md5=07ed4b9470b2395ad5f969a501761ab8 sha1=1f74838581e8bef12cb7df2d70099cd6865ef238 jli.dll md5=25ee87bb42d88bf00f60c4064c376846 sha1=e98c54ce736a607803e89144daa679fccd4f7521 config.ini md5=dd89cfd1f0b13addfc43cae758130b6a sha1=f7db825aeee21d6326fa9c31512d090720546341 libcef.dll md5=615a6089ab073115ed0b8bcfcfbdc966 sha1=dae5a4489671e2d9d2189a830b17ff144f8ab904 CoreFoundation.dll md5=4e916e024ea0c0eb16bd91f054d22444 sha1=ffe58ea274af642a3fc1d50e823cb01f61dc8dae sbiedll.dll md5=e63ec733393e4e7e3424cbff918003a3 sha1=cd1a262f8c2624700440b0aa464b7a2b42e23511 jli.dll md5=2a39552543f84aa3a7a562d9bb54fc00 sha1=536d6a8fa98a566079a459b16df1e29622dd8af5 NvdaHelperRemote.dll md5=8c32bf3711b237e3c781a00b5c526695 sha1=4e6d600ce7a9cf6414e738d8f39260ae961602f0 jli.dll md5=f771159881bc82217d30a64a7716e613 sha1=624da53bd827ca27b66d8a42a9524b0b48e882b4 jli.dll md5=3addd7c803b9570fc0b1ee6899444c66 sha1=56b1258c4553fb549fca9215727be1e5cd1efe4e jli.dll md5=a0fa0893e1adde6b93063ab2c7369536 sha1=1abe25d3255679bdc1c35c070da40e3c4572bb4a MSIMG32.dll md5=0a7464945e1994a7fc5ee2b86ce48c94 sha1=2f399541445cc1aade0e7a2148853fe41be57827 jli.dll md5=e43a7c1169cf1d4ce8b22c1301ca100c sha1=120d204d253293d594d6fcbe681797942fb74f7a snmpapi.dll md5=5ac863a8bffbcca5647284e088d401dc sha1=0ed62f00b9e7c5780c9bd05b096eee13a160480f sbiedll.dll md5=b695542718a7cc373112852d97d1811e sha1=c2811a0fa539e4cd6633f32349fb34b0455bcba6 sbiedll.dll md5=4cf187200a4e639e314b7f96a33f161e sha1=1fc7350e215759b4d66ab6458244271b5e2cfa90 jli.dll md5=32151547d912488ac5242731057170a3 sha1=24ede364f5eabe991c866e92ffa396bcb894eb14 jli.dll md5=c15c10589e671094185311e358b8903b sha1=6204c6342c5dfb67bdc29d45a524c3ac3a99aa01 sbiedll.dll md5=5910e874fccc9b37239b00b993393994 sha1=ffd5cfbd5274a351315ba1e922d795f872f7ff9b jli.dll md5=0ff9ecbaf18e45cd7b4943b21d5c6cf1 sha1=8964de054bfb70c5560ebabe224bb45723f60b37 msvcp140.dll md5=ebf221383c234ea2361ed54e6df6ddfc sha1=ab86a6b71582e16a7da14533fe9407d7a2bc525c
SandboxieWUAU.exe or Start.exe next to sbiedll.dll outside a Sandboxie folder Signed host (javaw, Krita, NvdaHelper, Jcef_helper, Vmmap, LineAppMgr, bginfo64) beside a rogue DLL and config.ini Host executable spawning cmd, net, vssadmin, nltest or ntdsutil vssadmin create shadow followed by a copy naming ntds.dit Host process resolving file.io, gofile.io, ably.net, ably.io or api.github.com DLL that reads a local file and immediately runs code in memory (Sophos guidance) Reflective loading and anomalous PE headers in memory (Sophos guidance)
BRONZE SANDCASTLE (Sophos CTU designation) Modified Meterpreter-based backdoor, payload versions 1.1.5 and 1.1.7 Sophos detections: ATK/Swrort-Y, ATK/ScLoad-W, ATK/ScLoad-X, ATK/ScLoad-Y, ATK/ScLoad-Z, Troj/Loader-JL, Troj/Loader-JP Sideload pairs: SandboxieWUAU.exe and Start.exe with sbiedll.dll; javaw.exe with jli.dll; Krita.exe with Krita.dll; NvdaHelper.exe with NvdaHelperRemote.dll; Jcef_helper.exe with Libcef.dll; Vmmap.exe with Version.dll; LineAppMgr.exe with msvcp140.dll; bginfo64.exe with snmpapi.dll Payload carrier: config.ini (encrypted); sample archive aez.zip
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v CWDIllegalInDllSearch reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids Get-ADGroupMember -Identity "Backup Operators" | Select-Object Name, SamAccountName
Detection Validation Gates
| Gate | Check | Pass when |
|---|---|---|
| Telemetry ready | Process creation with path and parent (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents); executable write (CrowdStrike: PeFileWritten. SentinelOne: File Creation. Defender: DeviceFileEvents); DNS with process (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceEvents) | Each source returns rows for a known test host in the last hour |
| Benign baseline | Run Q4, Q5, Q7, Q8, Q9, Q10 over 30 days and list hits by application directory and account | Every recurring hit has an exclusion in the TUNING lines |
| Positive tests | On an isolated test host, copy a benign signed executable renamed SandboxieWUAU.exe into a temp folder (Q2); drop a harmless file named sbiedll.dll in the same folder (Q3); run vssadmin create shadow /for=C: only on a lab server (Q9). Use no real malware. | Each query returns the test host within minutes |
| Promotion | Keep every IOA and IOC at detect. Promote only after 14 days and a measured false-positive rate under 5 percent. | Decision and rate recorded in the hunt ticket |
Static gates run on this file: structure (verify_huntpack), Falcon field names (lint_cql_fields), CQL syntax (lint_cql_syntax), IOC provenance against the saved snapshots (check_ioc_provenance), and a duplicate check against the published library.
Hardening: Tiered
Platform in scope: Windows endpoints, servers and Active Directory domain controllers. The sources describe no Linux, macOS, cloud or appliance activity.
- 1. Command-line process auditing. Record command lines in Security 4688 so net, vssadmin and ntds.dit activity is visible without EDR. MITRE M1047 (Audit). Authority: Microsoft Learn, "Command line process auditing" (best-practice; no formal CIS item cited here).
- 2. Refuse DLL loads from the current working directory. Set
CWDIllegalInDllSearchto 0xFFFFFFFF per Microsoft KB 2264107. MITRE M1044 (Restrict Library Loading). Does not stop a DLL beside the executable, which is this group's technique, so treat it as a partial control (flagged: best-practice, no formal benchmark). - 3. Review who can create shadow copies on domain controllers. Audit Backup Operators and local Administrators membership on DCs. MITRE M1026 (Privileged Account Management), M1018 (User Account Management).
- 4. Attack Surface Reduction in audit mode. Enable the rule "Block executable files from running unless they meet a prevalence, age, or trusted list criterion" in AuditMode on a pilot ring. MITRE M1038 (Execution Prevention). Authority: Microsoft Defender ASR rules reference. Requires Microsoft Defender Antivirus active.
- 5. Application control for user-writable paths. Author a WDAC or AppLocker policy in audit mode that flags executables and DLLs loading from ProgramData, Public, Temp and Downloads. MITRE M1038, M1045 (Code Signing). Authority: Microsoft WDAC deployment guide, CIS Windows Benchmark application-control guidance.
- 6. Retire unsanctioned Sandboxie, Krita, NVDA, Sysinternals copies. If the product is not approved in your estate, add it to the unsanctioned-software inventory and remove stray copies found by Q2 and Q5. MITRE M1047.
- 7. Tiered administration for domain controllers. Limit interactive and remote admin logon to DCs to dedicated Tier 0 accounts and hosts, which limits who can run vssadmin and read ntds.dit. MITRE M1026, M1030 (Network Segmentation). Authority: Microsoft enterprise access model, Microsoft Security Baseline for Windows Server.
- 8. Enforced application control with signed policy. Move step 5 from audit to enforce for servers first. MITRE M1038.
- 9. Server egress filtering. Deny anonymous file-sharing and messaging APIs from servers by proxy category, keeping the audit log. MITRE M1031 (Network Intrusion Prevention). Best-practice, no formal benchmark.
Verify after deployment
Use the Hardening audit block in section 10. For control 1, Security 4688 events must now carry a Process Command Line field. For controls 4 and 5, review audit events for 14 days before any enforcement.
Deployable Playbooks
Step 1: Enable command-line capture in process-creation events
Prerequisites: local admin or GPO write; the "Audit Process Creation" subcategory must also be enabled for 4688 to be generated. Reboot required: No. Rollback: run the rollback lines at the end of the block; the setting returns to its default.
$k = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit' New-Item -Path $k -Force | Out-Null Set-ItemProperty -Path $k -Name ProcessCreationIncludeCmdLine_Enabled -Type DWord -Value 1 auditpol /set /subcategory:"Process Creation" /success:enable # Verify Get-ItemProperty $k -Name ProcessCreationIncludeCmdLine_Enabled # Rollback Remove-ItemProperty -Path $k -Name ProcessCreationIncludeCmdLine_Enabled auditpol /set /subcategory:"Process Creation" /success:disable
Step 2: Refuse DLL loads from the current working directory
Prerequisites: test legacy line-of-business apps that rely on loading DLLs from the working directory. Reboot required: No for new processes; restart long-running services. Rollback: remove the value.
$k = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' Set-ItemProperty -Path $k -Name CWDIllegalInDllSearch -Type DWord -Value 0xFFFFFFFF # Verify Get-ItemProperty $k -Name CWDIllegalInDllSearch # Rollback Remove-ItemProperty -Path $k -Name CWDIllegalInDllSearch
Step 3: ASR prevalence rule in audit mode (pilot ring)
Prerequisites: Microsoft Defender Antivirus is the active antimalware engine on the pilot hosts; a pilot ring of 20 or fewer hosts. Reboot required: No. Rollback: set the rule to Disabled or remove it.
$id = '01443614-cd74-433a-b99e-2ecdc07bfc25' Add-MpPreference -AttackSurfaceReductionRules_Ids $id -AttackSurfaceReductionRules_Actions AuditMode # Verify Get-MpPreference | Select-Object AttackSurfaceReductionRules_Ids, AttackSurfaceReductionRules_Actions # Rollback Remove-MpPreference -AttackSurfaceReductionRules_Ids $id
Step 4: Review shadow-copy-capable groups on a domain controller
Prerequisites: ActiveDirectory PowerShell module, read access to the domain. Reboot required: No. Rollback: none required, this step only reads group membership.
Import-Module ActiveDirectory
'Backup Operators','Administrators','Domain Admins' | ForEach-Object {
Get-ADGroupMember -Identity $_ -Recursive | Select-Object @{n='Group';e={$_}}, Name, SamAccountName
}
# Expected: only named Tier 0 accounts and the backup service account
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-contain the host with the sideload hit (EDR network containment). Do not power off: the backdoor runs in memory. If a domain controller shows Q9 or Q10 hits, treat the domain as compromised. | IR lead | Containment timestamp, host and account list |
| 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. | IR lead | Containment timestamp, host and account list |
| Preserve | Capture memory first. Then copy the whole folder holding the host executable, rogue DLL and config.ini (and any ZIP). Hash all files and compare with section 4. | Forensics | Memory image, folder copy, hashes |
| Scope | Run Q1 to Q10 over 90 days. Find other hosts with the same folder layout, other host/DLL pairs from Sophos Table 1, and any command line naming ntds.dit or vssadmin shadow creation. | Threat hunter | Host list with first and last seen |
| Eradicate | Remove the staged folder contents after evidence is secured; remove any autorun or task found pointing at it (the sources do not document a persistence mechanism, so check for one rather than assume). | IR lead | Before and after file listing |
| Credential reset | If ntds.dit was copied: reset the krbtgt account twice with a gap that respects replication, reset all privileged and service accounts, then user accounts, in that order. | AD owner | Reset log per account class |
| Recover | Rebuild confirmed-compromised servers from known-good media; restore the hardening in section 12; keep the IOA rules at detect and watch for 30 days. | Infrastructure | Rebuild record, 30-day clean hunt result |
| Report | Record victimology and any new hash, domain or host/DLL pair for a pack update. Sophos IoC file may be updated, so re-check it. | Threat intel | Updated indicators with source snapshots |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | CrowdStrike coverage | SentinelOne | Defender XDR |
|---|---|---|---|---|---|---|
| T1574.001 | Sandboxie host and sbiedll.dll staging | Q1, Q2, Q3 | IOA 1, IOA 2 | Good | Good, with assumptions | Partial: Q1 telemetry gap |
| T1574.001 | Eight other host/DLL pairs | Q4, Q5 | IOA 3 (children) | Partial | Partial: Q4 approximate | Partial: same limit as CrowdStrike |
| T1036.005 | Renamed legitimate executables | Q2, Q5 | None | Partial | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1620 / T1027 | Encrypted config.ini decode and in-memory run | None | None | GAP | GAP | GAP |
| T1071.001 / T1102 | C2 domains and abused services | Q6, Q7 | None | Partial | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1087 / T1018 | net discovery commands | Q8 | IOA 3 | Partial | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1003.003 | vssadmin shadow copy and ntds.dit copy | Q9, Q10 | IOA 4 | Good | Good, with assumptions | Good, with assumptions |
| T1056.001 / T1113 | Keylogging and screenshots | None | None | GAP | GAP | GAP |
Gaps, stated plainly: (1) the in-memory decode and reflective load has no hunt query, the sources recommend memory and behavioral sensor detection [#1]; (2) renamed host executables evade name matching in Q2, Q5, Q7, Q8 (Sophos says renaming is frequent [#1]); (3) the pairing of CoreFoundation.dll and MSIMG32.dll with a host is not published; (4) module-load telemetry for the DLL is not used because the sensor event name was not verified against the data dictionary, and an invented event name would return nothing; (5) no persistence mechanism is documented, so none is hunted. Validation gates are in section 11.
Hunt Summary Ticket
TITLE: BRONZE SANDCASTLE: Sandboxie DLL sideload and modified Meterpreter backdoor hunt
SEVERITY: High (China-based espionage cluster, AD database theft reported)
SCOPE: Windows endpoints and servers; domain controllers for the credential-theft steps
HYPOTHESIS: Signed host executables run beside rogue DLLs and an encrypted config.ini in user-writable
folders, then enumerate the network and copy ntds.dit
QUERIES: Q1 to Q10 (CrowdStrike LogScale). 4 Custom IOA rules, all detect. 23 atomic IOCs, all detect.
DO FIRST: Q2, Q3, Q8 across the estate; Q9 and Q10 on domain controllers; Q1 and Q6 as 90-day retro-hunts
FINDINGS: Expected positive: a host executable from a non-install folder with a DLL written minutes
earlier, followed by net, vssadmin or ntds.dit command lines. Escalate immediately on any
Q9 or Q10 hit on a DC. Queries must be run manually; no findings recorded in this pack.
GAPS: In-memory decode and reflective load (needs memory or behavioral sensor detection, outside
endpoint telemetry queries); renamed host executables; keylogging and screenshot capture
ACTIONS: Low risk now: run queries, enable command-line auditing. Pending approval: ASR audit pilot,
application-control audit policy, DC admin review
OWNER: HuntPack
VERSION: v0.1 (Draft) 2026-10-25
Changelog
References
| # | Tier | Source | Used for | Access date |
|---|---|---|---|---|
| 1 | T1 | Sophos CTU: BRONZE SANDCASTLE deploys modified Meterpreter shells | All technique and victimology claims | 2026-10-25 |
| 2 | T2 | The Hacker News | Capabilities, GitHub account status, APT41 context | 2026-10-25 |
| 3 | T2 | SecurityOnline | Renamed executables, corroboration | 2026-10-25 |
| 4 | T2 | GBHackers | aez.zip layout, T1574.001 reference, COFFLoader caveat | 2026-10-25 |
| 5 | T1 | SophosLabs IoC repository, BRONZESANDCASTLE_Meterpreter_IOCs.csv | All hashes and C2 domains | 2026-10-25 |
| 6 | T1 | MITRE ATT&CK T1574.001 | Technique reference | 2026-10-25 |
Source snapshots for #1 to #5 are saved beside this file in BronzeSandcastle-Sandboxie-Meterpreter-Hunt-sources/. Reference 6 was not fetched; it is cited only as the public technique ID.
Generated 2026-10-25 by HuntPack · v0.1 (Draft) · Defensive content only. Validate field names and tuning in your tenant before deploying.