CVE-2024-30084 — Kernel Streaming IOCTL_KS_PROPERTY Double Fetch

Last updated: 2026-04-12
Severity: High
Component: ks.sys (Kernel Streaming)
Bug Class: TOCTOU / Double Fetch (Neither I/O)
Privilege Escalation: User → SYSTEM
Patch: July 2024 Patch Tuesday

Vulnerability Summary

IOCTL_KS_PROPERTY uses Neither I/O buffering, meaning Type3InputBuffer remains in user memory throughout processing. ks.sys’s KspPropertyHandler reads the KSPROPERTY GUID once to validate the property set, then UnserializePropertySet reads the same user buffer again. An attacker can race between these two reads to swap the GUID, bypassing validation and triggering CVE-2024-35250’s logic flaw (arbitrary call) via MSKSSRV — which is available on every Windows system including Hyper-V VMs without audio devices.


Root Cause Analysis

Neither I/O = No Buffer Capture

IOCTL_KS_PROPERTY is defined with METHOD_NEITHER. This means:

  • The I/O Manager does NOT copy user input into a kernel buffer
  • Irp->Parameters.DeviceIoControl.Type3InputBuffer points directly to user-mode memory
  • The user can modify this memory at any time, including between kernel reads

Double Read Pattern

KspPropertyHandler:
   1. Copies KSPROPERTY from Type3InputBuffer into SystemBuffer  [READ 1]
   2. Checks if GUID (SystemBuffer) is in the device's property set list
   3. If KSPROPERTY_TYPE_UNSERIALIZESET flag → calls UnserializePropertySet

UnserializePropertySet:
   4. Reads Type3InputBuffer AGAIN as the input for new IOCTL         [READ 2]
   5. Calls KsSynchronousIoControlDevice with this re-read data

Race window: Between step 2 (GUID validated from SystemBuffer) and step 4 (GUID re-read from user memory for new IOCTL). The user changes the buffer between these two reads.


Exploitation Technique

Race Setup

  1. Thread 1 (exploit): Continuously sends IOCTL_KS_PROPERTY with:
    • GUID = KSPROPSETID_Service (supported by MSKSSRV — always available)
    • Flags = KSPROPERTY_TYPE_UNSERIALIZESET
  2. Thread 2 (racer): Monitors for step 2 completion, then swaps:
    • Buffer GUID → KSPROPSETID_DrmAudioStream
    • Function pointer at +0x38&RtlSetAllBits
    • UserBuffer&fake_RTL_BITMAP over Token->Privileges

Result

When race succeeds:

  • Step 2: KSPROPSETID_Service is validated (MSKSSRV supports it) ✓
  • Step 4: KSPROPSETID_DrmAudioStream is used for new KernelMode IOCTL
  • ksthunk sees KernelMode + KSPROPSETID_DrmAudioStream → arbitrary call [CVE-2024-35250]

Environment Independence

This makes the combined chain (CVE-2024-30084 + CVE-2024-35250) work on every Windows system:

  • Without audio device: use MSKSSRV for KSPROPSETID_Service validation
  • Hyper-V VMs without audio hardware: fully exploitable via MSKSSRV

Key Primitives Used

  • Neither I/O double fetch (classic race)
  • MSKSSRV KSPROPSETID_Service as race-win validation bypass vehicle
  • CVE-2024-35250 arbitrary call as payload

Proof-of-Concept Notes

  • 100% reliable once CVE-2024-35250 payload is in place; race may need a few attempts
  • No audio device required — MSKSSRV provides the property set for step 1 validation

References

  • Angelboy (DEVCORE), “Streaming vulnerabilities from Windows Kernel - Proxying to Kernel - Part I”, devco.re, 2024-08-23
  • MSRC: CVE-2024-30084 — msrc.microsoft.com/update-guide/vulnerability/CVE-2024-30084
  • See also: Cve 2024 35250 (the triggered vulnerability)
  • See also: Kernel Streaming, Race Conditions