Skip to content
Persistenceintermediate

Winlogon Helper DLL

Malware modifies Winlogon's Userinit, Shell, or Notify registry values so its executable or DLL runs during the interactive logon sequence.

Winlogon is the Windows component that manages the interactive logon sequence: loading the user profile, starting the shell, and notifying registered packages of logon/logoff events. Several of its behaviours are controlled by registry values that name executables and DLLs to run. Because these values are read with high privilege during every logon, they are an attractive and durable persistence target.

The three most-abused values are Userinit (a comma-separated list of programs run at logon, normally just userinit.exe), Shell (the user's shell, normally explorer.exe), and the legacy Notify subkeys that load a DLL on logon/logoff events. An attacker appends their payload to Userinit or Shell, or registers a Notify package, and the code executes inside the logon flow without creating a Run-key entry.

These values live under HKLM, so modification requires administrative rights, but the resulting persistence is system-wide and runs before most user-level defences are active.

How it works

The canonical Winlogon values live under one key:

text
Key:   HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
Name:  Userinit   Data:  C:\Windows\system32\userinit.exe,C:\Users\Public\payload.exe,
Name:  Shell      Data:  explorer.exe,C:\Users\Public\payload.exe

Appending a path after the trailing comma in Userinit is the classic move — the legitimate value is preserved so logon still succeeds, and the extra binary runs silently. The legacy Notify variant registers a DLL handler:

text
Key:   HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\<name>
Name:  DllName   Data:  C:\Users\Public\evil.dll

The load-bearing artifacts are the appended path in Userinit/Shell (everything beyond the expected default) and any Notify subkey on modern systems, where the mechanism is deprecated and should be empty.

Detection & analysis

Static analysis:

  • In a captured sample, look for the subkey string Winlogon plus the value names Userinit, Shell, or Notify\...\DllName, and RegSetValueExW calls that read-modify-write the existing value (concatenation) rather than overwriting it.
  • Triage a live or imaged host with Autoruns (Sysinternals): the "Logon" tab surfaces Userinit, Shell, and Notify entries; "Hide Microsoft Entries" leaves only appended payloads.
  • Offline forensics: parse the SOFTWARE hive with RegRipper or Registry Explorer. Userinit should equal exactly C:\Windows\system32\userinit.exe, and Shell should equal explorer.exe — any deviation is high-signal. The Winlogon key's last-write timestamp dates the change.

Dynamic analysis:

  • Run the sample under Procmon filtered on Path contains Winlogon and Operation is RegSetValue to capture exactly which value is altered.
  • Sysmon Event ID 13 records the value modification with the writing process. At logon, Sysmon Event ID 1 shows winlogon.exe or userinit.exe spawning an unexpected child, and Event ID 7 shows a Notify DLL loaded into the logon process.

Detection rule hint:

Alert when Userinit or Shell is set to anything other than its known-good default, or when any value is written under ...\Winlogon\Notify. The strongest signal is an appended executable path in Userinit/Shell pointing to a user-writable directory, or winlogon.exe/userinit.exe spawning a non-system child process.

Votes

Comments(0)