A registry persistence triage workflow for malware
7 min read
You have a host that might be compromised. You have its hives. Now you need an order of operations, because the registry autostart surface is large enough that you can spend a day in it and miss the one value that matters. This post is a registry autostart triage workflow: the sequence I walk to confirm or rule out malware persistence, the boring keys first because that is where the malware almost always is, and the anomaly signals that tell you when a value deserves your afternoon.
The principle behind the whole persistence checklist is the same one from the Run keys and IFEO deep-dive: there is a famous matrix of a hundred-plus persistence locations, and memorizing it is not the job. The job is to check the high-prevalence, low-effort locations first — the ones an attacker reaches for because they require nothing but a write to a key — and only then go hunting for the clever stuff. Nine incidents out of ten, the boring path is the path.
A note on scope before we start: this is the registry surface. The Startup folder, WMI event subscriptions, COM hijacks in living memory, and DLL search-order abuse all overlap with what is below but live partly or wholly outside the hives. The registry is where you start because it is fast to acquire offline and the autostart values are concentrated. It is not where you stop.
The autostart surface, in triage order
Work top to bottom. Each entry links to the deep-dive; the one-liner is the mechanism and the single anomaly signal that should stop you.
-
Run / RunOnce keys —
HKLMandHKCU\...\CurrentVersion\Run,RunOnce, theWow6432Nodeviews, and the per-userExplorer\Run/Windows\Loadsiblings. Fire at logon in the user's context, need only a key write. See Run keys (T1547.001) and the Run/IFEO workflow. Anomaly: a value whose data points into\AppData\,\Temp\, orC:\Users\Public\, or apowershell -encblob. -
Services —
HKLM\System\CurrentControlSet\Services\<name>, theImagePathand the svchostServiceDllunderParameters\. The dominant vector on enterprise intrusions; runs as SYSTEM, survives logoff. See the services plugin. Anomaly: anImagePathorServiceDlloutsidesystem32/SysWOW64/Program Files, or aServiceDllswapped under a legitimate-looking service display name. -
Scheduled tasks (TaskCache) —
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\{Tasks,Tree,Plain}, the registry half of a task whose XML lives inSystem32\Tasks\. See the TaskCache plugin. Anomaly: a task present in one half but not the other, or an action pointing at a script interpreter in a user-writable path. -
Winlogon Shell / Userinit —
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon.Userinitshould end inuserinit.exe,;Shellshould beexplorer.exe. Anything appended runs at every interactive logon. See the Winlogon plugin. Anomaly: a second path after the comma inUserinit, or aShellthat is anything butexplorer.exe. -
AppInit / AppCert DLLs —
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs(loaded into every process linkinguser32.dll) andHKLM\System\CurrentControlSet\Control\Session Manager\AppCertDLLs. See the AppInit/AppCert plugin. Anomaly: any non-empty value at all — these are empty on a clean modern install — especially withLoadAppInit_DLLsflipped to 1. -
IFEO debuggers and SilentProcessExit —
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<image>\Debuggerand the parallelSilentProcessExittree. Whatever is inDebuggerruns in place of the named binary. The sethc/utilman sticky-keys backdoor lives here. See the Run/IFEO deep-dive. Anomaly: aDebuggerpointing atcmd.exe,powershell.exe, or an unsigned binary; or anyDebuggeron an accessibility binary (sethc,utilman,osk,magnify,narrator,displayswitch). -
The broader event-triggered surface — once the common keys are clear, expand to the event-triggered techniques: WMI subscriptions, netsh helpers, LSA security/authentication packages, screensaver hijacks, and the print-monitor and PowerShell-profile angles. Most map to ATT&CK T1546, Event-Triggered Execution. Anomaly: any addition to a list-valued key (
Security Packages,Authentication Packages,Notification Packages) that is not the OS default.
The ordering is deliberate. Items 1–4 catch the overwhelming majority of opportunistic and targeted persistence and are cheap to dump. Items 5–7 are lower-prevalence but higher-confidence: a non-empty AppInit_DLLs is suspicious by its mere existence, where a Run value still needs interpretation.
What normal looks like
You cannot spot an anomaly without a baseline, and "I don't recognize it" is not a baseline. Hold these reference shapes in your head:
- Run keys carry vendor entries:
OneDrive,SecurityHealth, the antivirus tray, the GPU control panel,Teams. The data points atProgram Files,Program Files (x86), or a vendor folder under%LocalAppData%\Programs\— which is the exception that makes\AppData\alone not damning. Quoted full paths, recognizable vendor names. - Services run from
system32,SysWOW64, orProgram Files. svchost services have aServiceDllunderParameters\pointing at a system DLL and anImagePathof%SystemRoot%\System32\svchost.exe -k <group>. The set of-kgroups is finite and well-documented. - TaskCache is dominated by Microsoft's own maintenance tasks under
\Microsoft\Windows\. Both the registry and XML halves exist for each, and theCompatibilityAdapter\Signatureshash matches the XML on disk. - Winlogon is
Userinit=C:\Windows\system32\userinit.exe,(trailing comma) andShell=explorer.exe. Nothing more. - AppInit_DLLs / AppCertDLLs / IFEO are essentially empty on a clean install. A handful of IFEO subkeys may carry
GlobalFlagorMitigationOptionsfrom legitimate tooling, butDebuggervalues are rare and named-binary debuggers rarer still.
The shortcut: most of these locations are tightly constrained on a healthy host. The diversity is in the Run keys, which is exactly why they need the most interpretation and the others need the least.
Anomaly signals
Four signals do most of the work. Any one is a lead; two stacked is an incident until disproven.
- User-writable execution paths. Persistence data resolving into
\AppData\,\Temp\,C:\Users\Public\,C:\ProgramData\<random>\, or any directory a non-admin can write. SYSTEM-level autostart pointing at a user-writable binary is a privilege inversion that has no benign explanation. - Recent LastWrite. Every registry key carries a LastWrite timestamp. A persistence key written hours before the host was flagged — and out of step with the system's patch and install cadence — is your timeline anchor. Cross it against the binary's MFT, Prefetch, and AmCache records to corroborate when it fired.
- Unsigned or masquerading binaries. The target is unsigned, or it is signed but living somewhere the real publisher would never ship it, or it is named to impersonate a system binary (
svch0st.exe,lsassin a user folder,chrome.exeoutside the Chrome directory). - Encoded or obfuscated commands.
powershell -enc,-EncodedCommand, base64 blobs,mshta/rundll32/regsvr32invoking a remote or scriptlet payload,cmd /cchains. Legitimate autostart entries do not hide their arguments.
A fifth, slower signal: structural inconsistency. A task in one half of TaskCache but not the other, a ServiceDll that disagrees with its display name, a CompatibilityAdapter hash that no longer matches the XML. These survive an attacker who cleaned up the obvious value but not the bookkeeping around it.
Work the case in your browser (tool + findings)
Drop SYSTEM, SOFTWARE, and every NTUSER.DAT — with their .LOG1/.LOG2 so in-flight writes get replayed — into Registry Parser. It runs the matching artifact plugins per hive: Run keys and Winlogon and AppInit from SOFTWARE and the user hives, services and TaskCache and AppCert from SYSTEM. Each value comes with its key's LastWrite, so the timeline anchor is in front of you without a second tool.
The Findings tab applies the anomaly ruleset above automatically — user-writable paths, encoded commands, non-default values in the list-valued keys, Winlogon and IFEO deviations — and flags the hits so you triage the flagged set instead of reading every value by hand. Export the findings to JSON, CSV, or Markdown with the SHA-256 of each hive for your case notes. Nothing is uploaded; the hives are parsed in the page and discarded when you close the tab, which keeps SAM/SECURITY credential material and NTUSER.DAT user activity inside your chain of custody.
Highest-value move once you have a lead: diff the persistence keys against a VSS snapshot from before the suspected compromise. A value present live but absent two days ago is your incident, with the timestamp range already narrowed.
Two gotchas worth pinning to the wall. First, always check both registry views. Malware writes to Wow6432Node precisely because a tool checking only the native view will miss it; dump both. Second, a deleted value is not a clean value. A savvy attacker writes the Run value, runs the payload, deletes the value — and the LastWrite now reflects the deletion. The prior data lives in the transaction logs, in VSS, and in unallocated hive cells recoverable with the deleted-key tooling. An empty-looking Run key with a recent LastWrite is a question, not an all-clear.
Related
- Scenario pillar: Registry forensics investigations
- Persistence via Run keys and the IFEO debugger trick
- The services plugin
- The TaskCache plugin
- The Winlogon plugin
- The AppInit / AppCert DLLs plugin
- ATT&CK T1546: Event-Triggered Execution
- ATT&CK T1547.001: Run keys
- Parse your hives in the browser: Registry Parser