|
| 1 | +--- |
| 2 | +title: "Windows Hyper-V NT Kernel Integration VSP Elevation of Privilege Vulnerabilitys" |
| 3 | +subtitle: "Sample Subtitle" |
| 4 | +date: 2025-04-28 |
| 5 | +author: "Ghostbyt3" |
| 6 | +tags: ["1day", "vkrnlintvsp.sys", "windows", "kernel", "heap"] |
| 7 | +categories: ["1Day Breakdown"] |
| 8 | +authorbox: true |
| 9 | +pager: true |
| 10 | +toc: true |
| 11 | +sidebar: "right" |
| 12 | +layout: "single" |
| 13 | +showTableOfContents: true |
| 14 | +--- |
| 15 | + |
| 16 | +**CVE-2025-21333:** https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-21333 |
| 17 | +**Vulnerability Type:** Heap-based Buffer Overflow |
| 18 | +**Tested On:** vkrnlintvsp.sys - 10.0.22621.2506 |
| 19 | + |
| 20 | +## Description |
| 21 | + |
| 22 | +A vulnerability in the Windows Hyper-V NT Kernel Integration VSP driver exists due to a vulnerable function, `VkiRootAdjustSecurityDescriptorForVmwp()`, which can be invoked from user mode. This leads to a heap-based buffer overflow, ultimately resulting in privilege escalation. |
| 23 | + |
| 24 | +## Requirements |
| 25 | + |
| 26 | +To exploit this vulnerability, Windows Sandbox must be enabled in "Turn Windows features on or off". |
| 27 | + |
| 28 | + |
| 29 | + |
| 30 | +## Vulnerability analysis |
| 31 | + |
| 32 | +The vulnerability exists in the `VkiRootAdjustSecurityDescriptorForVmwp()` function of the `vkrnlintvsp.sys` driver, where the `Dacl` is user-controllable. The `memmove` operation uses `Dacl->AclSize` without verifying the user-supplied size, leading to a heap-based buffer overflow by copying unvalidated data into the Paged Pool. |
| 33 | + |
| 34 | +```c++ |
| 35 | +__int64 __fastcall VkiRootAdjustSecurityDescriptorForVmwp(void *a1, char a2) |
| 36 | +{ |
| 37 | + struct _ACL *v4; // rdi |
| 38 | + NTSTATUS ObjectSecurity; // ebx |
| 39 | + __int16 v6; // bx |
| 40 | + __int16 v7; // ax |
| 41 | + WORD v8; // bx |
| 42 | + struct _ACL *Pool2; // rax |
| 43 | + int v10; // esi |
| 44 | + unsigned __int8 DaclDefaulted[8]; // [rsp+20h] [rbp-50h] BYREF |
| 45 | + PACL Dacl; // [rsp+28h] [rbp-48h] BYREF |
| 46 | + PSID Sid; // [rsp+30h] [rbp-40h] BYREF |
| 47 | + PSID P; // [rsp+38h] [rbp-38h] BYREF |
| 48 | + PSECURITY_DESCRIPTOR SecurityDescriptor; // [rsp+40h] [rbp-30h] BYREF |
| 49 | + _OWORD v17[2]; // [rsp+48h] [rbp-28h] BYREF |
| 50 | + __int64 v18; // [rsp+68h] [rbp-8h] |
| 51 | + unsigned __int8 DaclPresent; // [rsp+A0h] [rbp+30h] BYREF |
| 52 | + unsigned __int8 MemoryAllocated; // [rsp+A8h] [rbp+38h] BYREF |
| 53 | + |
| 54 | + Dacl = 0LL; |
| 55 | + DaclDefaulted[0] = 0; |
| 56 | + SecurityDescriptor = 0LL; |
| 57 | + Sid = 0LL; |
| 58 | + P = 0LL; |
| 59 | + memset(v17, 0, sizeof(v17)); |
| 60 | + v18 = 0LL; |
| 61 | + DaclPresent = 0; |
| 62 | + v4 = 0LL; |
| 63 | + MemoryAllocated = 0; |
| 64 | + ObjectSecurity = ObGetObjectSecurity(a1, &SecurityDescriptor, &MemoryAllocated); |
| 65 | + if ( ObjectSecurity >= 0 ) |
| 66 | + { |
| 67 | + if ( !SecurityDescriptor ) |
| 68 | + goto LABEL_15; |
| 69 | + ObjectSecurity = RtlGetDaclSecurityDescriptor(SecurityDescriptor, &DaclPresent, &Dacl, DaclDefaulted); |
| 70 | + if ( ObjectSecurity < 0 ) |
| 71 | + goto LABEL_16; |
| 72 | + if ( DaclPresent && Dacl ) |
| 73 | + { |
| 74 | + ObjectSecurity = SeConvertStringSidToSid(L"S-1-5-83-0", &Sid); |
| 75 | + if ( ObjectSecurity >= 0 ) |
| 76 | + { |
| 77 | + ObjectSecurity = SeConvertStringSidToSid( |
| 78 | + L"S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704", |
| 79 | + &P); |
| 80 | + if ( ObjectSecurity >= 0 ) |
| 81 | + { |
| 82 | + v6 = RtlLengthSid(Sid); |
| 83 | + v7 = RtlLengthSid(P); |
| 84 | + v8 = Dacl->AclSize + v7 + v6 + 16; |
| 85 | + Pool2 = (struct _ACL *)ExAllocatePool2(256LL, v8, 1867671894LL); |
| 86 | + v4 = Pool2; |
| 87 | + if ( Pool2 ) |
| 88 | + { |
| 89 | + memmove(Pool2, Dacl, Dacl->AclSize); |
| 90 | + v4->AclSize = v8; |
| 91 | + v10 = a2 != 0 ? 2 : 0; |
| 92 | + ObjectSecurity = RtlAddAccessAllowedAce(v4, 2u, v10 + 2031617, Sid); |
| 93 | + if ( ObjectSecurity >= 0 ) |
| 94 | + { |
| 95 | + ObjectSecurity = RtlAddAccessAllowedAce(v4, 2u, v10 + 2031617, P); |
| 96 | + if ( ObjectSecurity >= 0 ) |
| 97 | + { |
| 98 | + ObjectSecurity = RtlCreateSecurityDescriptor(v17, 1u); |
| 99 | + if ( ObjectSecurity >= 0 ) |
| 100 | + { |
| 101 | + ObjectSecurity = RtlSetDaclSecurityDescriptor(v17, 1u, v4, 0); |
| 102 | + if ( ObjectSecurity >= 0 ) |
| 103 | + ObjectSecurity = ObSetSecurityObjectByPointer(a1, 4LL, v17); |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | + else |
| 109 | + { |
| 110 | + ObjectSecurity = -1073741801; |
| 111 | + } |
| 112 | + } |
| 113 | + } |
| 114 | + } |
| 115 | + else |
| 116 | + { |
| 117 | +LABEL_15: |
| 118 | + ObjectSecurity = 0; |
| 119 | + } |
| 120 | + } |
| 121 | +LABEL_16: |
| 122 | + if ( Sid ) |
| 123 | + ExFreePoolWithTag(Sid, 0); |
| 124 | + if ( P ) |
| 125 | + ExFreePoolWithTag(P, 0); |
| 126 | + if ( v4 ) |
| 127 | + ExFreePoolWithTag(v4, 0x6F526956u); |
| 128 | + ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated); |
| 129 | + return (unsigned int)ObjectSecurity; |
| 130 | +} |
| 131 | +``` |
| 132 | +
|
| 133 | +## Exploit |
| 134 | +
|
| 135 | +Tested on: Windows 11 23H2 |
| 136 | +Working POC: https://github.com/ghostbyt3/WinDriver-EXP/tree/main/CVE-2025-21333/POC |
| 137 | +
|
| 138 | + |
| 139 | +
|
| 140 | +## Acknowledgements |
| 141 | +
|
| 142 | +- The original [PoC](https://github.com/MrAle98/CVE-2025-21333-POC) was developed by [Alessandro Iandoli](https://x.com/MrAle_98), on which the above POC is created. |
| 143 | +- [Corentin Bayet](https://x.com/onlytheduck) and [Paul Fariello](https://x.com/paulfariello) for their outstanding explanation of [Windows Pool](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) |
| 144 | +- Yarden Shafir for the [IORING](https://windows-internals.com/one-i-o-ring-to-rule-them-all-a-full-read-write-exploit-primitive-on-windows-11/) method for an arbitrary Read/Write exploit primitive. |
| 145 | +
|
| 146 | +
|
| 147 | +**References:** |
| 148 | +
|
| 149 | +- https://infosecwriteups.com/cve-2025-21333-windows-heap-based-buffer-overflow-analysis-d1b597ae4bae |
| 150 | +- https://www.nccgroup.com/us/research-blog/cve-2021-31956-exploiting-the-windows-kernel-ntfs-with-wnf-part-1/ |
| 151 | +- https://github.com/synacktiv/Windows-kernel-SegmentHeap-Aligned-Chunk-Confusion/ |
0 commit comments