# 08 · The Zero-Day Research Capstone

> **Audience / level:** Advanced red team operators and vulnerability researchers; assumes chapters 01–06.  **Prerequisites:** COM activation internals, the impersonation contract, AppID security, OleViewDotNet basics, WinDbg attach/breakpoint fluency.  **Estimated reading time:** 90–120 minutes.
> After this chapter you will be able to run a repeatable, eight-stage pipeline — enumerate, triage, reverse, harness, fuzz, prove, weaponize, report — that turns the COM attack surface covered by this course into new, original bugs.

**Contents**
- [1. The research mindset](#1-the-research-mindset)
- [2. Stage 1 — Enumeration: building the target list](#2-stage-1--enumeration-building-the-target-list)
- [3. Stage 2 — Triage: ranking candidates](#3-stage-2--triage-ranking-candidates)
- [4. Stage 3 — Static reverse engineering](#4-stage-3--static-reverse-engineering)
- [5. Stage 4 — Dynamic analysis harness](#5-stage-4--dynamic-analysis-harness)
- [6. Stage 5 — Fuzzing COM interfaces](#6-stage-5--fuzzing-com-interfaces)
- [7. Stage 6 — From crash or lead to a proven primitive](#7-stage-6--from-crash-or-lead-to-a-proven-primitive)
- [8. Stage 7 — Weaponization and reporting](#8-stage-7--weaponization-and-reporting)
- [9. The research backlog: open problems worth hunting](#9-the-research-backlog-open-problems-worth-hunting)
- [10. Appendix A — Master tooling table](#10-appendix-a--master-tooling-table)
- [11. Appendix B — Master reading list](#11-appendix-b--master-reading-list)
- [12. References](#12-references)

---

## 1. The research mindset

COM remains under-explored for structural reasons, not because it is hidden. It is the substrate under OLE, ActiveX, WMI, the shell, Office automation, WinRT, and UAC; practically every Windows process loads `combase.dll`/`ole32.dll`; thousands of classes are registered by default; and activation is driven entirely by the registry, which makes the surface enormous, largely un-audited per class, and almost invisible to file-less-malware defenses. Chapter 01 mapped thirteen fundamental primitives rooted in that design; every technique in chapters 02–06 is an instance of one of them:

| # | Primitive (chapter 01) | Attack family it feeds |
|---|---|---|
| 1 | HKCU shadowing of `CLSID\{X}\InprocServer32`/`LocalServer32` | Persistence / UAC bypass |
| 2 | `TreatAs`/`AutoTreatAs` redirect | Persistence |
| 3 | Phantom `InprocServer32`/`LocalServer32` paths | Persistence |
| 4 | `Interface\{IID}\ProxyStubClsid32` shadow (DLL into *both* endpoints) | LPE / Persistence |
| 5 | `TypeLib\{LIBID}\...\win32` path shadow + `LoadTypeLib` moniker quirk | Persistence / Execution |
| 6 | ProgID/`CurVer` squatting | Persistence |
| 7 | Moniker string injection (`script:`, `new:`, `session:`, `Elevation:`) | Execution |
| 8 | ROT squatting/snooping | LPE / Execution |
| 9 | Cross-session activation (`RunAs=Interactive User`) | LPE |
| 10 | DCOM remote activation of LM-friendly classes | Lateral movement |
| 11 | Custom-marshal blob abuse (`OBJREF_CUSTOM` forgery) | Execution / Relay |
| 12 | Surrogate abuse (`DllSurrogate`) | Persistence / Execution |
| 13 | Reg-free COM manifest hijack | Persistence / Execution |

> **Key idea:** Thirteen primitives, six chapters of techniques, and no reason to believe the list is closed. The primitives are *design properties* (merged-view precedence, marshal-by-reference, AppID ACLs, the impersonation contract); design properties do not get patched — individual weaponizations do.

### 1.1 The two root patterns behind almost every find

Nearly every bug in this course reduces to one of two root causes:

1. **"A service exposes a dangerous method to everyone."** DiagHub's SYSTEM service let any user drive `AddAgent(dllPath, guid)` into `LoadLibraryExW` ([3]). UPnP Device Host exposed the undocumented `IUPnPContainerManager` (IID `6D8FF8D4-730D-11D4-BF42-00B0D0118B56`) methods `ReferenceContainer`, `CreateInstance`, `CreateInstanceWithProgID` to any local user as LOCAL SERVICE — CVE-2019-1405, fixed by adding Administrators-only checks to the dangerous methods ([7]). StorSvc's `SvcMoveFileInheritSecurity` impersonated, moved the file, then reverted and called `SetNamedSecurityInfo` as SYSTEM — the late-impersonation pattern ([3]). USO loaded a non-existent `windowscoredeviceinfo.dll` from System32 on every session creation ([5]).
2. **"The registry is trusted more than it should be."** The `HKCR` merged view lets per-user keys silently override system keys ([47]); `ProxyStubClsid32` shadows inject a DLL into every process that marshals that interface, including SYSTEM servers; `TreatAs` redirects activation without touching the target's `InprocServer32` ([28], [29]); and `LoadTypeLib` parses a non-TLB path string as a *moniker display name*, so `"script:http://evil/x.sct"` reaches the script moniker from a "data" API ([23]).

A third, smaller family is **marshaling trust**: forged `OBJREF`/`IStorage` bindings (CVE-2015-2370 and the whole potato lineage it birthed ([8], [17])) and objects marshaled by reference that were never meant to leave their process (trapped objects ([4])).

### 1.2 Microsoft's mitigation style — and what it teaches

Microsoft rarely fixes a whole bug class; it kills the *weaponization primitive* that made the class exploitable:

| Mitigation | Year | Primitive killed | Bug class left behind |
|---|---|---|---|
| 1809 silent `rpcss` fix (`CreateRemoteBindingToOR`, OXID on port 135 only, remote OXID queries as ANONYMOUS LOGON, captured tokens downgraded to Identification, CLSIDs gated to INTERACTIVE) | 2018 | Rotten/JuicyPotato reflection ([9]) | Service-account token capture — re-solved by RoguePotato and JuicyPotatoNG ([12], [13]; conceptual root in Forshaw's DCOM-relay work ([18])) |
| DiagHub `ProcessImageLoadPolicy` (Microsoft-signed loads only) | 19H1/1903 | "Load arbitrary extension from System32" via `AddAgent` ([3]) | Arbitrary file-write bugs — re-bridged by USO ([5]) |
| oleaut32 `VerifyTrust` (cached signing level ≥ 12 for TLBs in protected processes) | 2019-era | Type-library substitution inside protected processes ([4]) | Trapped-object instantiation — re-bridged via .NET/StdFont ([4]) |
| CI.DLL `CipMitigatePPLBypassThroughInterpreters` (blocks `scrobj.dll`, `jscript.dll`, etc. in protected processes) | 1803 | Scriptlet-based PPL injection ([24]) | PPL type-confusion — re-bridged by KnownDlls aliasing, `IRundown::DoCallback` ([24], [25]) |
| KB5004442 / CVE-2021-26414 (PKT_INTEGRITY floor for activation) | 2021–2023 | Relay *to* DCOM activation ([10]) | Authenticated admin DCOM LM; relay *from* DCOM ([26], [27]) |

Three lessons fall out of that table:

- **Chase primitives, not bugs.** When a loader policy or binding builder dies, the underlying file-write/auth-capture bugs usually survive; the researcher who finds the *next* bridge (USO after DiagHub, RoguePotato after JuicyPotato) owns the next CVE family.
- **Diff the silent fixes.** The 1809 OXID change was never a CVE; it was found by researchers diffing `rpcss.dll` ([9]). `rpcss.dll`, `combase.dll`, `ole32.dll`, `oleaut32.dll` are the four binaries to BinDiff every Patch Tuesday.
- **"Not a boundary" is a hunting license.** Microsoft services UAC and PPL slowly or not at all (no CVEs/bounties for PPL-only issues ([24]; "we don't consider UAC a hard security boundary" — MSRC case 64957, per Kanthak ([43])). Bug density in these zones stays high precisely because fixes ship late.

![Figure 1 — The eight-stage zero-day research pipeline](diagrams/d27-research-pipeline.png)
*How to read this figure: the pipeline you will run for the rest of this chapter, left to right — enumerate (OleViewDotNet, registry sweeps), triage (OOP + SYSTEM + ACLs + dangerous methods), static RE, dynamic harness, fuzzing, root-cause, weaponize, report — with the tools named at each stage. Sections 2–8 map one-to-one onto the stages.*

> **Legal:** Everything here is for authorized research: your own lab VMs, bug-bounty scope, or systems you are contracted to test. The enumeration and fuzzing stages are indistinguishable from attack behavior on a network you do not own.

---

## 2. Stage 1 — Enumeration: building the target list

The goal of Stage 1 is a *complete* candidate list: every COM class on the box that could plausibly execute attacker-influenced logic at a higher privilege, plus every registry path whose trust could be subverted. Completeness matters more than precision — Stage 3 discards.

> **Beginner note:** An **out-of-process (OOP) server** is a COM class whose code runs in its own process — a `LocalServer32` EXE, a service-hosted class, or a DLL hosted by the `dllhost.exe /Processid:{AppID}` surrogate. OOP matters because the server process often runs as SYSTEM, so "who may activate it and what methods does it expose" becomes a privilege question. In-process (`InprocServer32`) classes matter when the *host* is privileged (auto-elevated binaries, PPL services, other users' processes).

### 2.1 OleViewDotNet — deep usage

OleViewDotNet (Forshaw) is the recon workhorse ([1]). Two front-ends, same data:

**GUI views that build target lists:**

- `Registry → Local Services` — COM objects hosted in Windows services, with filtering. This is the LPE shortlist.
- `Registry → CLSIDs by Server` — group by server binary to see which DLL/EXE carries the most classes.
- Object node → **View Launch Permissions / View Access Permissions** — the AppID SDDLs decoded; a class readable by `Authenticated Users`/`INTERACTIVE` shows up immediately.
- AppID properties expose `RunAs`, service name, and **ServiceProtectionLevel** (PPL); the class list can be filtered to **"Run as: Interactive User"** — the exact filter that surfaces cross-session candidates such as the PhoneExperienceHost class `{7540C300-BE9B-4C0D-A335-F002F9AB73B7}` behind bohops' CVE-2023-33127 chain ([11]).

**PowerShell module** (`Install-Module OleViewDotNet` — **PowerShell 5 only, not 7+**):

```powershell
Get-ComClass -Service                              # all service-hosted classes (the LPE shortlist)
Get-ComClass -Clsid 42CBFAA7-A4A7-47BB-B422-BD10E9D02700
$cls.Servers                                       # InProc vs Local server registrations
$cls.AppIDEntry                                    # RunAs identity, service name
$cls.AppIDEntry.ServiceProtectionLevel             # PPL check, e.g. WindowsLight
Get-ComInterface -Class $cls                       # interfaces the class advertises
New-ComObject -Clsid 72566E27-1ABB-4EB3-B4F0-EB431CB1CB32
Import-ComTypeLib -Object $obj                     # pull the object's type library
Get-ComObjRef $obj                                 # proves OOP: shows hosting PID/process name
```

Worked example — the exact enumeration behind the trapped-objects research ([4]): `Get-ComClass -Service` → enumerate interfaces → filter `IsDispatch` → **five candidates on a default box**: WaaSRemediation `{72566E27-1ABB-4EB3-B4F0-EB431CB1CB32}`, SearchGatheringManager `{9E175B68-F52A-11D8-B9A5-505054503030}`, SearchGathererNotification `{9E175B6D-F52A-11D8-B9A5-505054503030}`, AutomaticUpdates `{BFE18E9C-6D87-4450-B37C-E02F0B373803}`, and `Microsoft.SyncShare.SyncShareFactoryClass` `{DA1C0281-456B-4F14-A46D-8ED2E21A866F}`. One `IsDispatch` filter turned "thousands of classes" into a weekend-sized list — that is what good enumeration looks like. OleViewDotNet can also invoke arbitrary methods, view the ROT, parse `.winmd` metadata, and spawn elevated instances (`CreateElevated`).

### 2.2 Raw-registry sweeps

OleViewDotNet reads the registry; sometimes you want the registry itself:

```powershell
# Full CLSID/AppID walk (machine + merged view)
Get-ChildItem Registry::HKEY_CLASSES_ROOT\CLSID
reg query HKCR\CLSID /s
# DCOM-reachable applications and their AppIDs
Get-CimInstance Win32_DCOMApplication
# Orphan sweep (bohops): registered servers whose binary is missing ([28])
$inproc = Get-WmiObject Win32_COMSetting | ?{ $_.InprocServer32 -ne $null }
foreach ($p in ($inproc | %{$_.InprocServer32})) { $p; cmd /c dir $p > $null }   # "File Not Found" = orphan
# Scheduled tasks with COM handler actions = timed triggers ([34])
foreach ($Task in Get-ScheduledTask) {
  if ($Task.Actions.ClassId -ne $null -and $Task.Triggers.Enabled -eq $true -and $Task.Principal.GroupId -eq "Users") {
    Write-Host "$($Task.TaskName) :: $($Task.Actions.ClassId)"
  }
}
```

- **Dangling references:** ProcMon during logon/app launches with `Operation is RegOpenKey` + `Result is NAME NOT FOUND` + `Path ends with InprocServer32` — every hit is a CLSID a live process *tries* to activate that you can register in HKCU ([30]). The ClickOnce phantom-object technique (pre-registering a CLSID that `dfsvc.exe` registers later) is this idea weaponized ([31]).
- **Phantom hunting generally:** ProcMon `Path contains InprocServer32/LocalServer32/TreatAs/ProxyStubClsid32`, `Result = NAME NOT FOUND`.
- **Per-user shadow audit:** diff `HKCU\Software\Classes\CLSID` and `...\TypeLib` against HKLM; anything present in both with different server paths is an existing hijack or a plant.

### 2.3 The WinRT surface

WinRT is COM vNext — same `IUnknown` base, `IInspectable` instead of `IDispatch`, `.winmd` metadata instead of TLBs — but its classes register per-package under `HKLM\SOFTWARE\Microsoft\WindowsRuntime` (with `ActivatableClassId` server mappings), **not** `HKCR\CLSID`. Classic CLSID tooling does not see them; OleViewDotNet parses both worlds. Brokers are just OOP COM servers with sandbox-facing activation permissions — CVE-2019-0555 (XML DOM exposed through WinRT → XSLT sandbox escape) is the canonical find ([4]). Enumerate this hive separately or your target list has a hole.

### 2.4 Automation: the incendium.rocks methodology

Manual browsing does not scale. The incendium.rocks methodology ([2]) automates the loop end-to-end: walk the registry/CLSID set → use OleViewDotNet to dump each class's interfaces and methods to **JSON** → build dynamic `IDispatch` stubs at runtime and **automatically `Invoke`** every method with generated arguments → logHRESULTs, crashes, and side effects. OleViewDotNet builds dynamic `IDispatch` stubs at runtime to call arbitrary vtables — the same primitive every COM fuzzer uses (§6).

### 2.5 Standing on corpora

Do not re-derive what is published: the JuicyPotato per-OS abusable-CLSID lists (`ohpe.it/juicy-potato/CLSID/`) encode the potato criteria (instantiable by the user, implements `IMarshal`, elevated server identity) per Windows build ([16]); the strontic xcyclopedia CLSID library catalogs classes and their capabilities; the juicy-potato repo README tables map CLSIDs to working OS versions. NCC's acCOMplice ships `masterkeys.csv` of known hijackable shell classes (§10). These are starting sets — your job is to extend them, not worship them.

---

## 3. Stage 2 — Triage: ranking candidates

A default Windows box yields thousands of classes; you can reverse perhaps a dozen well. Triage is a scoring pass that answers one question: *if I drive this object, does privileged code do something I control?* Every heuristic below is drawn from the case studies in this course — each is a property that a published bug actually had.

### 3.1 The master checklist

A candidate is promising if it checks these boxes, in descending order of importance:

1. **OOP server.** Registered with `LocalServer32`, hosted in a service via its AppID, or running in a `dllhost` surrogate. In-proc classes count only when the host is privileged (auto-elevated binary, PPL service, another user's process).
2. **Privileged identity.** Server runs as `NT AUTHORITY\SYSTEM` (direct win), `LOCAL SERVICE`/`NETWORK SERVICE` (hop — these hold `SeImpersonatePrivilege`, the potato entry point), or another user / `RunAs=Interactive User` (cross-session).
3. **Reachable ACLs.** `LaunchPermission` + `AccessPermission` (or machine defaults under `HKLM\SOFTWARE\Microsoft\Ole`) include your principal: `Authenticated Users` (S-1-5-11), `INTERACTIVE` (S-1-5-4), or AppContainer/LPAC capability SIDs for sandbox escapes. DiagHub's launch SDDL literally contained `(A;;CCDCSW;;;AU)` — Authenticated Users ([3]).
4. **Dangerous methods.** Interface methods that touch: filesystem paths (`CreateFile`, `MoveFile`, delete/rename), the registry, process creation, `LoadLibrary*`/`GetProcAddress`, `SetNamedSecurityInfo`/ACL APIs, token APIs — or that **accept interface pointers** (callback-impersonation pattern: DCOMPotato's attacker-supplied `IUnknown` impersonates the SYSTEM caller inside its own `QueryInterface`) or **return objects** (trapped-object pattern: the returned reference stays live in the server ([4])).
5. **Marshaling trust.** Class implements `IMarshal` (potato criterion ([16])), is marshaled TypeLib-driven via `PSOAInterface` `{00020424-0000-0000-C000-000000000046}` (type-library substitution applies), or its `Interface\{IID}\ProxyStubClsid32` can be shadowed per-user (a DLL into both endpoints).
6. **Bonus multipliers.** `IDispatch`/`dual` present (type-info vector — `ITypeInfo::CreateInstance` instantiates server-side ([4])); .NET COM interop (loads the CLR into the server); `RunAs=Interactive User` (cross-session); `Elevation\Enabled=1` (UAC elevation-moniker surface ([37])); server binary unsigned or third-party (patch-cycle lag).

### 3.2 Scored triage table *(illustrative scoring)*

The weights below are a starting heuristic, not ground truth — calibrate them against your own hit rate.

| Signal | Where you read it | Points *(illustrative)* |
|---|---|---|
| OOP server (LocalServer32 / service AppID / surrogate) | OleViewDotNet `.Servers`, AppID entry | +3 |
| Runs as SYSTEM | AppID `LocalService`, service config | +3 |
| LOCAL/NETWORK SERVICE identity (potato hop) | AppID / service config | +2 |
| Launch+Access ACLs include AU / INTERACTIVE / LPAC | OVDN View Permissions | +3 |
| Method takes a path/URL/command string | Proxy definition / typelib | +2 |
| Method wraps `LoadLibrary*`, process creation, or `SetNamedSecurityInfo` | Static RE (§4) | +3 |
| Method accepts an interface-pointer argument | Proxy definition | +2 |
| Method returns an object reference | Proxy definition | +2 |
| `IDispatch`/dual interface | `Get-ComInterface`, `IsDispatch` | +2 |
| Implements `IMarshal` | Interface list | +1 |
| TypeLib-driven marshaling (`PSOAInterface` proxy) | `HKCR\Interface\{IID}\ProxyStubClsid32` | +1 |
| .NET interop (`mscoree.dll` InprocServer32) | Registry | +1 |
| `RunAs = Interactive User` | AppID entry / OVDN filter | +2 |
| Server is PPL (`.AppIDEntry.ServiceProtectionLevel`) | OleViewDotNet | +1 (PPL-class impact) |

> **Key idea:** Read the table historically: DiagHub scores on rows 1, 2, 3, 4, 5; UPnP CVE-2019-1405 on 1, 2, 3, 4; the StdFont trapped-object chain needed only rows 4 (returns object), 5, and 6 (`IDispatch`). No published bug needed every row — three or four of the heavy ones suffice. Kill anything scoring 0 on rows 1–3 unless you are specifically hunting hijacks.

For persistence-style targets (chapter 05) the analogous score is: **trigger frequency x host desirability x breakage risk** — count `RegOpenKey` hits per CLSID per process per hour from a ProcMon boot trace (or hijack several candidates with a logging DLL, acCOMplice `Hijack-MultipleKeys`-style), prefer explorer/browsers/taskhostw over niche hosts, and prefer orphaned/abandoned/undefined classes that a Windows update will not re-register ([31]).

---

## 4. Stage 3 — Static reverse engineering

Static RE answers two questions per candidate: **what are the exact method signatures** (so you can call them) and **where does the server mishandle trust** (so you know what to call). The canonical recipe is the one Forshaw used against DiagHub ([3]), generalized below, with itm4n's USO service work ([5], [6]) as the second reference implementation.

### 4.1 The DiagHub recipe, generalized

1. **Instantiate and inspect.** In OleViewDotNet, create an instance of the class → right-click → *Marshal ⇒ View Properties*. Capture the **PID** of the hosting process, the **IPID** (per-interface-pointer GUID), the **OXID** (object exporter), the string bindings, and the authentication services. This proves the object is OOP and names its host.
2. **Get the server-side vtable address.** OleViewDotNet's process view (needs admin plus configured symbols: dbghelp from the WinDbg install and `srv*https://msdl.microsoft.com/download/symbols`) → find your IPID entry → it shows the interface pointer and the **server-side VTable address**, e.g. `DiagnosticsHub_StandardCollector_Runtime+0x36C78` for DiagHub.
3. **Symbolize the vtable.** Attach WinDbg to the server process and dump the vtable with `dqs <module>+<offset> L<nMethods>` — Microsoft public symbols resolve the slots to real names. DiagHub's `IStandardCollectorService` (IID `0D8AF6B7-EFD5-4F6D-A834-314740AB8CAA`) yielded `CreateSession`, `GetSession`, `DestroySession`, `DestroySessionAsync`, `AddLifetimeMonitorProcessIdForSession` exactly this way ([3]):

   ```text
   0:019> dqs DiagnosticsHub_StandardCollector_Runtime+0x36C78 L8
   ```

4. **Recover signatures from the wire format.** OleViewDotNet's **View Proxy Definition** decompiles the NDR "stubless" bytecode of the proxy into method signatures; the **Structures tab** gives marshaled struct layouts. Rebuild the interface in C++/C# from these. For DiagHub this produced the `SessionConfiguration` struct and `CreateSession`/`AddAgent` prototypes the exploit needed.
5. **Reconcile with disassembly.** In IDA/Ghidra: xref command/operation strings (itm4n found `"StartScan"` in `usosvc.dll` and walked the xrefs into `PerformOperationOnSession()`/`PerformOperationOnManager()` ([6])); where CFG is present, map `_guard_dispatch_icall_fptr` indirect calls to vtable slots with dynamic breakpoints; match client-side proxy slots (`ObjectStublessClientN`) to server-side symbols so client slot *N* = server function you are reading.
6. **Hunt the failure modes** (this is the actual bug list; every one is a published bug class):

   | Failure mode in server code | Historical instance |
   |---|---|
   | Missing `CoImpersonateClient`/`RpcImpersonateClient` around a privileged op | Classic privileged-file-operation class |
   | Impersonate → check → `RevertToSelf` → *then* write | StorSvc `SvcMoveFileInheritSecurity` ([3]) |
   | Accepting an identify-level token where impersonation is required | Potato CLSID hardening regression space ([9]) |
   | Device-map / symlink / hard-link handling while impersonating | CVE-2019-0841 AppXSvc, StorSvc hard links ([3]) |
   | Path validation that constrains directory but not extension/content | DiagHub `GetValidAgentPath` ([3]) |
   | `RunAs` mismatch / missing client-identity verification | CVE-2017-0100 HelpPane ([46]) |
   | Type-library trust (stub generated from attacker-controlled TLB) | NGEN type confusion, trapped objects ([24], [4]) |
   | Unmarshal-by-reference of objects never meant to leave the server | CVE-2019-0555, CVE-2017-0211 ([4]) |

### 4.2 The USO variant — when the tool fails, pivot

itm4n's USO write-up is the honest version of this workflow ([5], [6]): `symchk` pulled PDBs first (symbols are leverage, always try); string xref on `"StartScan"` located the trigger path; OleViewDotNet then **failed to expand the object** (`ClassFactory cannot supply requested class`) — and the research continued anyway, client-side: breakpoint on `_guard_dispatch_icall_fptr` after `CoCreateInstance`, `dqs` on the client proxy vtable (`usoapi!IUpdateSessionOrchestratorProxyVtbl`), then match `ObjectStublessClientN` slots against server symbols in `usosvc.dll`. The result was the full map of `IUpdateSessionOrchestrator` (`{07F3AFAC-7C8A-4CE7-A5E0-3D24EE8A77E0}`: `CreateUpdateSession`, `GetCurrentActiveUpdateSessions`, `LogTaskRunning`, `CreateUxUpdateManager`, `CreateUniversalOrchestrator`) and the 68-method `IUsoSessionCommon` (`{FCCC288D-B47E-41FA-970C-935EC952F4A4}`), with `VTable[21]` identified as the StartScan trigger.

> **Key idea:** OleViewDotNet failing on a class is information, not a dead end. `ClassFactory cannot supply requested class` means the activation path itself is unusual (locked-down factory, wrong CLSCTX, interface-only marshaling) — switch to client-side dynamic analysis of the proxy and read the server from the disassembler.

> **Warning:** WinDbg-attaching to a SYSTEM service freezes its threads while broken in; RPCSS garbage-collects OXIDs on missed pings, and some services watchdog-restart. Snapshot the VM first, and prefer non-invasive attach (`-pv`) when you only need `dqs`.

---

## 5. Stage 4 — Dynamic analysis harness

Static reading tells you what the server *can* do; the harness tells you what it *actually does when you call it*, under which token, touching which paths. The harness is deliberately minimal: a C++ client you control argument-by-argument, plus observation tooling on the server process.

### 5.1 The minimal client skeleton

The shape comes directly from the published DiagHub/USO clients ([3], [6]): initialize, activate OOP, **offer impersonation**, then call methods with controlled inputs. The `CoSetProxyBlanket(... RPC_C_IMP_LEVEL_IMPERSONATE ...)` call is not ceremony — itm4n's StartScan flow required it, because a server can only impersonate a client that lets it (the impersonation contract of chapter 03).

```cpp
// Minimal COM method-probing client (after itm4n's USO "StartScan" flow ([6]))
CoInitializeEx(0, COINIT_MULTITHREADED);
CoCreateInstance(CLSID_TargetClass, nullptr, CLSCTX_LOCAL_SERVER,
                 IID_PPV_ARGS(&service));
service->LogTaskRunning(L"Probe");                       // any bookkeeping call
service->CreateSession(1, &IID_ISessionItf, &session);   // obtain the interesting interface
CoSetProxyBlanket(session, RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT,
                  COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_DEFAULT,
                  RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, NULL);
session->TheMethod(0, 0, L"C:\\Users\\Public\\probe.txt");  // controlled inputs here
CoUninitialize();
```

```cpp
// Generic one-method-per-argument sweep (illustrative)
// For each method M and each string argument A: call M with A set to a
// canary path; log HRESULT; check ProcMon for the canary appearing in the
// server's file/registry operations.
HRESULT hr = E_FAIL;
for (auto& m : methods) {
    for (auto& arg : m.stringArgs) {
        hr = m.invoke(canaryPath(arg));
        log(m.name, arg.index, hr);       // non-E_INVALIDARG HRESULTs = arg parsed
    }
}
```

> **Beginner note:** `CoSetProxyBlanket` sets per-proxy security (it wraps `IClientSecurity::SetBlanket`): which authentication level and *impersonation level* the server gets on calls through that one proxy. `RPC_C_IMP_LEVEL_IDENTIFY` (2) lets the server only identify you — its token cannot access objects; `RPC_C_IMP_LEVEL_IMPERSONATE` (3) lets it act as you locally. If a bug needs the server to touch your files as you, offer 3.

### 5.2 Observation stack

| Tool | Configuration | What it proves |
|---|---|---|
| ProcMon | Filter: server PID (from §4 step 1); watch file/registry/LoadImage operations | Which paths the server touches **as its own identity**; canary strings reaching `CreateFile` |
| API Monitor | Hook the server binary | Parameter-level view of `CreateFileW`/`LoadLibraryExW`/registry calls |
| WinDbg breakpoints | `CoImpersonateClient`, `RpcImpersonateClient`, `CoRevertToSelf`, `CreateFileW`, `RegCreateKeyExW`, `LoadLibraryExW`, `SetNamedSecurityInfo` | Whether the server impersonates *at all*, and whether the sensitive call happens **before or after revert** (the late-impersonation bug pattern) |
| TokenViewer (Forshaw) | Inspect the token the server captured | Impersonation vs Identification token — the #1 cause of "exploit didn't work" confusion (early RoguePotato experiments captured "useless" Identification tokens ([12])) |
| ETW | `Microsoft-Windows-RPC` (`{6AD52B32-D609-4BE9-AE07-CE8DAE937E39}`, Debug — EID 5/6 give InterfaceUuid/OpNum/Protocol/Endpoint), `Microsoft-Windows-RPC-Events` (`{F4AED7C7-A898-4627-B053-44A7CAA12FCD}`), `Microsoft-Windows-RPCSS` (`{D8975F88-7DDB-4ED0-91BF-3ADF48C48E0C}`), `Microsoft-Windows-COMRuntime` (`{BF406804-6AFA-46E7-8A48-6C357E1D6D61}`, verbose) | Activation and call tracing without a debugger; which interface/opnum your client actually reached |

Enable the COMRuntime provider (plus the RPC providers) for activation tracing before each run; for cross-checking the wire, Wireshark's `dcom`/`dcerpc` dissectors find the `MEOW` signature of marshaled references. The full ProcMon filter set for hijack-style targets is the phantom set from §2.2 (`Path contains InprocServer32/LocalServer32/TreatAs/ProxyStubClsid32`, `Result = NAME NOT FOUND`).

### 5.3 What you are looking for

- **Token sequencing:** breakpoint hits on `CreateFileW`/`SetNamedSecurityInfo`/`LoadLibraryExW` with no preceding `CoImpersonateClient` (missing impersonation), or after `CoRevertToSelf` (late impersonation — the StorSvc pattern ([3])).
- **Identity of file ops:** ProcMon shows the op performed as SYSTEM against your canary path in a user-writable directory.
- **Reachability of dangerous paths:** your string argument landing verbatim in a `LoadLibraryExW` path or a command line.
- **Reference leaks:** the returned proxy's `Get-ComObjRef` showing an object living in the server that the design never intended to expose (trapped-object lead ([4])).

> **OpSec:** A harness is noisy by design — rapid-fire activation, odd arguments, debugger processes. Run it in a snapshot-isolated VM. The same telemetry that helps you (ETW RPC EID 5/6, ProcMon canaries) is what a defender uses, so the harness doubles as a detection-engineering data source: record what every probe looks like in the logs for the report (§8).

---

## 6. Stage 5 — Fuzzing COM interfaces

Logical bugs (Stages 3–5) pay best, but COM interfaces are also a memory-corruption surface: every OOP call is attacker-controlled NDR bytes being unmarshaled in a privileged process — the exact layer OleViewDotNet decompiles in *View Proxy Definition*. WalletService's CVE-2020-1362 is the proof of concept for the whole category: `Wallet::WalletCustomProperty::SetGroup` OOB write over DCOM → `SetLabel` BSTR pointer write-what-where → fake vtable → virtual call redirected into `dxgi` code whose `LoadLibraryExW` uses a writable global path → SYSTEM ([42]).

![Figure 2 — COM fuzzing harness anatomy](diagrams/d28-fuzzing-harness.png)
*How to read this figure: the harness loop — create a valid object, iterate interface/method pairs from the recovered signatures (§4), mutate typed arguments (BSTR paths, SAFEARRAY bounds, VARIANT types, IStream blobs, fake interface pointers), log every HRESULT, and let a crash monitor (page heap + AppVerifier + debugger + WER) catch faults, feeding interesting inputs back into the corpus.*

### 6.1 Mutation strategies that match the marshaling layer

1. **Raw NDR buffer mutation.** Interpose between proxy and channel and mutate the marshaled buffer before it reaches the server's **NDR interpreter stubs** (the stubless-engine layer). Watch for OOB reads/writes in server-side unmarshaling (the WalletService class) and for marshal-by-reference object leaks (§5.3). Because signatures come from §4, you know which bytes are length fields, pointers, and conformant-array bounds.
2. **Typed argument mutation.** Higher yield per call, because the arguments are semantically typed:

   | Argument type | Mutations *(illustrative test list)* | Historical rationale |
   |---|---|---|
   | `BSTR` path/URL strings | Overlong strings, embedded NULs, `\??\` and device paths, junction/symlink targets, non-existent extensions on valid directories | DiagHub extension-agnostic load ([3]); USO non-existent DLL ([5]); mock-directory normalization desync |
   | `SAFEARRAY` | Bounds/count fields desynced from payload size; multidimensional edge cases | Conformant-array handling in the NDR engine |
   | `VARIANT` | Type-tag vs payload confusion (tag says `VT_BSTR`, payload is a pointer-sized integer); nested arrays; `VT_UNKNOWN`/`VT_DISPATCH` carrying unexpected pointers | TLB/proxy type-confusion family ([24], [4]) |
   | `IStream`/`IStorage` blobs | Truncated streams, negative sizes, streams whose content is a second marshaled object | `CoGetInstanceFromIStorage` OBJREF forgery lineage ([8]) |
   | Interface pointers | Fake/foreign interface pointers, pointers to objects of the wrong class, freed-then-reused pointers | Callback-impersonation (DCOMPotato) and trapped-object classes ([4]) |

3. **Interface brute-calling (poor-man's fuzzer).** The OleViewDotNet PowerShell loop — `New-ComObject` + reflection-driven method invocation with generated arguments — requires zero harness code and is exactly what the incendium.rocks automation formalized: registry → JSON of interfaces/methods → automated `Invoke` ([2]). OleViewDotNet builds the dynamic `IDispatch` stubs; you supply the argument generator and the logging.

### 6.2 What the field already built

- **COMRace** (USENIX Security '22) — data-race detection in COM objects; races matter because MTA-hosted objects are called on arbitrary RPC thread-pool threads and must self-synchronize ([39]).
- **Black Hat EU 2024, "Enhancing Automatic Vulnerability Discovery for Windows RPC/COM in New Ways"** — harness-generation research for RPC/COM fuzzing ([40]).
- **RPC-aware fuzzing driven from IDA-generated clients** — the manual version of the same idea: reverse the interface (§4), generate the client, fuzz through it.

### 6.3 Crash triage setup

The monitor stack shown in Figure 2 is page heap + AppVerifier on the server process, a debugger (or time-travel trace) attached for first-chance exceptions, and WER as the collection backstop. The briefs underlying this course do not specify exact configuration flags, so treat the specific `gflags`/AppVerifier settings as **(verify in lab)** against your Windows build before relying on them. What the course case studies do establish: crashes inside `ole32`/`combase` unmarshaling or inside the server method itself are the signal; crashes in your own proxy are harness bugs — filter by faulting module before investing in root cause.

> **Warning:** Fuzzing a SYSTEM service will, by design, crash it. Some services are marked critical — a fault can bugcheck the box or leave the service dead until reboot. Snapshot the VM, fuzz one interface at a time, and keep the corpus so every crash is replayable.

---

## 7. Stage 6 — From crash or lead to a proven primitive

A crash or an odd HRESULT is not a finding. A finding is a **primitive**: a repeatable statement like "any local user can cause an arbitrary file write as SYSTEM" with a PoC that proves it. The taxonomy below maps raw leads onto this course's bug classes, with the historical proof for each — use it to route your lead to the right proving strategy.

### 7.1 Outcome taxonomy, mapped to the course's bug classes

| Lead (what you observed) | Bug class | Proven primitive | Historical proof |
|---|---|---|---|
| Server touches attacker paths without (or after) impersonation | Missing/late impersonation | Arbitrary file write / ACL set as SYSTEM | StorSvc `SvcMoveFileInheritSecurity` + hard links → `SetNamedSecurityInfo` applies attacker ACEs to any file SYSTEM can `WRITE_DAC` (P0 1427/1428) ([3]) |
| Method loads libraries/executables from partially-controlled paths | Dangerous method exposed to everyone | Code execution as server identity | DiagHub `AddAgent` ([3]); UPnP `IUPnPContainerManager` command exec as LOCAL SERVICE, CVE-2019-1405 ([7]) |
| Returned proxy references an object still living in the server | Trapped object | Server-side `CoCreateInstance` of attacker-chosen classes | `IDispatch::GetTypeInfo` → `ITypeInfo::CreateInstance` → StdFont planted inside the service; chained to .NET `Assembly.Load` in PPL ([4]) |
| Stub built from attacker-influenced type library | TypeLib/proxy confusion | Type confusion in server stub; unsigned code in protected processes | NGEN `ICorSvcPooledWorker::CanReuseProcess` integer-as-pointer → KnownDlls aliasing → PPL injection ([24]) |
| Registry shadow/redirect loads attacker code | Registry hijack | Execution inside any process that activates the class, incl. elevated/PPL hosts | Per-user CLSID/`TreatAs`/`TypeLib` hijacks (chapters 04–05); StdFont `TreatAs` → `System.Object` ([4]) |
| Server calls into an attacker-implemented callback object | Callback impersonation | Server's token captured in-process | DCOMPotato/PrintNotifyPotato: fake `IUnknown` callback, `CoImpersonateClient()` inside `QueryInterface` impersonates the SYSTEM caller |
| `RunAs=Interactive User` class reachable cross-session | Cross-session activation / missing client verification | Code in another user's/session's context | CVE-2017-0100 HelpPane ([46]); CVE-2023-33127 PhoneExperienceHost chain ([11]) |
| Memory-corruption crash in unmarshaling or method body | NDR/argument corruption | Controlled write → fake vtable → code exec | CVE-2020-1362 WalletService BSTR write-what-where ([42]) |

### 7.2 How "proven" looks for each class

- **File write:** demonstrate creation/content control of a file at a SYSTEM-writable-only path (the DiagHub chain used `C:\Windows\System32\license.rtf`, chosen as a non-TrustedInstaller-owned, non-critical System32 file — candidates enumerated with NtObjectManager's `Get-AccessibleFile -AccessRights WriteDac` against the StorSvc process token ([3])).
- **Server-side instantiation:** `Get-ComObjRef` on the returned object must show the hosting PID is the *service* process — that single screenshot is the trapped-object proof ([4]); public third-party PoCs by Fakroud and IBM X-Force reproduce the chain end-to-end ([20], [21]).
- **Type confusion:** show the server stub interpreting your controlled input as a pointer (crash with your value in a dereferenced register), then escalate to a controlled write.
- **Callback impersonation:** inside your callback, `OpenThreadToken` and print the user — if it reads SYSTEM, the primitive is proven; TokenViewer removes all doubt (§5.2).
- **Memory corruption:** faulting address controlled by an input field; then the CVE-2020-1362 template (OOB → write-what-where → fake vtable → loader hijack) ([42]).

### 7.3 Reliability work (where most PoCs actually live)

- **STA pumping.** If your client or callback object lives in an STA, you *must* pump messages (`GetMessage`/`DispatchMessage`) or cross-apartment calls hang — and the reentrancy window during an outgoing call is where callback impersonation lands. Raymond Chen's write-up of COM failing to pump in a single-threaded apartment is the canonical failure narrative ([45]). Put exploit threads in the MTA unless you specifically need STA reentrancy.
- **Session / window-station issues.** Spawning a process from a captured service token hits Session-0 window-station permission problems; RoguePotato's final `CreateProcessAsUser` step required a Session-0 window-station permission fix ([12]), and its SYSTEM token was kidnapped from the rpcss logon session that NETWORK SERVICE shares with SYSTEM-token-holding threads ([19]). Cross-session activations likewise depend on *which* session is currently interactive ([11]).
- **Token type math.** `CreateProcessWithTokenW` needs an impersonate-capable primary-token duplicate; `CreateProcessAsUser` needs `SeAssignPrimaryTokenPrivilege`; an Identification token is a dead end for both — verify the captured token in TokenViewer before writing the spawn code ([12]).
- **Ping/liveness.** Holding OBJREFs across long analysis sessions fails silently: missed pings let the server garbage-collect stubs. Re-resolve OXIDs on long runs.

---

## 8. Stage 7 — Weaponization and reporting

### 8.1 The full-chain template

The course's two end-to-end chains (DiagHub, USO) share one template; every new primitive you prove should be driven through the same four stages:

1. **Primitive** — the thing Stage 6 proved (arbitrary file write, server-side instantiation, token capture, type confusion).
2. **File write (if not already code execution)** — overwrite a loadable artifact in a privileged location. The canonical target properties: System32-resident, not TrustedInstaller-owned, not system-critical. DiagHub's worked example used `C:\Windows\System32\license.rtf` ([3]); LocalPotato's write primitive was aimed at `SprintCSP.dll` or `printconfig.dll` ([14]).
3. **Loader trigger** — a COM/RPC method that loads or executes the planted artifact *as the privileged identity*, ideally **outside `DllMain`/loader lock**: DiagHub `AddAgent("license.rtf", guid)` (the service calls `DllGetClassObject` after load ([3])); USO's `windowscoredeviceinfo.dll` load on Update Session creation, triggered by `usoclient.exe StartScan` or directly over COM (the service calls a specific export after load ([5], [6])); `SprintCSP.dll` + `SvcRebootToFlashingMode`, or overwrite `printconfig.dll` and instantiate PrintNotify ([14]).
4. **SYSTEM** — payload runs in the service context; if you captured a token instead, apply §7.3's token math.

```text
primitive ──► file write ──► loader trigger ──► SYSTEM
StorSvc ACL      license.rtf     DiagHub AddAgent       DllGetClassObject as SYSTEM   ([3])
any write        windowscoredeviceinfo.dll   USO session create   export call as SYSTEM ([5])
LocalPotato SMB  SprintCSP.dll   SvcRebootToFlashingMode          service as SYSTEM     ([14])
```

> **Key idea:** Microsoft keeps killing stage 3 (`ProcessImageLoadPolicy`, `VerifyTrust`, KnownDlls changes) because stages 1–2 are cheap to find. Budget your research time accordingly: a standing list of *fresh loader triggers* is the reusable asset; the file-write bugs that feed them are renewable.

### 8.2 Reporting norms (as supported by the course's documented cases)

- **Know the boundary rules before you write.** Microsoft's servicing criteria decide whether your finding gets a CVE: UAC is explicitly *not* a hard security boundary ("we don't consider UAC a hard security boundary, but rather, a customizable enhancement" — MSRC case 64957, per Kanthak ([43])); PPL-only escapes get no CVEs/bounties, with fixes shipped late in new Windows versions ([4], [24]); integrity levels are not a security boundary either — the lesson of the CVE-2017-0298 bad fix, where HelpPane compared integrity levels instead of verifying the caller's admin membership. The LocalPotato HTTP/WebDAV scenario was left unpatched as an explicit Microsoft decision ([15]). Servicing-criteria link: ([44]).
- **Write the report like the ones that landed.** Forshaw's P0 issues are the model: mechanism-first (what trust assumption fails), minimal PoC, affected builds, and — critically — follow-up when the fix is wrong ("Bad Fix for COM Session Moniker EoP" became CVE-2017-0298). Track the fix: the 1809 OXID change was a *silent* `rpcss.dll` fix with no CVE, found by diffing ([9]).
- **Coordinated disclosure in practice (from the course corpus):** CVE-2015-2370 reported 2015-04-09 via Project Zero, patched as MS15-076 on 2015-07-14 ([8]); the trapped-COM-objects bug class was published as a *class* write-up after Microsoft declined boundary status ([4]); decoder's "No more rotten/juicy potato?" documented a silent mitigation publicly ([9]); CISA KEV later absorbed CVE-2017-0213 and CVE-2019-1388 — evidence that "not fixed" does not mean "not exploited."
- **Detection content is part of the deliverable.** Include the telemetry map with your PoC: which ETW providers fire (`Microsoft-Windows-RPC` EID 5/6 records InterfaceUuid/OpNum), which DistributedCOM events appear (10036–10038 for hardening refusals), which registry values change (`AllowDCOMReflection`/`OnlyUseLatestCLR` are high-fidelity trapped-COM artifacts). A finding that ships with its own detections gets patched — and credited — faster.

---

## 9. The research backlog: open problems worth hunting

Every row below is an open direction *stated in the underlying research* — not speculation. The first experiment is sized to one lab day.

| Hypothesis | Why it might exist | First experiment |
|---|---|---|
| **Alternative `IDispatch` classes** beyond the documented five enable trapped-object chains without the PPL CLR-load limitation | Outflank's LLM-assisted enumeration found exactly such alternatives after the WaaSMedicSvc path failed on updated Win11; the failure is target-specific, not class-specific ([22]) | Re-run `Get-ComClass -Service` → `IsDispatch` filter across builds, SKUs, and third-party software; for each hit, walk `ReferencedTypeLibs` and test server-side `CreateInstance` of an in-proc CoClass |
| **Trapped-object variants beyond StdFont** | StdPicture has an OOP check; StdFont does not — registration checks are per-class, so other in-proc CoClasses in commonly referenced typelibs may share the gap; `stdole` is virtually always referenced, and Forshaw found no direct EoP in the font object itself, leaving the class under-explored ([4]) | Enumerate every CoClass in the referenced typelibs of each IDispatch server; instantiate each via the remote typelib and confirm host PID with `Get-ComObjRef` |
| **Reg-free COM manifest hijack** as a stealth path | Activation-context manifests resolve classes before the registry; entries are invisible to naive `HKCR` hunting and need no registry write at all | Inventory `%WinDir%\WinSxS\Manifests` for `comClass`/`comInterfaceExternalProxyStub` declarations; in a lab, plant an attacker manifest beside a side-loadable binary and observe resolution order |
| **WinRT broker surface** hides the next sandbox escape | Brokers are OOP COM servers with sandbox-facing activation permissions, registered under `HKLM\SOFTWARE\Microsoft\WindowsRuntime` where classic CLSID tooling cannot see them; CVE-2019-0555 is the precedent ([4]) | Enumerate `ActivatableClassId` server mappings; run the §3 triage checklist against broker AppIDs, prioritizing AppContainer-reachable ones |
| **Session/cross-session activation** still exposes interactive-user classes | `RunAs=Interactive User` instantiates the object in whatever session is interactive; the class produced CVE-2017-0100 and, a decade later, CVE-2023-33127 ([46], [11]) | Apply the OleViewDotNet "Run as: Interactive User" filter per build; activate each from a service session and document what client verification the server performs |
| **TypeLib script-moniker paths** survive as a load primitive | `LoadTypeLib` parses a non-TLB path as a moniker display name, so `script:` URLs execute from a "data" API; observed in the wild (ReliaQuest 2025) and in VS poisoning ([23], [35]) | Inventory high-frequency Automation LIBIDs (explorer touches SHDocVw `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` constantly); shadow per-user and record which processes load it and whether the `script:` string survives per-build hardening |
| **DCOM relay post-KB5004442** has exploitable boundaries | The floor stops relay *to* activation, but relay *from* DCOM still works (RemoteMonologue's `RunAs` tampering + UNC-dereferencing methods); the LocalPotato HTTP scenario is unpatched by decision; RemotePotato0 was "Won't Fix" ([26], [15], [27]) | Inventory methods that dereference UNC paths (the RemoteMonologue set: `ServerDataCollectorSet`, `FileSystemImage`, `UpdateSession`, MSTSWebProxy); test coercion from each with the PKT_INTEGRITY floor enforced |
| **Per-user hijack into PPL** without admin | Forshaw: the general trapped-object technique does not require admin if any suitable IDispatch-exposing server activates user-scope classes — the per-user variant of the StdFont `TreatAs` hijack ([4]) | Find PPL-hosted classes that activate HKCU-scope classes in-session; test `TreatAs` and TypeLib shadows under `HKCU\Software\Classes` against them |

> **OpSec:** Several rows (TypeLib shadows, `TreatAs`, `AllowDCOMReflection`) are heavily signatured since 2025. Run backlog experiments on instrumented VMs and diff your own telemetry against the public Sigma/Elastic coverage — the rows where your experiment is invisible are the publishable ones.

---

## 10. Appendix A — Master tooling table

Every tool named in the course's research briefs, one row each. `—` means the brief named the tool without a URL (built-in Windows components, or links not given in the sources); retrieve those from their official channels only.

| Category | Tool | Author | Purpose | URL |
|---|---|---|---|---|
| Enumeration & analysis | OleViewDotNet | James Forshaw (tyranid) | The recon workhorse: classes/interfaces/AppIDs/typelibs, decoded ACLs, `RunAs` filters, ROT, method invocation, proxy decompilation, `.winmd` parsing | https://github.com/tyranid/oleviewdotnet |
| Enumeration & analysis | oleview.exe | Microsoft (SDK) | Legacy COM/OLE viewer | — |
| Enumeration & analysis | dcomcnfg.exe | Microsoft | GUI for AppID Launch/Access ACLs and machine OLE defaults | — |
| Enumeration & analysis | RpcView | — | RPC endpoint/interface (IPID) maps | — |
| Enumeration & analysis | ProcMon | Microsoft Sysinternals | File/registry/LoadImage tracing; phantom-CLSID hunting | — |
| Enumeration & analysis | Autoruns | Microsoft Sysinternals | Autostart enumeration (does not diff the full HKCU CLSID tree — known gap) | — |
| Enumeration & analysis | Wireshark | Wireshark project | `dcom`/`dcerpc` dissectors; grep `MEOW` in captures | — |
| Enumeration & analysis | API Monitor | — | Parameter-level API logging | — |
| Enumeration & analysis | Event Viewer | Microsoft | DistributedCOM 10010/10015/10016/10036–10038 telemetry | — |
| Enumeration & analysis | `Win32_DCOMApplication` / `Win32_COMSetting` | Microsoft (WMI) | DCOM app and COM-setting inventory | — |
| Enumeration & analysis | incendium.rocks methodology | incendium.rocks | Automated registry → JSON → `Invoke` research pipeline | https://incendium.rocks/posts/Automating-COM-Vulnerability-Research/ |
| Enumeration & analysis | JuicyPotato CLSID lists | ohpe / @Giutro & @decoder_it | Per-OS abusable-CLSID corpora | http://ohpe.it/juicy-potato/CLSID/ |
| Enumeration & analysis | strontic xcyclopedia | strontic | CLSID library/catalog | — |
| Enumeration & analysis | awesome-potatoes | bodik | Potato study notes and link farm | https://github.com/bodik/awesome-potatoes |
| Enumeration & analysis | BloodHound (`ExecuteDCOM` edge) | SpecterOps | Graph modeling of DCOM-abusable admin relationships | https://bloodhound.specterops.io/resources/edges/execute-dcom |
| Reverse engineering & debugging | WinDbg (`dqs`, `symchk`) | Microsoft | VTable symbolization, server attach, breakpoint harness, PDB retrieval | — |
| Reverse engineering & debugging | IDA / Ghidra | Hex-Rays / NSA | Server-binary disassembly; string xref (`"StartScan"` technique) | — |
| Reverse engineering & debugging | BinDiff | — | Patch diffing `rpcss.dll`, `combase.dll`, `ole32.dll`, `oleaut32.dll`, `usosvc.dll` | — |
| Reverse engineering & debugging | TokenViewer | James Forshaw | Inspect captured tokens — impersonation vs identification | — |
| Reverse engineering & debugging | NtObjectManager | — | `Get-AccessibleFile -AccessRights WriteDac` target-file enumeration | — |
| Reverse engineering & debugging | ExploitRemotingService | James Forshaw | .NET remoting trapped-object exploitation | — |
| Reverse engineering & debugging | IE11SandboxEscapes | James Forshaw | CVE-2014-0257 .NET DCOM reflection PoC (reference for trapped-object PoC) | https://github.com/tyranid/IE11SandboxEscapes |
| Reverse engineering & debugging | COMRace | USENIX Security '22 authors | Data-race detection in COM objects | https://www.youtube.com/watch?v=9bBh2YEqVMA |
| Local privilege escalation (potato family & bridges) | RottenPotato | FoxGlove Security (@breenmachine, @vvalien1) | BITS DCOM trigger + NTLM reflection (≤1803) | https://github.com/foxglovesec/RottenPotato |
| Local privilege escalation (potato family & bridges) | RottenPotatoNG | FoxGlove Security | Standalone C++ port (no Meterpreter) | https://github.com/foxglovesec/RottenPotatoNG |
| Local privilege escalation (potato family & bridges) | LonelyPotato | decoder | RottenPotato standalone | https://decoder.cloud/2017/12/23/the-lonely-potato/ |
| Local privilege escalation (potato family & bridges) | JuicyPotato | ohpe / @Giutro & @decoder_it | Arbitrary CLSID/port/program reflection (≤1803) | https://github.com/ohpe/juicy-potato |
| Local privilege escalation (potato family & bridges) | RoguePotato | @decoder_it & @splinter_code | Fake OXID resolver + named-pipe redirect (1809+) | https://github.com/antonioCoco/RoguePotato |
| Local privilege escalation (potato family & bridges) | RogueWinRM | antonioCoco | BITS→WinRM HTTP NTLM capture | https://github.com/antonioCoco/RogueWinRM |
| Local privilege escalation (potato family & bridges) | SweetPotato | @_EthicalChaos_ / CCob | C# unified potato toolkit | https://github.com/CCob/SweetPotato |
| Local privilege escalation (potato family & bridges) | JuicyPotatoNG | @decoder_it & @splinter_code | Type-9 `LogonUser` + SSPI hook (1809+/Win11) | https://github.com/antonioCoco/JuicyPotatoNG |
| Local privilege escalation (potato family & bridges) | LocalPotato | @decoder_it & @splinter_code | NTLM context swap → SYSTEM SMB write (CVE-2023-21746) | https://github.com/decoder-it/LocalPotato |
| Local privilege escalation (potato family & bridges) | GodPotato | BeichenDream | Service-DCOM trigger + callback impersonation (Win8–11) | https://github.com/BeichenDream/GodPotato |
| Local privilege escalation (potato family & bridges) | DCOMPotato | zcgonvh | Attacker `IUnknown` callback → `CoImpersonateClient` | https://github.com/zcgonvh/DCOMPotato |
| Local privilege escalation (potato family & bridges) | PrintNotifyPotato | BeichenDream | PrintNotify CLSID + callback (works with legacy Spooler off) | https://github.com/BeichenDream/PrintNotifyPotato |
| Local privilege escalation (potato family & bridges) | PrintSpoofer | itm4n | Spooler pipe-name normalization + impersonation | https://github.com/itm4n/PrintSpoofer |
| Local privilege escalation (potato family & bridges) | BadPotato | BeichenDream | PrintSpoofer C# port | https://github.com/BeichenDream/BadPotato |
| Local privilege escalation (potato family & bridges) | EfsPotato | zcgonvh | MS-EFSR coercion + pipe impersonation | https://github.com/zcgonvh/EfsPotato |
| Local privilege escalation (potato family & bridges) | SharpEfsPotato | bugch3ck | EfsPotato C# variant | https://github.com/bugch3ck/SharpEfsPotato |
| Local privilege escalation (potato family & bridges) | CoercedPotato | @Hack0ura & @Prepouce (Hackvens) | Automated multi-coercion (MS-RPRN + MS-EFSR) | https://github.com/Prepouce/CoercedPotato |
| Local privilege escalation (potato family & bridges) | PetitPotato | wh0amitz | Local PetitPotam → pipe | https://github.com/wh0amitz/PetitPotato |
| Local privilege escalation (potato family & bridges) | RasmanPotato | crisprss | RasMan RPC coercion → pipe | https://github.com/crisprss/RasmanPotato |
| Local privilege escalation (potato family & bridges) | CandyPotato | klezVirus | Weaponized pure-C++ RottenPotatoNG | https://github.com/klezVirus/CandyPotato |
| Local privilege escalation (potato family & bridges) | MultiPotato | S3cur3Th1sSh1t | Multi-trigger combo | https://github.com/S3cur3Th1sSh1t/MultiPotato |
| Local privilege escalation (potato family & bridges) | SigmaPotato | tylerdotrar | Modernized GodPotato-style, in-memory .NET | https://github.com/tylerdotrar/SigmaPotato |
| Local privilege escalation (potato family & bridges) | GenericPotato | Micah van Deusen | Generic SeImpersonation → SYSTEM | https://micahvandeusen.com/the-power-of-seimpersonation/ |
| Local privilege escalation (potato family & bridges) | GhostPotato | Shenanigans Labs | NTLM challenge-cache SMB relay bypass | https://shenaniganslabs.io/2019/11/12/Ghost-Potato.html |
| Local privilege escalation (potato family & bridges) | RemotePotato0 | antonioCoco / SentinelOne | Cross-protocol RPC→HTTP relay (remote user→DA) | https://github.com/antonioCoco/RemotePotato0 |
| Local privilege escalation (potato family & bridges) | CertPotato | SensePost | ADCS path from virtual/network service accounts | https://sensepost.com/blog/2022/certpotato-using-adcs-to-privesc-from-virtual-and-network-service-accounts-to-local-system/ |
| Local privilege escalation (potato family & bridges) | SpoolSample | Lee Christensen | MS-RPRN coercion PoC | https://github.com/leechristensen/SpoolSample |
| Local privilege escalation (potato family & bridges) | UsoDllLoader | itm4n | USO weaponization-bridge PoC | https://github.com/itm4n/UsoDllLoader |
| Local privilege escalation (potato family & bridges) | COMahawk | NCC Group / Fox-IT | CVE-2019-1405 + CVE-2019-1322 chain PoC | — |
| Local privilege escalation (potato family & bridges) | RpcClient (StorSvc) | BlackArrowSec | `SvcRebootToFlashingMode` trigger client (LocalPotato weaponization) | — |
| Local privilege escalation (potato family & bridges) | Trebuchet | NetSPI | MS15-076 → arbitrary file write | https://www.netspi.com/blog/technical-blog/web-application-pentesting/exploiting-ms15-076-cve-2015-2370/ |
| Lateral movement | impacket (`dcomexec.py`, `rpcdump.py`, `oxidresolver`) | Fortra (agsolino / byt3bl33d3r) | DCOM exec via MMC20/ShellWindows/ShellBrowserWindow; RPC dumps; OXID resolver interface leak | https://github.com/fortra/impacket |
| Lateral movement | NetExec | NetExec project | `--exec-method mmcexec` remote command execution | https://www.netexec.wiki/smb-protocol/command-execution/execute-remote-command |
| Lateral movement | SharpCOM | rvrsh3ll | C# DCOM execution | https://github.com/rvrsh3ll/SharpCOM |
| Lateral movement | SharpExcel4-DCOM | rvrsh3ll | Excel XLM/shellcode via DCOM | https://github.com/rvrsh3ll/SharpExcel4-DCOM |
| Lateral movement | Invoke-DCOM.ps1 | rvrsh3ll | PowerShell DCOM invocation | https://github.com/rvrsh3ll/Misc-Powershell-Scripts |
| Lateral movement | CsDCOM / CheeseDCOM | rasta-mouse | C# DCOM tooling | — |
| Lateral movement | SharpMove | 0xthirteen | Lateral movement (`action=dcom`/`hijackdcom`) | https://github.com/0xthirteen/SharpMove |
| Lateral movement | MoveKit | — | Lateral movement kit | — |
| Lateral movement | SharpLateral (`reddcom`) | — | DCOM lateral movement | — |
| Lateral movement | LethalHTA | codewhitesec | Remote `htafile` + custom moniker + DotNetToJScript | https://github.com/codewhitesec/LethalHTA |
| Lateral movement | Invoke-DCOMPowerPointPivot.ps1 | attactics.org | PowerPoint add-in DCOM pivot | https://attactics.org/2018/02/dcom-lateral-movement-powerpoint/ |
| Lateral movement | Empire | — | `invoke_dcom` module (MMC20, ShellWindows, ShellBrowserWindow, ExcelDDE, RegisterXLL) | — |
| Lateral movement | Cobalt Strike | — | `remote-exec com-mmc20` via Aggressor | — |
| UAC bypass | UACME (Akagi) | hfiref0x | The 82-method UAC-bypass corpus; read `comsup.h` and the `ucm*Method` modules | https://github.com/hfiref0x/UACME |
| UAC bypass | Sharp4COMBypassUAC | xz.aliyun.com writeup | ICMLuaUtil UAC bypass PoC | https://xz.aliyun.com/t/16063 |
| UAC bypass | Atomic Red Team | Red Canary | T1548.002 / T1546.015 / T1021.003 lab tests | https://github.com/redcanaryco/atomic-red-team |
| UAC bypass | Metasploit | Rapid7 | `bypassuac_eventvwr`, `bypassuac_comhijack`, `ms16_075_reflection`, CVE-2019-0841 module | https://github.com/rapid7/metasploit-framework |
| Persistence & hijacking | acCOMplice / COMHijackToolkit | David Tulis / NCC Group | `Extract-HijackableKeysFromProcmonCSV`, `Find-MissingLibraries`, `Hijack-CLSID`, `Hijack-MultipleKeys`, `masterkeys.csv` | https://github.com/nccgroup/Accomplice |
| Persistence & hijacking | COM-Hunter | @nickvourd + @S1ckB0y1337 | `search`/`persist`/`tasksch`/`treatas`/`remove` modes (.NET + BOF) | https://github.com/nickvourd/COM-Hunter |
| Persistence & hijacking | Get-ScheduledTaskComHandler.ps1 | enigma0x3 | Enumerate scheduled tasks with ComHandler actions | https://github.com/enigma0x3/Misc-PowerShell-Stuff |
| Persistence & hijacking | COMProxy | leoloobeek | Pass-through hijack DLL PoC (+ TestCOMClient/TestCOMServer) | https://github.com/leoloobeek/COMProxy |
| Persistence & hijacking | SharpDllProxy | Flangvik | Export-forwarding stub generator | https://github.com/Flangvik/SharpDllProxy |
| Persistence & hijacking | FaceDancer | — | Export-forwarding stub generator (`recon -I target.dll -G`) | — |
| Persistence & hijacking | Koppeling | — | Export-forwarding stub generator | — |
| Persistence & hijacking | Invoke-OutlookPersistence.ps1 | 3gstudent | Outlook `TreatAs` persistence automation (handles WOW6432Node) | https://github.com/3gstudent/COM-Object-hijacking |
| Persistence & hijacking | Invoke-EventVwrBypass.ps1 | enigma0x3 | eventvwr `mscfile` hijack PoC | https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/ |
| Persistence & hijacking | CS-Situational-Awareness-BOF | TrustedSec | Situational-awareness BOF (COM enumeration) | https://github.com/trustedsec/CS-Situational-Awareness-BOF |
| Persistence & hijacking | EVTX-ATTACK-SAMPLES | sbousseaden | COM-hijack Sysmon telemetry samples | https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES |
| Execution, injection & evasion | DotNetToJScript | James Forshaw | .NET assembly → JScript/VBScript/HTA via COM-visible mscorlib classes | https://github.com/tyranid/DotNetToJScript |
| Execution, injection & evasion | SharpShooter | MDSec | DotNetToJScript-based payload generation | https://www.mdsec.co.uk/2018/06/freestyling-with-sharpshooter-v1-0/ |
| Execution, injection & evasion | CACTUSTORCH / GreatSCT / SuperSharpShooter | — | DotNetToJScript-derived frameworks | — |
| Execution, injection & evasion | PPLdump / PPLmedic / PPLKiller | itm4n | PPL bypass / injection tooling | https://github.com/itm4n/PPLmedic |
| Execution, injection & evasion | PPLFault | gabriellandau | PPL bypass | — |
| Execution, injection & evasion | ANGRYORCHARD | — | PPL follow-on tooling | — |
| Execution, injection & evasion | IRundown::DoCallback injection | MDSec | COM-based injection into protected processes | https://mdsec.co.uk/2022/04/process-injection-via-component-object-model-com-irundowndocallback/ |
| Execution, injection & evasion | ForsHops | IBM X-Force Red | Remote trapped-COM fileless lateral movement | https://github.com/xforcered/ForsHops |
| Execution, injection & evasion | ComDotNetExploit | Mohamed Fakroud / T3nb3w | Local trapped-COM PPL-injection PoC | https://github.com/T3nb3w/ComDotNetExploit |
| Execution, injection & evasion | RemoteMonologue | IBM X-Force (Andrew Oliveau) | DCOM NTLM coercion via AppID `RunAs` tampering | https://github.com/3lp4tr0n/RemoteMonologue |
| Execution, injection & evasion | Koadic / Covenant | — | C2 frameworks using COM scriptlet delivery | — |
| Defense validation & detection engineering | RPC Firewall | Zero Networks | Per-call RPC UUID/opnum/source-IP filtering and logging (closes the raw-RPC-ETW remote-IP gap) | https://github.com/zeronetworks/rpcfirewall |
| Defense validation & detection engineering | sysmon-config | SwiftOnSecurity | Sysmon baseline configuration | https://github.com/SwiftOnSecurity/sysmon-config |
| Defense validation & detection engineering | sysmon-modular | olafhartong | Modular Sysmon configuration | https://github.com/olafhartong/sysmon-modular |
| Defense validation & detection engineering | Sigma | SigmaHQ | Rule set incl. COM hijack, MMC20, squiblydoo, RPC-firewall rules | https://github.com/SigmaHQ/sigma |
| Defense validation & detection engineering | Elastic detection-rules | Elastic | Prebuilt COM-hijack and DCOM-LM rules | https://github.com/elastic/detection-rules |

---

## 11. Appendix B — Master reading list

The further-reading picks from every chapter's Research Lab, deduplicated and grouped. Read in group order if you are new to the field; jump to the row matching your current pipeline stage otherwise.

**COM internals & research methodology**

- OleViewDotNet — James Forshaw — the tool and its source are the best COM-internals documentation that exists — https://github.com/tyranid/oleviewdotnet
- COM in Sixty Seconds — James Forshaw — activation/OBJREF internals talk ([49])
- The Component Object Model — magicsplat — registry keys, HKCR merged view, SCM lookup walkthrough — https://www.magicsplat.com/book/com.html
- COM Hijacking in Windows — cyberc0re — per-user vs system hive mechanics — https://www.cyberc0re.in/posts/com-hijacking-in-windows/
- Automating COM/DCOM vulnerability research — incendium.rocks — the IDispatch-JSON automation methodology — https://incendium.rocks/posts/Automating-COM-Vulnerability-Research/
- DCOM Turns 30: Revisiting a Legacy Interface in the Modern Threatscape — hack.lu 2025 slides ([41])

**Privilege escalation**

- Windows Exploitation Tricks: Exploiting Arbitrary File Writes for Local Elevation of Privilege — James Forshaw — the DiagHub chain and the file-write template — https://googleprojectzero.blogspot.com/2018/04/windows-exploitation-tricks-exploiting.html
- Weaponizing Privileged File Writes with the USO Service, parts 1–2 — itm4n — the USO bridge and honest RE workflow — https://itm4n.github.io/usodllloader-part1/ · https://itm4n.github.io/usodllloader-part2/
- CVE-2019-1405 and CVE-2019-1322 — NCC Group / Fox-IT — "service exposes dangerous API to everyone", with a ready-made OleViewDotNet methodology section — https://www.fox-it.com/be-en/cve-2019-1405-and-cve-2019-1322-elevation-to-system-via-the-upnp-device-host-service-and-the-update-orchestrator-service/
- Giving JuicyPotato a second chance: JuicyPotatoNG — decoder — post-1809 potato design — https://decoder.cloud/2022/09/21/giving-juicypotato-a-second-chance-juicypotatong/

**Trapped objects, PPL & injection**

- Windows Bug Class: Accessing Trapped COM Objects with IDispatch — James Forshaw — the newest bug class in this course, with the full OleViewDotNet methodology ([4])
- Injecting Code into Windows Protected Processes using COM, Part 1 — James Forshaw — typelib substitution → type confusion → PPL ([24])
- Process Injection via Component Object Model (COM) IRundown::DoCallback — MDSec — the callback-execution injection primitive ([25])
- Fileless Lateral Movement with Trapped COM Objects — IBM X-Force — taking the class remote ([21])

**Lateral movement**

- Lateral Movement via DCOM: Round 2 — enigma0x3 — the ShellWindows/ShellBrowserWindow playbook — https://enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/
- Abusing DCOM for Yet Another Lateral Movement Technique — bohops — abandoned binaries (mobsync) — https://bohops.com/2018/04/28/abusing-dcom-for-yet-another-lateral-movement-technique/
- I Like to Move It: Windows Lateral Movement Part 2 — DCOM — MDSec — XLM and shellcode in DCOM-spawned Excel — https://www.mdsec.co.uk/2020/09/i-like-to-move-it-windows-lateral-movement-part-2-dcom/
- Abuse the Power of DCOM Excel Application — SpecterOps — ActivateMicrosoftApp EOL proxy execution — https://posts.specterops.io/lateral-movement-abuse-the-power-of-dcom-excel-application-3c016d0d9922
- BloodHound `ExecuteDCOM` edge docs — SpecterOps — graph modeling of this attack class ([48])

**UAC**

- UAC bypasses from COMAutoApprovalList — swapcontext — enumerating and weaponizing the approved-class list — https://swapcontext.blogspot.com/2020/11/uac-bypasses-from-comautoapprovallist.html
- Calling Local Windows RPC Servers — James Forshaw — AppInfo's RPC interface and `RAiLaunchAdminProcess` ([36])
- UACME — hfiref0x — the 82-method corpus; read `comsup.h` and the `ucm*Method` modules ([38])
- UAC Bypass by Mocking Trusted Directories — David Wells / Tenable — the normalization-desync blueprint — https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e
- Advanced Windows Task Scheduler Playbook Part 2 — zcgonvh — from COM to UAC bypass to SYSTEM — http://www.zcgonvh.com/post/Advanced_Windows_Task_Scheduler_Playbook-Part.2_from_COM_to_UAC_bypass_and_get_SYSTEM_dirtectly.html
- Reading Your Way Around UAC — James Forshaw — deep UAC internals series — https://tyranidslair.blogspot.com/2017/05/reading-your-way-around-uac-part-1.html

**Persistence**

- Abusing the COM Registry Structure Part 2 — bohops — loading techniques and evasion ([29])
- Revisiting COM Hijacking — SpecterOps — modern hosts, export forwarding, OpSec ([30])
- Proxying COM For Stable Hijacks — leoloobeek — the pass-through pattern ([33])
- New Abuse of the ClickOnce Technology: Part 2 — CrowdStrike — phantom-object persistence ([31])
- acCOMplice — David Tulis / NCC Group — discovery methodology and tooling — https://github.com/nccgroup/Accomplice
- Persistence Part 2 – COM Hijacking — Dominic Chell / MDSec — the ComHandler walkthrough ([32])

**Execution, relay & detection**

- Attacking Visual Studio for Initial Access — Outflank — the `LoadTypeLib` moniker-parsing quirk ([23])
- RemoteMonologue: Weaponizing DCOM NTLM Authentication Coercions — IBM X-Force — relay-from-DCOM in 2025 ([26])
- Utilizing RPC Telemetry — SpecterOps — turning `Microsoft-Windows-RPC` ETW into call-level visibility — https://posts.specterops.io/utilizing-rpc-telemetry-7af9ea08a1d5

---

## 12. References

[1] OleViewDotNet — James Forshaw (tyranid) — https://github.com/tyranid/oleviewdotnet
[2] Automating COM/DCOM vulnerability research — incendium.rocks — https://incendium.rocks/posts/Automating-COM-Vulnerability-Research/
[3] Windows Exploitation Tricks: Exploiting Arbitrary File Writes for Local Elevation of Privilege — James Forshaw, Google Project Zero (2018) — https://googleprojectzero.blogspot.com/2018/04/windows-exploitation-tricks-exploiting.html
[4] Windows Bug Class: Accessing Trapped COM Objects with IDispatch — James Forshaw, Project Zero (2025) — https://projectzero.google/2025/01/windows-bug-class-accessing-trapped-com.html
[5] Weaponizing Privileged File Writes with the USO Service, Part 1 — itm4n (2019) — https://itm4n.github.io/usodllloader-part1/
[6] Weaponizing Privileged File Writes with the USO Service, Part 2 — itm4n (2019) — https://itm4n.github.io/usodllloader-part2/
[7] CVE-2019-1405 and CVE-2019-1322 — Elevation to SYSTEM via the UPnP Device Host Service and the Update Orchestrator Service — NCC Group / Fox-IT, Langlois & Torkington (2019) — https://www.fox-it.com/be-en/cve-2019-1405-and-cve-2019-1322-elevation-to-system-via-the-upnp-device-host-service-and-the-update-orchestrator-service/
[8] Windows: DCOM DCE/RPC Local NTLM Reflection Elevation of Privilege (Project Zero issue 325) — James Forshaw (2015) — https://bugs.chromium.org/p/project-zero/issues/detail?id=325
[9] No more rotten/juicy potato? — decoder (2018) — https://decoder.cloud/2018/10/29/no-more-rotten-juicy-potato/
[10] KB5004442 — Manage changes for Windows DCOM Server Security Feature Bypass (CVE-2021-26414) — Microsoft Support — https://support.microsoft.com/en-au/topic/kb5004442-manage-changes-for-windows-dcom-server-security-feature-bypass-cve-2021-26414-f1400b52-c141-43d2-941e-37ed901c769c
[11] Abusing .NET Core CLR Diagnostic Features (CVE-2023-33127) — bohops (2023) — https://bohops.com/2023/11/27/abusing-net-core-clr-diagnostic-features-cve-2023-33127/
[12] No more JuicyPotato? Old story, welcome RoguePotato! — decoder (2020) — https://decoder.cloud/2020/05/11/no-more-juicypotato-old-story-welcome-roguepotato/
[13] Giving JuicyPotato a second chance: JuicyPotatoNG — decoder (2022) — https://decoder.cloud/2022/09/21/giving-juicypotato-a-second-chance-juicypotatong/
[14] LocalPotato — When Swapping The Context Leads You To SYSTEM — decoder (2023) — https://decoder.cloud/2023/02/13/localpotato-when-swapping-the-context-leads-you-to-system/
[15] LocalPotato HTTP edition — decoder (2023) — https://decoder.cloud/2023/11/03/localpotato-http-edition/
[16] JuicyPotato — abusing the golden privileges (with per-OS CLSID lists) — ohpe / @Giutro & @decoder_it (2018) — http://ohpe.it/juicy-potato/ and http://ohpe.it/juicy-potato/CLSID/
[17] Rotten Potato — Privilege Escalation from Service Accounts to SYSTEM — FoxGlove Security (2016) — https://foxglovesecurity.com/2016/09/26/rotten-potato-privilege-escalation-from-service-accounts-to-system/
[18] Windows Exploitation Tricks: Relaying DCOM Authentication — James Forshaw, Google Project Zero (2021) — https://googleprojectzero.blogspot.com/2021/10/windows-exploitation-tricks-relaying.html
[19] Sharing a Logon Session a Little Too Much — James Forshaw (2020) — https://www.tiraniddo.dev/2020/04/sharing-logon-session-little-too-much.html
[20] Abusing IDispatch for Trapped COM Object Access & Injecting into PPL Processes — Mohamed Fakroud — https://mohamed-fakroud.gitbook.io/red-teamings-dojo/abusing-idispatch-for-trapped-com-object-access-and-injecting-into-ppl-processes
[21] Fileless lateral movement with trapped COM objects — IBM X-Force (2025) — https://www.ibm.com/think/news/fileless-lateral-movement-trapped-com-objects
[22] Accelerating Offensive R&D with LLMs — Kyle Avery, Outflank (2025) — https://www.outflank.nl/blog/2025/07/29/accelerating-offensive-research-with-llm/
[23] Attacking Visual Studio for Initial Access — Outflank (2023) — https://www.outflank.nl/blog/2023/03/28/attacking-visual-studio-for-initial-access/
[24] Injecting Code into Windows Protected Processes using COM, Part 1 — James Forshaw, Google Project Zero (2018) — https://googleprojectzero.blogspot.com/2018/10/injecting-code-into-windows-protected.html
[25] Process Injection via Component Object Model (COM) IRundown::DoCallback — MDSec (2022) — https://mdsec.co.uk/2022/04/process-injection-via-component-object-model-com-irundowndocallback/
[26] RemoteMonologue: Weaponizing DCOM NTLM Authentication Coercions — IBM X-Force, Andrew Oliveau (2025) — https://www.ibm.com/think/x-force/remotemonologue-weaponizing-dcom-ntlm-authentication-coercions
[27] 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/
[28] Abusing the COM Registry Structure: CLSID, LocalServer32, & InprocServer32 — bohops (2018) — https://bohops.com/2018/06/28/abusing-com-registry-structure-clsid-localserver32-inprocserver32/
[29] 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/
[30] Revisiting COM Hijacking — SpecterOps (2025) — https://specterops.io/blog/2025/05/28/revisiting-com-hijacking/
[31] New Abuse of the ClickOnce Technology: Part 2 — CrowdStrike (2025) — https://www.crowdstrike.com/en-us/blog/new-abuse-of-the-clickonce-technology-part-two/
[32] Persistence Part 2 – COM Hijacking — Dominic Chell, MDSec (2019) — https://www.mdsec.co.uk/2019/05/persistence-the-continued-or-prolonged-existence-of-something-part-2-com-hijacking/
[33] Proxying COM For Stable Hijacks — leoloobeek (2019) — https://adapt-and-attack.com/2019/08/29/proxying-com-for-stable-hijacks/
[34] Userland Persistence with Scheduled Tasks and COM Handler Hijacking — enigma0x3 (2016) — https://enigma0x3.net/2016/05/25/userland-persistence-with-scheduled-tasks-and-com-handler-hijacking/
[35] Hijacked and Hidden: New Backdoor and Persistence Technique — ReliaQuest (2025) — https://reliaquest.com/blog/threat-spotlight-hijacked-and-hidden-new-backdoor-and-persistence-technique/
[36] Calling Local Windows RPC Servers — James Forshaw, Google Project Zero (2019) — https://googleprojectzero.blogspot.com/2019/12/calling-local-windows-rpc-servers-from.html
[37] The COM Elevation Moniker — Microsoft Learn — https://learn.microsoft.com/en-us/windows/win32/com/the-com-elevation-moniker
[38] UACME — Defeating Windows User Account Control — hfiref0x — https://github.com/hfiref0x/UACME
[39] COMRace: data-race detection in COM objects (USENIX Security 2022 talk) — https://www.youtube.com/watch?v=9bBh2YEqVMA
[40] Enhancing Automatic Vulnerability Discovery for Windows RPC/COM in New Ways (Black Hat EU 2024 talk) — https://www.youtube.com/watch?v=VQiQuLo0v58
[41] DCOM Turns 30: Revisiting a Legacy Interface in the Modern Threatscape — hack.lu 2025 slides — https://d3lb3.github.io/assets/hacklu_2025.pdf
[42] CVE-2020-1362 WalletService writeup — Q4n (2020) — https://github.com/Q4n/CVE-2020-1362
[43] Mitigate some Exploits for Windows UAC (MSRC case 64957 quote) — Stefan Kanthak — https://skanthak.hier-im-netz.de/uacamole.html
[44] Microsoft Security Servicing Criteria for Windows — Microsoft — https://www.microsoft.com/en-us/msrc/windows-security-servicing-criteria
[45] The case of COM failing to pump messages in a single-threaded COM apartment — Raymond Chen, The Old New Thing (2025) — https://devblogs.microsoft.com/oldnewthing/20250314-00/?p=110965
[46] CVE-2017-0100 — Windows HelpPane Elevation of Privilege Vulnerability — Microsoft Security Response Center (2017) — https://msrc.microsoft.com/update-guide/vulnerability/CVE-2017-0100
[47] Merged View of HKEY_CLASSES_ROOT — Microsoft Learn — https://learn.microsoft.com/en-us/windows/win32/sysinfo/merged-view-of-hkey-classes-root
[48] BloodHound — ExecuteDCOM edge — SpecterOps — https://bloodhound.specterops.io/resources/edges/execute-dcom
[49] COM in Sixty Seconds — James Forshaw — https://github.com/tyranid/presentations
