Black Hat Asia 2026 (Singapore, Apr 23–24) — Briefings Deep Dives

PhantomRPC — Discovering New RPC-Impersonation Privilege Escalations

Talk 11 · Windows security · analysis from the speaker's published deck

Sep 23, 2026 · conferences · 9 min read · 1734 words advanced

PhantomRPC — the RPC runtime can't tell if a server is real, so it isn't.

conferences blackhat windows privilege-escalation rpc

Official recording, Black Hat YouTube channel · open on YouTube ↗

Kabibo (Kaspersky's Industrial Security Services team) revisits the "Potato" family of Windows local privilege escalations, in which a low-privileged process holding SeImpersonatePrivilege tricks a SYSTEM service into authenticating to it and then impersonates that privileged identity. The structural root cause: the Windows RPC runtime (rpcrt4.dll) has no mechanism to verify that an RPC server is legitimate, and Windows will happily let you stand up a look-alike server with the same interface UUID and endpoint as a real one. So an attacker registers a phantom RPC server, gets a privileged client to connect to it (many benign-looking actions trigger such connections), and impersonates the caller. PhantomRPC's real contribution isn't one exploit, it's a systematic discovery method: capture the RPC-unavailable exceptions that privileged clients throw when a server is missing, enrich them with ETW (Event Tracing for Windows) traces, and mine the result for new impersonation triggers. Using it, Kabibo found chains starting from ordinary actions, opening Edge, running ipconfig, gpupdate /force, even a background diagnostics service, each of which coaxes a privileged service into a rogue RPC connection.

Post 11 of my Black Hat Asia 2026 series. Analysis-first: the mechanism, the discovery method, and the detection guidance. No exploit code.

1. The two primitives: RPC and impersonation

MSRPC is how Windows processes talk to each other locally (over ALPC) and remotely. A server registers an interface (identified by a UUID) with named functions at an endpoint; a client binds to that UUID/endpoint and calls the functions. It is everywhere, most system DLLs use it under the hood.

Impersonation lets a server temporarily assume a client's identity for access checks. In RPC, a server calls RpcImpersonateClient to act as the caller. How much the server is allowed to do is governed by Security Quality of Service (SQoS), which defines four levels, Anonymous, Identification, Impersonation, and Delegation. The two higher levels let the server act as the client. For a server to impersonate at all, it needs SeImpersonatePrivilege in its token, a privilege that service accounts (LOCAL SERVICE, NETWORK SERVICE) hold by default, which is exactly the foothold Potato attacks assume.

2. The root cause: RPC doesn't authenticate the server

Kabibo states the flaw plainly: the RPC runtime does not verify the legitimacy of RPC servers, and Windows lets you deploy the exact same RPC server (same interface UUID and endpoint) that a legitimate process exposes. So if the real server isn't running, or you can race/replace it, a client that intends to call the legitimate SYSTEM service can be made to connect to your server instead. If that client impersonates at the Impersonation level, your phantom server calls RpcImpersonateClient and now holds a SYSTEM (or service) token, local privilege escalation.

The phantom RPC server Attacker (low priv) has SeImpersonatePrivilege registers same UUID/endpoint Privileged client SYSTEM / service connects, Impersonation level Impersonate RpcImpersonateClient = SYSTEM token connects to the runtime never checks the server is the real one

Fig. 1 — Because RPC won't authenticate the server, a look-alike endpoint plus a privileged client that connects and impersonates equals SYSTEM. The whole "Potato" family is instances of this.

The concrete first case: the Group Policy Client (GPSVC), running as SYSTEM, throws an exception during gpupdate /force. Tracing it revealed a failed ALPC connection to the Terminal Services (RDP) TermSrvApi endpoint at Impersonation level. Since RDP is off by default, that endpoint is free for the taking, register a phantom TermSrvApi, run gpupdate /force, and GPSVC (SYSTEM) connects and is impersonated.

3. The real contribution: an ETW-driven hunt for new triggers

Rather than hand-find one trigger, Kabibo built a discovery pipeline. The insight: a privileged client failing to reach a (missing) server throws a distinctive exception, RPC_S_SERVER_UNAVAILABLE (0x800706BA / 1722). Each such failure is a candidate impersonation trigger. To be useful it must originate from a high-privilege process and use a high impersonation level. The pipeline:

  1. Generate exceptions. Enable logging, then reboot, run random operations, and, importantly, turn off each service in turn and repeat, forcing clients to fail to reach servers that would normally be present.
  2. Capture with ETW. Event Tracing for Windows records RPC bindings, endpoints, interface UUIDs, auth details, call flow, timing, and status codes, deep visibility into client/server behavior without touching the applications. logman drives the trace to an .etl file.
  3. Correlate. Convert ETL→JSON and match RPC Stop events (status, image name, PID, endpoint) with RPC Start events (UUID, OPNUM, impersonation level), filtering on the unavailable status. Enrich each hit by looking up the interface UUID to attach the module, module path, and procedure count.

The output is an enriched list of "who tries to call what, at what impersonation level, from what privilege", i.e. a catalog of phantom-server opportunities. Kabibo calls the good candidates "Ghost Lovers": privileged clients that will happily embrace a rogue server.

Why the method matters more than the CVEs. Individual Potato techniques get patched or the specific endpoint gets locked down. A discovery method turns a one-off into a repeatable capability: point it at a new Windows build and it surfaces the current crop of triggers. That's the same "automate the finding, not just the exploit" theme as the Secrux tool in the Ghost Bits talk.

4. The triggers: benign actions that hand you SYSTEM

The pipeline surfaced several everyday actions that make a privileged service connect to an RPC endpoint an attacker can pre-register:

TriggerPrivileged clientTarget endpointNote
gpupdate /forceGPSVC (SYSTEM)RDP TermSrvApiRDP off by default → endpoint free
Launching Microsoft Edgemsedge.exe (as admin)RDP TermSrvApiEdge triggers an RPC call to RDP at high impersonation level on start
Background diagnosticsWdiSystemHost (SYSTEM)RDP TermSrvApiNo user interaction, periodic calls
ipconfigadmin processDHCP Client (LOCAL SERVICE)DHCP RPC server called by system DLLs at high impersonation
Time sync (w32tm)W32Time (LOCAL SERVICE)W32TIME_ALTEnabled by default; no need to turn the service off

The WdiSystemHost case is the standout: a background service periodically makes the vulnerable RPC call with no user interaction at all, so an attacker just waits. And the architectural point generalizes, RPC is called indirectly through layers of system DLLs (winsta.dll → rpcrt4.dll), so applications calling seemingly benign APIs can unintentionally trigger local privilege escalation without anyone realizing an RPC call is even happening.

5. Microsoft's response, and why detection is the answer

Microsoft assessed it as Moderate severity, below the bar for immediate servicing, on the grounds that the attack requires a process that already holds SeImpersonatePrivilege. That's the same reasoning applied to the whole Potato family: it's a privilege escalation from an already-privileged service account, not a bug that grants that account. The report was shared with the product team for future action.

Kabibo's honest conclusion for defenders: this type of activity cannot really be prevented, and the attack surface is extensive, so mitigation depends on future Microsoft changes. What you can do is detect it, using the same signals the broader Potato-detection community relies on.

Detection & hardening:

  • Apply "Potato" detection logic. Watch for a process holding SeImpersonatePrivilege registering an RPC/ALPC endpoint that matches a known system interface, and for token-impersonation events where a service identity is assumed by an unexpected process. ETW RPC providers, the very ones Kabibo used to find the bugs, are also how you detect them.
  • Minimize SeImpersonatePrivilege holders. The precondition is a foothold in a service account with this privilege; reduce which service accounts and third-party services run with it, and isolate those that must.
  • Reduce enabled RPC surface. Keep unneeded services (RDP especially) disabled, an off endpoint is a free phantom, but note W32Time is on by default and still exploitable, so this only shrinks the surface, it doesn't close it.
  • Alert on anomalous RPC endpoint ownership, e.g. a well-known interface UUID suddenly served by a non-standard image/path (the "attach module path" enrichment Kabibo's pipeline produces is exactly the anomaly signal).

PoCs were tested on the latest Windows Server 2022 and 2025 and reported to Microsoft on 2025-09-29; Kaspersky published the PhantomRPC research repo. Kabibo notes the released PoCs are simple examples and "additional cases are likely to exist", the method will keep producing them.

Is this a new vulnerability or an old technique?

The impersonation-via-rogue-RPC-server primitive is the classic "Potato" family. What's new is (a) a systematic ETW-based method to discover fresh triggers automatically, and (b) a set of concrete, benign-looking triggers (Edge launch, ipconfig, gpupdate, a no-interaction background service) on current Windows Server builds.

Why won't Microsoft "fix" it?

Because it requires a process that already holds SeImpersonatePrivilege, Microsoft treats it as Moderate, below the immediate-servicing bar. The runtime's lack of server authentication is architectural, so mitigation is expected to come through gradual product changes rather than a single patch.

Does disabling RDP protect me?

It removes one free endpoint (TermSrvApi), but W32Time is enabled by default and still exploitable, and other services expose callable interfaces. Disabling unneeded services shrinks the surface; it doesn't eliminate the class. Detection is the durable control.

How do I detect it if I can't prevent it?

Use ETW RPC providers to flag: a SeImpersonatePrivilege-holding process registering a known system interface UUID/endpoint, unexpected image paths serving well-known interfaces, and impersonation events where a service token is assumed by an anomalous process. This mirrors established Potato detections.

Takeaways

  • The RPC runtime doesn't authenticate servers, and Windows lets you register a look-alike interface UUID/endpoint, the structural root of the Potato family.
  • A low-priv process with SeImpersonatePrivilege stands up a phantom RPC server, gets a privileged client to connect, and impersonates SYSTEM.
  • The contribution is a repeatable ETW-driven discovery pipeline: capture RPC_S_SERVER_UNAVAILABLE exceptions, enrich with RPC traces, mine for new impersonation triggers.
  • Real triggers found: gpupdate, Edge launch, ipconfig, w32tm, and a no-interaction diagnostics service, several on default configurations.
  • Microsoft rates it Moderate (needs an existing privileged foothold); it won't be patched quickly.
  • Detect, don't try to prevent: apply Potato detections via ETW, minimize SeImpersonatePrivilege holders, and alert on anomalous RPC endpoint ownership.

References & further reading

← prev: React2Shell next: Rocket.Chat E2EE →
© cvam — written in plaintext, served warm