Skip to content

Windows Persistence Mechanisms Triage Playbook

Adversaries establish persistence to maintain uninterrupted access across system restarts and credential resets. This field guide details the most prevalent Windows persistence locations and triage commands.


🗂️ Master Persistence Vector Checklist

Section titled “🗂️ Master Persistence Vector Checklist”
[ ] 1. Registry Run / RunOnce Keys (HKLM / HKCU)
[ ] 2. Startup Folders (User & All Users)
[ ] 3. Windows Services (ImagePath, svchost ServiceDll)
[ ] 4. Scheduled Tasks (XML actions, hidden tasks)
[ ] 5. WMI Event Subscriptions (__EventConsumer)
[ ] 6. Accessibility Binaries (Sticky Keys / Utilman)
[ ] 7. Winlogon Shell & Userinit Keys
[ ] 8. COM Component Hijacking (CLSID InprocServer32)

⚙️ 1. Windows Services Abuse (T1543.003)

Section titled “⚙️ 1. Windows Services Abuse (T1543.003)”

Adversaries create malicious services or tamper with existing service binary paths (binPath).

  • HKLM\SYSTEM\CurrentControlSet\Services\[ServiceName]
  • Key values: ImagePath (binary path), Start (2=Auto, 3=Manual, 4=Disabled), ServiceDll (for svchost services under Parameters).
Terminal window
# Identify services with unusual paths (outside System32 or Program Files)
Get-CimInstance Win32_Service |
Where-Object {
$_.PathName -notmatch '^(C:\\Windows\\system32|C:\\Program Files|C:\\Program Files \(x86\))' -and
$_.PathName -ne $null
} |
Select-Object Name, DisplayName, State, StartMode, PathName |
Format-Table -AutoSize

📅 2. Scheduled Tasks Triage (T1053.005)

Section titled “📅 2. Scheduled Tasks Triage (T1053.005)”

Scheduled tasks are commonly created via schtasks.exe or PowerShell to execute payloads periodically.

  • Task XML Files: C:\Windows\System32\Tasks\
  • Task Registry Tree: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\ and ...\Tree\
Terminal window
# Parse Task XML definitions directly for script interpreters or temporary folder paths
Get-ChildItem -Path "C:\Windows\System32\Tasks" -Recurse -File | ForEach-Object {
try {
[xml]$taskXml = Get-Content $_.FullName -Raw -ErrorAction Stop
$actions = $taskXml.Task.Actions
$exec = $actions.Exec.Command
$args = $actions.Exec.Arguments
if ($exec -match '(powershell|cmd|cscript|wscript|mshta|temp|appdata)' -or $args -match '(temp|appdata|http|-enc)') {
[PSCustomObject]@{
TaskName = $_.Name
FullPath = $_.FullName
Command = $exec
Args = $args
}
}
} catch {}
} | Format-Table -AutoSize

🕷️ 3. WMI Event Subscriptions (T1546.004)

Section titled “🕷️ 3. WMI Event Subscriptions (T1546.004)”

WMI persistence runs completely in the repository without standard registry keys or executable files in startup folders, making it extremely stealthy.

  1. __EventFilter: WQL query specifying triggering event (e.g. system startup, user logon, or specific time).
  2. __EventConsumer: Action taken upon trigger (e.g. CommandLineEventConsumer running a command or script).
  3. __FilterToConsumerBinding: The link associating the filter to the consumer.
Terminal window
# Query WMI Persistence in root\subscription namespace
$ns = 'root\subscription'
$consumers = Get-CimInstance -Namespace $ns -ClassName __EventConsumer
$filters = Get-CimInstance -Namespace $ns -ClassName __EventFilter
$bindings = Get-CimInstance -Namespace $ns -ClassName __FilterToConsumerBinding
Write-Host "=== WMI CONSUMERS ===" -ForegroundColor Cyan
$consumers | Select-Object Name, CommandLineTemplate, ExecutablePath, ScriptText | Format-List
Write-Host "=== WMI BINDINGS ===" -ForegroundColor Yellow
$bindings | Select-Object Filter, Consumer | Format-List

🔑 4. Winlogon & Authentication Packages (T1547.004)

Section titled “🔑 4. Winlogon & Authentication Packages (T1547.004)”

Modifying the default shell or logon helper applications to execute an adversary binary at logon.

  • HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
    • Shell: Must default to explorer.exe
    • Userinit: Must default to C:\Windows\system32\userinit.exe,
    • Taskman: Normally empty
Terminal window
# Verify Winlogon defaults
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" |
Select-Object Shell, Userinit, Taskman, VmApplet |
Format-List

♿ 5. Accessibility Backdoors (Sticky Keys / Utilman) (T1546.008)

Section titled “♿ 5. Accessibility Backdoors (Sticky Keys / Utilman) (T1546.008)”

Replacing accessibility binaries (sethc.exe or utilman.exe) with cmd.exe, or configuring an Image File Execution Options (IFEO) debugger.

Terminal window
# Check IFEO Debugger values for accessibility binaries
$ifeoKeys = @('sethc.exe', 'utilman.exe', 'osk.exe', 'Magnify.exe', 'DisplaySwitch.exe')
foreach ($key in $ifeoKeys) {
$path = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$key"
if (Test-Path $path) {
$debugger = (Get-ItemProperty -Path $path).Debugger
if ($debugger) {
Write-Warning "BACKDOOR DETECTED on $key -> Debugger: $debugger"
}
}
}