CVE-2024-35250 — Kernel Streaming KSPROPSETID_DrmAudioStream Arbitrary Call
Last updated: 2026-04-12
Severity: High
Component: ks.sys / ksthunk.sys (Kernel Streaming)
Bug Class: Access Mode Mismatch (Proxying to Kernel) → Arbitrary Call
Privilege Escalation: User → SYSTEM
Patch: July 2024 Patch Tuesday
Vulnerability Summary
A logic vulnerability in Windows Kernel Streaming where ks.sys’s UnserializePropertySet function calls KsSynchronousIoControlDevice with KernelMode(0), allowing user-supplied data to reach ksthunk.sys’s CheckIrpForStackAdjustmentNative with elevated RequestorMode. The ksthunk handler for KSPROPSETID_DrmAudioStream performs an arbitrary call using user-controlled data when RequestorMode == KernelMode. This was used in Pwn2Own Vancouver 2024 by DEVCORE (Angelboy). The vulnerability existed since Windows 7 — approximately 20 years.
Root Cause Analysis
Step 1: KsSynchronousIoControlDevice Always Uses KernelMode
ks.sys’s UnserializePropertySet (triggered by KSPROPERTY_TYPE_UNSERIALIZESET flag) copies user data and re-issues the IOCTL internally:
// ks.sys UnserializePropertySet:
New_KsProperty_req = ExAllocatePoolWithTag(NonPagedPoolNx, InSize, 0x7070534Bu);
memmove(New_KsProperty_req, CurrentStackLocation->Type3InputBuffer, InSize);
status = KsSynchronousIoControlDevice(
CurrentStackLocation->FileObject,
0, // ← KernelMode hardcoded
CurrentStackLocation->Parameters.DeviceIoControl.IoControlCode,
New_KsProperty_req,
InSize,
OutBuffer,
OutSize,
&BytesReturned);
This sets Irp->RequestorMode = KernelMode(0) in the new IRP.
Step 2: ksthunk Bypasses User Check
ksthunk.sys’s CheckIrpForStackAdjustmentNative checks for KSPROPSETID_DrmAudioStream:
if (*Type3InputBuffer->Set == KSPROPSETID_DrmAudioStream
&& !type3inputbuf.Id
&& (type3inputbuf.Flags & 2)) {
if (irp->RequestorMode) { // UserMode = 1 → error
return STATUS_INVALID_DEVICE_REQUEST;
}
// KernelMode = 0 → proceeds to arbitrary call!
result = (*(PFUNC)(Type3InputBuffer + 0x38))(
*UserBuffer, // first arg: user-controlled
0,
v19);
}
The function pointer at Type3InputBuffer + 0x38 is fully user-controlled, as is the first argument.
Exploitation Technique
kCFG Bypass via RtlSetAllBits
Since arbitrary function pointers are blocked by kCFG (Kernel Control Flow Guard), the attacker must use a valid CFG target. RtlSetAllBits (exported from ntoskrnl.exe) accepts a _RTL_BITMAP:
struct _RTL_BITMAP {
ULONG SizeOfBitMap;
ULONG* Buffer; // pointer to bitmap data
};
By setting Buffer → Token->Privileges.Enabled and SizeOfBitMap = large_value, RtlSetAllBits sets all privilege bits in the token → enables all privileges including SeDebugPrivilege.
EoP Flow
- Open audio device with
KSPROPSETID_DrmAudioStreamsupport (any audio device; mic/headphone) - Send
IOCTL_KS_PROPERTYwithKSPROPERTY_TYPE_UNSERIALIZESETflag andKSPROPSETID_DrmAudioStreamGUID ks.sysUnserializePropertySetcallsKsSynchronousIoControlDevice(KernelMode)ksthunkseesKernelMode→ proceeds toType3InputBuffer+0x38function callType3InputBuffer+0x38 = &RtlSetAllBits(valid kCFG target)*UserBuffer = &fake_RTL_BITMAP(first arg points to bitmap overToken->Privileges)- All privilege bits set →
SeDebugPrivilegeenabled OpenProcess(PROCESS_ALL_ACCESS, winlogon_pid)→CreateProcessinheriting SYSTEM token
Key Primitives Used
KsSynchronousIoControlDevicewith hardcodedKernelMode(design flaw)RtlSetAllBitsas kCFG-valid arbitrary write gadget- Token privilege abuse (all privileges enabled)
Mitigations Bypassed
kCFG(bypassed via legitimate CFG targetRtlSetAllBits)kASLR(bypassed viaNtQuerySystemInformation)SMEP(kernel code executes from kernel, no user shellcode)
Proof-of-Concept Notes
- Requires an audio device with
KSPROPSETID_DrmAudioStream(any mic, headphones, audio interface) - On Hyper-V without audio: use CVE-2024-30084 double fetch to trigger via MSKSSRV (present everywhere)
- Combined chain (CVE-2024-30084 + CVE-2024-35250) works on any Windows system
- 100% reliable exploitation, no races required for CVE-2024-35250 alone
Patch Analysis
Microsoft patched in July 2024. The fix validates RequestorMode in the KSPROPSETID_DrmAudioStream handler path before performing the function call — or restricts the conditions under which the call is made regardless of RequestorMode.
References
- Angelboy (DEVCORE), “Streaming vulnerabilities from Windows Kernel - Proxying to Kernel - Part I”, devco.re, 2024-08-23
- MSRC: CVE-2024-35250 — msrc.microsoft.com/update-guide/vulnerability/CVE-2024-35250
- Pwn2Own Vancouver 2024 — zerodayinitiative.com
- See also: Cve 2024 30084 (double fetch companion)
- See also: Kernel Streaming (full attack surface)
