Registry Parser
All articles

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.

  1. Run / RunOnce keysHKLM and HKCU\...\CurrentVersion\Run, RunOnce, the Wow6432Node views, and the per-user Explorer\Run / Windows\Load siblings. 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\, or C:\Users\Public\, or a powershell -enc blob.

  2. ServicesHKLM\System\CurrentControlSet\Services\<name>, the ImagePath and the svchost ServiceDll under Parameters\. The dominant vector on enterprise intrusions; runs as SYSTEM, survives logoff. See the services plugin. Anomaly: an ImagePath or ServiceDll outside system32/SysWOW64/Program Files, or a ServiceDll swapped under a legitimate-looking service display name.

  3. Scheduled tasks (TaskCache)HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\{Tasks,Tree,Plain}, the registry half of a task whose XML lives in System32\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.

  4. Winlogon Shell / UserinitHKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon. Userinit should end in userinit.exe,; Shell should be explorer.exe. Anything appended runs at every interactive logon. See the Winlogon plugin. Anomaly: a second path after the comma in Userinit, or a Shell that is anything but explorer.exe.

  5. AppInit / AppCert DLLsHKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs (loaded into every process linking user32.dll) and HKLM\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 with LoadAppInit_DLLs flipped to 1.

  6. IFEO debuggers and SilentProcessExitHKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<image>\Debugger and the parallel SilentProcessExit tree. Whatever is in Debugger runs in place of the named binary. The sethc/utilman sticky-keys backdoor lives here. See the Run/IFEO deep-dive. Anomaly: a Debugger pointing at cmd.exe, powershell.exe, or an unsigned binary; or any Debugger on an accessibility binary (sethc, utilman, osk, magnify, narrator, displayswitch).

  7. 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 at Program 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, or Program Files. svchost services have a ServiceDll under Parameters\ pointing at a system DLL and an ImagePath of %SystemRoot%\System32\svchost.exe -k <group>. The set of -k groups 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 the CompatibilityAdapter\Signatures hash matches the XML on disk.
  • Winlogon is Userinit = C:\Windows\system32\userinit.exe, (trailing comma) and Shell = explorer.exe. Nothing more.
  • AppInit_DLLs / AppCertDLLs / IFEO are essentially empty on a clean install. A handful of IFEO subkeys may carry GlobalFlag or MitigationOptions from legitimate tooling, but Debugger values 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, lsass in a user folder, chrome.exe outside the Chrome directory).
  • Encoded or obfuscated commands. powershell -enc, -EncodedCommand, base64 blobs, mshta/rundll32/regsvr32 invoking a remote or scriptlet payload, cmd /c chains. 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