Windows resolves a DLL by walking a defined search order, and some elevated processes request libraries that do not exist on disk or look first in a directory ordinary users can write (T1574.001). Dropping a DLL there yields code execution at the process’s privilege level. The attacker’s write and the victim’s load are both observable, and the pair is the best detection.
Signals at a Glance
| Signal | Where | ATT&CK |
|---|---|---|
| SYSTEM or service process loading a DLL from Users, ProgramData or Temp | Sysmon 7, EDR image loads | T1574.001 |
| Unsigned DLL loaded by a signed Windows service host | Sysmon 7 Signed field | T1574.001 |
| DLL created by a non-admin in an executable directory used by a service | Sysmon 11 | T1574.001 |
| DLL created and loaded by a privileged process within minutes | Sysmon 11 plus 7 | T1574.001 |
| Known phantom DLL names appearing on disk | File inventory, EDR | T1574.001 |
The Load Event
Image-load telemetry is voluminous, so constrain it to the interesting case: a SYSTEM process loading from a user-writable location. Joining to the earlier file write gives you the planted-and-loaded sequence:
// Microsoft Defender (KQL) - SYSTEM process loading a DLL from user-writable paths
DeviceImageLoadEvents
| where InitiatingProcessAccountSid == "S-1-5-18"
| where FileName endswith ".dll"
| where FolderPath startswith @"C:\Users" or FolderPath startswith @"C:\ProgramData"
or FolderPath has "Temp"
| join kind=leftouter (
DeviceFileEvents
| where ActionType == "FileCreated" and FileName endswith ".dll"
| project CreatedAt=Timestamp, DeviceId, FolderPath, FileName, CreatorSid=InitiatingProcessAccountSid
) on DeviceId, FolderPath, FileName
| project Timestamp, DeviceName, InitiatingProcessFileName, FolderPath, FileName, SHA256, CreatedAt, CreatorSid
// tune/validate: legitimate software under ProgramData loads its own DLLs; allowlist by signer.
Finding Hijackable Loads Before Attackers Do
The same logic works as a Sigma rule on Sysmon Event 7, and as a proactive audit. In a lab, Process Monitor filtered to Result is NAME NOT FOUND, Path ends with .dll, and the user set to SYSTEM lists the phantom DLL candidates; any whose parent directory is writable is a finding:
title: Elevated Process Loads Unsigned DLL from Writable Path
logsource:
product: windows
category: image_load
detection:
selection:
User: 'NT AUTHORITY\SYSTEM'
Signed: 'false'
ImageLoaded|contains:
- '\Users\'
- '\ProgramData\'
- '\Temp\'
condition: selection
level: medium
# tune/validate: requires Sysmon image-load logging, which is high volume; scope by user and path.
- Known phantom DLL cases, such as wlbsctrl.dll loaded by the IKE and AuthIP service on some builds, are documented in the community; check that your builds do not search writable locations for them.
- Prefer fixing ACLs on service directories and enabling safe DLL search mode over trying to blocklist DLL names.
- Application control such as WDAC or AppLocker in audit mode shows which unsigned DLLs elevated processes load, and gives you an allowlist to enforce later.
Use the SigmaHQ image-load rules, Elastic’s prebuilt rules for DLL side-loading and unsigned DLL loads by system processes, Procmon for audit, HijackLibs for known hijackable DLL names, and Atomic Red Team T1574.001 for validation. Baseline your own environment — third-party software loads many unsigned libraries legitimately.
Build Detections That Fire
Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.
- Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
- Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
- 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Stay ahead of emerging threats. Get notified when we publish new intelligence reports and advisories.
Subscribe to Alerts