Skip to content

Commit 046c2cf

Browse files
committed
cve-2025-21333 - 1day breakdown
1 parent a31f496 commit 046c2cf

File tree

2 files changed

+151
-16
lines changed

2 files changed

+151
-16
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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+
![IMG](/img/cve-2025-21333/img.png)
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+
![IMG1](/img/cve-2025-21333/img1.png)
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/

content/1day-breakdowns/example.md

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)