1041 words
5 minutes
EDR killing

Exploiting Vulnerable Drivers for EDR Evasion: A Technical Deep Dive into BYOVD Attacks

Disclaimer

This article is intended for educational and informational purposes only, specifically to raise awareness about the techniques used in Bring Your Own Vulnerable Driver (BYOVD) attacks and how they can be mitigated.

The information provided should not be used to engage in unauthorized activities, exploit vulnerabilities, or compromise systems. Unauthorized use of this knowledge may violate local, national, or international laws and regulations. I disclaim all responsibility for any misuse of the information presented.

Readers are strongly encouraged to use this knowledge responsibly and ethically, adhering to applicable laws.

The cybersecurity landscape continues to grapple with the escalating sophistication of Bring Your Own Vulnerable Driver (BYOVD) attacks, a technique that weaponizes legitimate but flawed kernel drivers to disable Endpoint Detection and Response (EDR) solutions. This article examines the technical mechanics of these attacks, focusing on the process of reverse engineering drivers to identify and exploit Input/Output Control (IOCTL) interfaces for executing privileged operations such as process termination.

Kernel-Level Exploitation Fundamentals#

BYOVD attacks exploit the inherent trust placed in signed drivers by operating systems. Attackers leverage drivers with inadequate input validation in their IOCTL handlers to achieve kernel-mode code execution. The end goal is often to terminate EDR processes using native API functions like ZwTerminateProcess, which operates at the kernel level and bypasses user-mode security hooks.

The attack chain begins with obtaining administrative privileges, typically through credential theft or privilege escalation vulnerabilities. Once elevated access is secured, the attacker deploys a vulnerable driver often one deprecated but still signed to the target system. Legitimate drivers from security vendors (e.g., anti-malware tools) are frequent targets due to their inherent permissions to interact with system processes.

Find a vulnerable driver#

Living Off The Land Drivers is a curated list of Windows drivers used by adversaries to bypass security controls and carry out attacks, referenced with imports attributes, certificates and so on. So we can basically looking at recently signed drivers by certificate date and look at the ZwTerminateProcess imported function from a driver in the list.

And you can simply download the driver from a github repository link:

Reverse Engineering Drivers for IOCTL Exploitation#

We need first to identifying the IOCTL codes and corresponding handler functions that enable unauthorized kernel operations. Here’s a structured approach to reverse engineering a driver for this purpose:

  1. Driver Acquisition and Static Analysis - Done ✅ Attackers first obtain the target driver (e.g., aswArPot.sys from Avast or RTCore64.sys from MSI Afterburner). Tools like IDA Pro or Ghidra, disassemble the driver binary to reveal its internal logic with codeflow and pseudo code. The primary focus is on the driver’s dispatch routine, which handles IRP_MJ_DEVICE_CONTROL requests—the mechanism for processing IOCTLs.

  2. Identifying the Dispatch Function - Time to quick reversing 🤓 In Windows drivers, the DriverEntry routine initializes a DRIVER_OBJECT structure containing function pointers for handling major operations. The MajorFunction array at index IRP_MJ_DEVICE_CONTROL (typically 0x0E) points to the IOCTL handler. Locating this function allows attackers to analyze how IOCTL codes are processed.

    IDA Pro

    For analyzing kernel drivers and low-level system components, IDA Pro provides critical capabilities that the free IDA version lacks, particularly when dealing with Windows Driver Model (WDM) code, IOCTL handlers, and kernel-mode exploitation vectors. Pro version iclude:

    • DriverEntry Routines: Visualize driver initialization logic.
    • IRP Handlers: Decompile IRP_MJ_DEVICE_CONTROL dispatch functions.
    • IOCTL Parsing: Automatically map control codes to handler logic.
  3. Retrieving IOCTL Codes
    IOCTL codes are 32-bit values structured as CTL_CODE(DeviceType, Function, Method, Access). By reviewing cross-references to the IOCTL handler, analysts identify codes that trigger privileged actions. For example, a driver might use a custom code like 0x9988C094 to invoke ZwTerminateProcess.

  4. Analyzing Handler Logic
    The handler function typically validates parameters, such as input/output buffer sizes and process handles, before performing operations. Vulnerabilities arise when these checks are insufficient. For instance, a driver might accept a process handle from user mode without verifying the caller’s privileges, allowing arbitrary process termination.

  5. Crafting Exploit
    With the IOCTL code and required parameters identified, attackers write a user-mode program to open a handle to the driver’s device object and send a crafted IOCTL request. This request includes the target process ID and triggers the driver’s handler to call ZwTerminateProcess with kernel privileges.

Practical example#

From IDA Pro, we’ve loaded the RTCore64.sys driver and navigated to the DriverEntry function, which reveals the device name the driver will create.

Imports tab shows various kernel-mode functions available to the driver:

Since our goal is to find a way to terminate EDR processes, we’re specifically looking for the ZwTerminateProcess function. Let’s load another view to search for this API:

To discover where this function is called within the driver, press x to display cross-references:

This brings us to the graph view of the function containing the ZwTerminateProcess call. Press F5 to decompile this block:

After renaming variables for clarity, we can see the function accepts a process handle parameter and passes it directly to ZwTerminateProcess:

Now we need to trace backward to find what calls this function. At the top of the decompiler window, locate the function name and use cross-references again to find its callers:

That led us to a dispatch function containing a switch statement that handles different IOCTL codes. We can now identify which IOCTL code triggers our process termination function:

From this analysis, we’ve successfully identified the IOCTL code that, when sent to the RTCore64 device, will invoke ZwTerminateProcess on a process list. 🤪

Now let’s kayakobeme this EDR/AV process:

Defensive Strategies and Mitigations#

Countering BYOVD attacks demands a multi-faceted approach:

  • Hypervisor-Protected Code Integrity (HVCI): Enabling HVCI restricts kernel-mode code execution to drivers validated by Microsoft’s code integrity policies, effectively blocking unauthorized drivers.
  • IOCTL Monitoring and Filtering: Security tools can intercept and inspect IOCTL requests, flagging anomalies such as process termination attempts from non-system processes.
  • Driver Allowlisting: Organizations should maintain a strict inventory of permitted drivers and block all others via Group Policy or endpoint protection platforms.
  • Certificate Pinning: Implementing custom certificate trust lists prevents drivers signed with revoked or unauthorized certificates from loading.
  • Kernel-Mode Threat Detection: Advanced EDR solutions now monitor for suspicious driver behavior, such as direct calls to ZwTerminateProcess or modifications to protected processes.

Conclusion#

BYOVD attacks represent a paradigm shift in offensive cybersecurity, exploiting the blurred line between legitimate and malicious kernel-mode operations. Defenders must adopt proactive measures, including rigorous driver vetting, kernel monitoring, and hardware-enforced security policies. As attackers continue to innovate, the cybersecurity community’s ability to anticipate and neutralize these threats will determine the resilience of modern enterprise environments.

Sources#

EDR killing
https://xsec.fr/posts/evasion/edr-killing/
Author
Xsec
Published at
2025-04-14
License
CC BY-NC-SA 4.0