Loading kernel drivers is a “Holy Grail” operation for attackers. It grants Ring 0 privileges, allowing for persistence, EDR blinding (“Killer Drivers”), or Bring Your Own Vulnerable Driver (BYOVD) attacks.
While the end result is the same (code running in the kernel), the forensic trails differ significantly depending on the tool used:
sc.exe: The direct, noisy approach via Service Control Manager.
devcon.exe: The stealthier approach leveraging the Windows Plug and Play (PnP) subsystem.The Service Control utility allows users to register a driver explicitly as a service. This is the “classic” method, often monitored by standard security baselines.
The attacker executes a command to register the driver. The key indicator is the type= kernel flag pointing to a user-writable location.
sc create DBUtilDrv2 binPath= C:\users\public\DBUtilDrv2.sys type= kernel
sc start DBUtilDrv2
Process Creation (Event ID 1): Look for sc.exe spawned by cmd.exe or powershell.exe containing binPath= (non-system directory) and type= kernel.
Registry (Event ID 12/13): sc.exe writes directly to the Services hive.
Key: HKLM\System\CurrentControlSet\Services\<DriverName>
Values: Type = 0x1 (Kernel Driver), ImagePath = Path to malicious driver.
Security Log: Event 4697 (A Service Was Installed) is the highest fidelity indicator here.
Red Team Note: This method is “loud.” Modifications to
HKLM\...\Servicesare heavily scrutinized. We use this only when we know logging is weak or we need speed over stealth.
devcon.exe (Device Console) is part of the Windows Driver Kit. Attackers use it to bypass standard service monitoring by abusing the SetupAPI and Plug and Play stacks. This leaves a much more complex, scattered footprint.
Instead of talking to the Service Controller directly, devcon requests the installation of an INF file for a “Root” (virtual) device.
devcon.exe install C:\Temp\DBUtilDrv2.inf Root\DBUtilDrv2
1. Process Anomalies The parent process is often powershell.exe triggering devcon.exe. However, the actual work is handed off to DrvInst.exe (Driver Install) and svchost.exe -k DcomLaunch (DeviceInstall service).
2. The Phantom Device (Registry) Unlike sc.exe, devcon does not initially write to the Services hive. It creates a “Phantom” device node.
Key: HKLM\System\CurrentControlSet\Enum\ROOT\<DeviceID>
Indicator: Look for new keys in Enum\ROOT that map to unknown hardware IDs.
3. Driver Staging (Registry) Before installation, the driver is staged in the Driver Store.
Key: HKLM\DRIVERS\DriverDatabase\DriverPackages
Value OemPath: This is a smoking gun. It reveals the original source of the INF file (e.g., C:\Users\Target\Documents\). Legitimate drivers usually originate from System paths.
4. File System & “Timestomping” devcon creates GUID-named folders in %TEMP% and %SystemRoot%\System32\DriverStore\Temp.
Anomaly: SetupAPI often preserves the vendor’s timestamp from the driver package. You might see a “new” temp file created with a timestamp from 2 years ago (setup behavior that mimics timestomping).
| Feature | sc.exe (Service Control) | devcon.exe (Plug & Play) |
| Mechanism | Direct Service Creation | SetupAPI / Driver Store Staging |
| Key Process | sc.exe |
devcon.exe -> DrvInst.exe |
| Primary Registry | HKLM\...\Services |
HKLM\...\Enum\ROOT & DriverDatabase |
| File Artifacts | Driver file stays in place | Staged to %SystemRoot%\DriverStore |
| Stealth Level | Low (Well known) | High (Complex artifact trail) |
Successfully loading a driver usually leads to one of two outcomes:
BYOVD (Bring Your Own Vulnerable Driver): The attacker loads a legitimate, signed driver (like DBUtilDrv2) that has known vulnerabilities. They then exploit this driver to elevate privileges. Signature verification is useless here because the driver is valid.
Killer Drivers: The attacker loads a custom malicious driver specifically designed to terminate EDR processes (e.g., killing MsMpEng.exe via kernel API ZwTerminateProcess).
// Step 1: Find sc/devcon
let DriverTools = DeviceProcessEvents
| where Timestamp > ago(1d)
| where (FileName =~ "sc.exe" and ProcessCommandLine has_any ("type=kernel", "type= kernel"))
or (FileName =~ "devcon.exe" and ProcessCommandLine has "install")
| project TimeProc=Timestamp, DeviceName, ToolName=FileName, CommandLine=ProcessCommandLine;
// Step 2: Find Kernel Driver Load
let DriverLoads = DeviceEvents
| where Timestamp > ago(1d)
| where ActionType == "DriverLoad"
| project TimeLoad=Timestamp, DeviceName, DriverName=FileName, DriverPath=FolderPath, DriverHash=SHA1;
DriverTools
| join kind=inner (DriverLoads) on DeviceName
// Alert if the driver loaded within 5 minutes of the tool running
| where (TimeLoad - TimeProc) between (0min .. 5min)
| project TimeProc, TimeLoad, DeviceName, ToolName, CommandLine, DriverName, DriverPath, DriverHash
Subscribe now to keep reading and get access to the full archive.