Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
BYOVD-DriverKiller — 驱动逆向与漏洞利用 | Kitploit
工具/GitHubGitHub/alex3o/byovd-driverkiller
漏洞利用逆向工程后渗透利用二进制分析学习与教育红队
GitHubalex3o/byovd-driverkiller

BYOVD-DriverKiller

驱动逆向与漏洞利用

查看仓库
831431年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

BYOVD-DriverKiller

⚠️ 警告:本项目严格用于教育和演示目的。它不打算在恶意环境中使用。目标是学习逆向工程方法论以及 Windows 驱动的利用步骤。


我将在这里说明我为解决 d1rk(SaadAhla) https://github.com/SaadAhla 提出的练习所采取的方法,该练习涉及对一个合法的、已签名的、并且不在阻止列表(HVCI、LOLBIN...)中的驱动执行逆向工程和利用。 一个 C 程序可用于通过此内核模式驱动终止系统上任何活动进程,我将在下文详细介绍其工作原理。

POC-BYOD

📃 用法:DriverKiller.exe <进程名.exe> [-d]

选项 -d:允许在利用后从系统中删除服务和驱动。

必须在目标机器上启用测试签名模式,因为驱动的证书已过期。


第 1 部分 - 逆向工程:

该练习提供了一个 .sys 文件,以其 SHA-256 哈希命名。 第一步是使用 IDA 打开该文件。
IDA 免费可用。只需访问 Hex-Rays 网站生成许可证并下载软件即可。

首先列出驱动的 IAT(导入地址表),并查找我们感兴趣的 API 调用:ZwTerminateProcess。

screen1-git

双击 ZwTerminateProcess 后,IDA 会将我们重定向到该函数的已编译代码。选中该条目并显示交叉引用后,即可获得调用它的驱动函数列表。

screen2-git

我们可以观察到,是位于偏移量 1CE 处的函数 sub_12EF4 使用了 ZwTerminateProcess。双击后,IDA 会显示其编译后的代码。

screen11-git

反编译代码显示了对 ZwOpenProcess(打开指向目标进程的句柄)和 ZwTerminateProcess(通过该句柄终止进程)的调用。

查阅 ZwOpenProcess 的文档 (https://learn.microsoft.com/fr-fr/windows-hardware/drivers/ddi/ntddk/nf-ntddk-zwopenprocess) 后,可以看到 ClientID 参数是一个指向目标进程 PID 的指针。

在上面一行,ClientId.UniqueProcess 使用变量 v22 进行初始化。后者就在上面定义:

root@kitploit:~
v22 = (void )((_QWORD *)i + 10);

要理解这个赋值,需要识别变量 i 和 +10 字段。

screen3-git

在该函数更上方,我们可以看到对带有 SYSTEM_PROCESS_INFORMATION 参数的 ZwQuerySystemInformation 的调用。我们还可以理解到,i 是使用变量 v6 遍历此结构条目的迭代器。

根据 ZwQuerySystemInformation 的文档:(https://learn.microsoft.com/en-us/windows/win32/sysinfo/zwquerysysteminformation),该函数返回一个数组,其中包含系统中每个活动进程的一个条目。

SYSTEM_PROCESS_INFORMATION 结构在此处描述:https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation

root@kitploit:~
typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset;
    ULONG NumberOfThreads;
    BYTE Reserved1[48];
    UNICODE_STRING ImageName;
    KPRIORITY BasePriority;
    HANDLE UniqueProcessId;
    PVOID Reserved2;
    ULONG HandleCount;
    ULONG SessionId;
    PVOID Reserved3;
    SIZE_T PeakVirtualSize;
    SIZE_T VirtualSize;
    ULONG Reserved4;
    SIZE_T PeakWorkingSetSize;
    SIZE_T WorkingSetSize;
    PVOID Reserved5;
    SIZE_T QuotaPagedPoolUsage;
    PVOID Reserved6;
    SIZE_T QuotaNonPagedPoolUsage;
    SIZE_T PagefileUsage;
    SIZE_T PeakPagefileUsage;
    SIZE_T PrivatePageCount;
    LARGE_INTEGER Reserved7[6];
} SYSTEM_PROCESS_INFORMATION;

提醒:Windows x64 上某些类型的大小

  • ULONG = 4 字节
  • USHORT = 2 字节
  • HANDLE = 8 字节
  • PWSTR = 8 字节
  • KPRIORITY(LONG 的 typedef)= 4 字节
  • UNICODE_STRING = 16 字节,因为其结构如下:
root@kitploit:~
  typedef struct _UNICODE_STRING {
    USHORT Length;        -> 2      
    USHORT MaximumLength; -> + 2 = 4
    PWSTR  Buffer;        -> + 8 = 12 (12 n'est pas un multiple de 8 donc padding de 4 ajouté en amont de Buffer) = 16
} UNICODE_STRING;

计算 UniqueProcessId 的偏移量:

root@kitploit:~
    ULONG NextEntryOffset;        -> 4
    ULONG NumberOfThreads;        -> + 4 = 8
    BYTE Reserved1[48];           -> + 48 = 56
    UNICODE_STRING ImageName;     -> + 16 = 72
    KPRIORITY BasePriority;       -> + 4 = 76 (76 n'est pas un multiple de 8 donc padding de 4 ajouté) = 80
    HANDLE UniqueProcessId;       -> + 8 = 88

因此,UniqueProcessId 成员位于偏移量 0x50(十进制 80)处。

查看变量 v22 的赋值,可以看到 i 被转换为 QWORD(8 字节)指针

root@kitploit:~
v22 = (void )((_QWORD *)i + 10);
因此 v22 对应 i 的地址 + 10 * 8 = 80 字节。所以该变量确实包含从 SYSTEM_PROCESS_INFORMATION 结构检索到的 PID。

为了确定哪个 PID 会被传递给 ZwTerminateProcess,需要分析这个赋值周围的条件。

screen4-git

我们可以看到,首先会检索进程映像名称:

root@kitploit:~
v9 = (wchar_t )((_QWORD *)i + 8);
因为 v9 = i 的地址 + 8 × 8 = 64 字节。这对应于 ImageName 成员的 Buffer,因为该成员位于偏移量 56 + 2(USHORT)+ 2(USHORT)+ 4(填充)= 64 处。

根据下面的操作和循环,可以推测,在参数中传递的进程名称(a2)与系统上活动进程 v9/String 之间进行了比较。

root@kitploit:~
sub_1C078(String, v9, (int)v13);
v17 = strupr(a2);
v18 = strupr(String);

因此,参数 a2 应当包含要经由 ZwTerminateProcess 终止的进程名称。我们注意到 a2 是函数 sub_12EF4 的一个参数。为了进一步分析,需要查看该函数的引用(为了更好的可读性,我将其重命名为 ZwTerminateProcessCaller)。

screen5-git

可以看到 ZwTerminateProcessCaller 被函数 sub_13624 在偏移量 61A 处调用。

screen6-git

在分析这个反编译代码之前,我将查找函数 sub_13624(重命名为 ZwTerminateProcessCallerCaller)的引用,以确保该代码确实是在从用户模式调用 DeviceIoControl API 之后使用的。

screen§-git

可以看到 ZwTerminateProcessCallerCaller 被函数 sub_14130(重命名为 ZwTerminateProcessCallerCallerCaller ...对我们来说幸运的是,这是进入入口点之前的最后一个 😅)调用。

screen7-git

可以看到 ZwTerminateProcessCallerCallerCaller 被函数 sub_1A4A8 在偏移量 306 处调用。

screen8-git

我们找到了 ZwTerminateProcessCallerCallerCaller 的分配位置:

root@kitploit:~
memset64(DriverObject->MajorFunction, (unsigned __int64)ZwTerminateProcessCallerCallerCaller, 0x1Cu);
这意味着该函数被分配给 MajorFunction 表的所有条目(0x1B = 27,并且存在 28 个主要 IRP)。

screen9-git

在回到函数 sub_13624(别名 ZwTerminateProcessCallerCaller)之前,我们获取 Symbolic Name 和 Device Name(此处相同):Viragtlt。

screen12-git

回到 ZwTerminateProcessCallerCaller,我们注意到它的第二个参数(即 a2)对应于 MasterIrp->AssociatedIrp.SystemBuffer。

screen13-git

就在调用 ZwTerminateProcessCaller 的上方,我们找到了 IOCTL 代码:-2106392528(十六进制:0x82730030)。

借助这些信息,我们可以推断,要利用此驱动,需要向该驱动发送一个 DeviceIoControl API 调用,并在 SystemBuffer 中包含要终止的进程名称。


🔷 通过逆向工程获得的信息:

  • IOCTL 代码:0x82730030
  • 设备名称:Viragtlt
  • 符号链接名称:Viragtlt
  • SystemBuffer 必须包含目标进程的名称

第 2 部分 - 利用

要利用此驱动(如果它已安装在目标机器上并处于活动状态),需要打开一个指向该驱动的句柄,然后使用包含要终止进程名称的 Buffer 进行 DeviceIoControl API 调用。
针对这个练习,我开发了一个 C 项目,它:

  • 检查驱动是否存在于系统中并处于活动状态(使用特定的服务名称):
    • 如果是,程序通过 DeviceIoControl API 调用来利用该驱动。
    • 如果否,程序从资源中提取驱动,将其部署到用户的桌面,创建一个活动服务,然后通过 DeviceIoControl API 调用来利用该驱动。(需要管理员权限,因为会创建服务。)
  • 如果驱动存在于系统中但服务未启动,程序会尝试启动该服务,然后通过 DeviceIoControl API 调用来利用它。

我还添加了一个 -d 选项,用于在利用后从系统中删除服务和驱动。

以下是 C 程序在其完整执行周期中的行为:

git

AV/EDR 规避

在这种情况下,DriverKiller.exe 不会被 Microsoft Defender 检测到,无论是静态还是动态。

在这里,规避的意义不大,因为被利用的驱动具有过期的证书,因此在现实条件下几乎无法使用。

但为了更好的隐蔽性,本可以实现:

  • 通过自定义实现 GetProcAddress 和 GetModuleHandle 来隐藏 IAT 表中的某些 API 调用
  • 更接近内核以执行 API 调用(直接/间接系统调用)
  • 反虚拟机 / 反调试技术

截至 2025 年 8 月 29 日对驱动的检测结果(已有结果,出于显而易见的原因我没有向 VirusTotal 提交任何内容):

image

⚠️ 本项目是在学习框架内完成的。它可能包含不准确之处或错误。欢迎任何建议、更正或讨论!😃 感谢 d1rk(SaadAhla):https://github.com/SaadAhla !

下载工具