Guides

Windows Privilege Escalation: An Analysis Checklist

Updated July 27, 2026 · Written by PWNMI — see About.

This is the Windows counterpart to the script privesc checklist — same idea, different operating system. Windows privesc rarely comes down to one dramatic exploit; it's almost always a misconfigured service, a credential someone left somewhere they shouldn't have, or a privilege that was granted for a legitimate reason and never scoped tightly enough. This covers local, single-host escalation — going from a low-privileged shell to NT AUTHORITY\SYSTEM or local admin on the box you're already on. Domain-level escalation (Kerberoasting, DCSync, and the rest) is its own, larger topic — see the Active Directory attack chain guide for that.

1. Locate & Scope

  • whoami /priv — the single most useful command to start with. Look specifically for SeImpersonatePrivilege, SeAssignPrimaryTokenPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeDebugPrivilege, SeTakeOwnershipPrivilege — each maps directly to a known escalation technique, covered below.
  • whoami /groups — note anything beyond the default groups, especially BUILTIN\Administrators (even if disabled) or membership that grants access to a service account.
  • systeminfoOS build and installed hotfixes (wmic qfe list as a cross-check). Worth comparing against known kernel exploits for that exact build before spending time on configuration-based routes, though kernel exploits are noisy and often a last resort on a real engagement.
  • Running the whole box through winPEAS or PowerUp surfaces most of what's below automatically — useful as a first pass, but know what each finding actually means rather than just running the suggested one-liner it prints. The rest of this checklist is what to understand well enough to work through by hand when a tool isn't an option, or when you need to explain why something works.
  • Any signed, pre-installed binary already on the box is worth checking against LOLBAS — a trusted binary that can be coerced into elevated execution is often a faster path than any of the misconfigurations below.

2. Service Misconfigurations

Windows services run with their own privilege level, often SYSTEM — if you can influence what a service runs or how it starts, you inherit that privilege.

  • Unquoted service paths. wmic service get name,pathname,startmode | findstr /i /v "C:\Windows" — a path like C:\Program Files\Some App\service.exe with no quotes lets Windows try C:\Program.exe, then C:\Program Files\Some.exe, before the real target. If any parent directory in that chain is writable, drop a binary there.
  • Weak service permissions. accesschk.exe -uwcqv <user> <service> (Sysinternals) — checks whether you can directly reconfigure the service's binary path (SERVICE_CHANGE_CONFIG) or start/stop it, regardless of the path itself.
  • Weak binary or folder permissions. Even a correctly quoted, correctly configured service is exploitable if the executable it points to, or its containing folder, is writable by you — replace the binary, restart the service (or wait for a reboot).
  • AlwaysInstallElevated. If both HKLM\...\Installer\AlwaysInstallElevated and the matching HKCU key are set to 1, any user can install an .msi with SYSTEM privileges — build one with msfvenom -f msi and run it via msiexec /quiet /qn /i payload.msi.

3. Stored Credentials

Windows environments accumulate leftover credential material in predictable places:

  • Unattend/sysprep files. C:\Windows\Panther\unattend.xml, Panther\Unattend\Unattend.xml, sysprep.inf, sysprep.xml — often contain a local admin or autologon password from imaging, sometimes base64-encoded but not encrypted.
  • Group Policy Preferences (GPP). Older, cached GPP XML files (Groups.xml, ScheduledTasks.xml, Services.xml, DataSources.xml under SYSVOL) can carry a cpassword value — Microsoft published the AES key years ago, so any cpassword found is trivially decryptable with gpp-decrypt. Patched by Microsoft for new deployments, but old cached files still turn up on real engagements more often than the age of this bug would suggest.
  • Config and web files. web.config, unattend.txt, application config files under inetpub or a service's install directory — connection strings and service account passwords in plaintext are common.
  • Registry autologon. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinlogonDefaultUserName / DefaultPassword if autologon was ever configured and not cleaned up.
  • Saved credentials in tools. PuTTY session data (HKCU\Software\SimonTatham\PuTTY\Sessions), saved RDP files, browser-saved passwords, cmdkey /list for cached Windows credentials.
  • PowerShell history. (Get-PSReadlineOption).HistorySavePath — a plaintext log of every command a user has run in a PowerShell session, including any password typed directly on the command line.

4. Dangerous Token Privileges

If whoami /priv showed any of these as enabled, they're each a direct path to SYSTEM, independent of anything else on the box:

  • SeImpersonatePrivilege / SeAssignPrimaryTokenPrivilege. The "Potato" family (PrintSpoofer, JuicyPotato, RoguePotato, GodPotato — which specific variant works depends on the OS build) abuses this to coerce a SYSTEM-level service into authenticating to a listener you control, then impersonates the resulting token. Extremely common on service accounts (IIS app pools, SQL Server) that were granted this privilege as a side effect of normal operation, not deliberately.
  • SeBackupPrivilege / SeRestorePrivilege. Lets you read (or write) any file on the filesystem regardless of its ACLs, bypassing normal permission checks entirely — enough to copy out the SAM and SYSTEM registry hives directly, even ones you couldn't otherwise touch.
  • SeDebugPrivilege. Lets you open a handle to any process on the system, including SYSTEM-level ones — a stepping stone to token theft or credential dumping from lsass.exe.
  • SeTakeOwnershipPrivilege. Lets you take ownership of any securable object, then grant yourself whatever permissions you want on it afterward.

5. Scheduled Tasks & Startup

  • schtasks /query /fo LIST /v — look for tasks running as SYSTEM or another privileged account, then check whether the binary or script they invoke is writable by you.
  • HKLM\...\CurrentVersion\Run and RunOnce — registry autostart entries; a writable target here runs with whatever privilege the logon that triggers it has.
  • Startup folder contents (C:\Users\...\Start Menu\Programs\Startup, and the all-users equivalent) — same idea, simpler mechanism.

6. Verify

Confirm the actual privilege level before and after — whoami /priv and whoami /groups again once you believe you've escalated, not just a shell that feels different. A shell running as a different user isn't automatically a shell running as SYSTEM; confirm it directly rather than assuming from context.

Quick Triage Order

  1. whoami /priv — check for exploitable token privileges first, they're often a one-command win
  2. Service misconfigurations (unquoted paths, weak permissions)
  3. Stored credentials (unattend files, GPP, registry autologon)
  4. Scheduled tasks and startup entries
  5. Kernel exploit matching the exact build, as a last resort

Next step

If you found a token privilege but the target's OS build is unfamiliar, check which Potato variant actually applies before assuming the general technique works — build-specific patches close some variants while leaving others open. For the concepts behind why privesc works at all, and how this checklist relates to the Linux side, see Privilege Escalation Fundamentals. Once you've escalated on a single host and want to move to the domain it belongs to, see the Active Directory attack chain. For the Linux side of this same checklist, see Script Privilege Escalation — and for what to do with elevated access once you have it, see Maintaining Access.