Skip to content

CVE-2024-35250

Kernel Streaming — untrusted pointer dereference in IOCTL dispatch allows EoP

Exploited in the Wild

This vulnerability was exploited in the wild before or shortly after patching.

Summary

Field Value
Driver ks.sys
Vulnerability Class IOCTL Hardening
Vulnerable Build 10.0.22621.3672 (KB5037853)
Fixed Build 10.0.22621.3733 (KB5039212)
Exploited ITW Yes

Affected Functions

  • DispatchDeviceControl
  • KsDispatchDeviceControl

Root Cause

The Kernel Streaming (KS) driver ks.sys is a core component of the Windows multimedia subsystem. It manages the creation and communication of KS filter and pin objects, which represent audio, video, and other streaming devices. User-mode applications interact with KS objects by sending IOCTLs to their device handles, including property get/set requests that configure streaming behavior.

Several of the KS IOCTL handlers use METHOD_NEITHER as their I/O transfer method. Under METHOD_NEITHER, the I/O manager passes the raw user-mode input and output buffer pointers directly to the driver without copying them into system buffers or mapping them into kernel space. The driver is therefore responsible for probing and capturing these pointers before use. In the vulnerable code path within KsDispatchDeviceControl (and related internal dispatch routines), the handler retrieves a pointer from the user-supplied KSSTREAM_HEADER or KS property request structure and dereferences it without first calling ProbeForRead or ProbeForWrite to verify that the address lies within the user-mode address range.

Because the pointer is not validated, an attacker can supply a kernel-mode virtual address in place of the expected user-mode buffer pointer. The driver follows this pointer at PASSIVE_LEVEL with kernel privileges, reading from or writing to an arbitrary kernel address chosen by the attacker. This is a textbook "untrusted pointer dereference" vulnerability specific to METHOD_NEITHER IOCTL handlers that fail to probe user-supplied buffer addresses.

AutoPiff categorizes this as ioctl_hardening with detection rules:

  • method_neither_probe_added
  • ioctl_input_size_validation_added

Exploitation

The untrusted pointer dereference gives the attacker a direct kernel read/write primitive. Depending on the specific IOCTL code path triggered, the driver will either read data from the attacker-supplied kernel address (leaking kernel memory to user mode) or write attacker-controlled data to the supplied kernel address. This is an unusually powerful primitive because it does not require pool spraying, heap grooming, or race conditions -- the attacker directly specifies the target address and the operation proceeds deterministically.

This vulnerability was demonstrated at Pwn2Own Vancouver 2024 by researchers from DevCore and Star Labs as a local privilege escalation vector. The attack achieves escalation from a standard user account to SYSTEM privileges. Exploitation proceeds as follows: the attacker opens a handle to a KS device (accessible to low-privileged users), constructs a crafted IOCTL request using METHOD_NEITHER that embeds a kernel-mode address as the buffer pointer, and sends it via DeviceIoControl. The kernel dereferences the attacker-chosen address, providing the read or write operation.

With the kernel R/W primitive established, the attacker locates the current process's EPROCESS structure (using known offsets or NtQuerySystemInformation leaks), reads the SYSTEM process token, and overwrites the attacking process's token pointer with the SYSTEM token. The process then operates with full SYSTEM privileges. The entire chain requires no information leak from a separate vulnerability because the read primitive from the same bug provides the necessary kernel address disclosure.

Patch Analysis

The patch shipped in KB5039212 (build 10.0.22621.3733) added ProbeForRead and ProbeForWrite calls in the METHOD_NEITHER IOCTL dispatch paths within ks.sys. Before the fix, the driver directly dereferenced user-supplied buffer pointers; after the fix, each pointer is first validated to confirm it falls within the user-mode address range and is properly aligned. If the probe fails (indicating a kernel-mode address or misaligned pointer), the request is rejected with STATUS_ACCESS_VIOLATION. Additionally, the patch introduced input buffer size validation to ensure that the IOCTL input buffer meets the minimum size required for the expected property request structure, preventing underflow or malformed request parsing.

AutoPiff detects these changes through the method_neither_probe_added rule, which identifies the insertion of ProbeForRead/ProbeForWrite calls in IOCTL handlers that previously lacked them, and the ioctl_input_size_validation_added rule, which flags new comparisons of the input buffer length against expected structure sizes. Together, these rules capture the two core defensive changes introduced by the patch.

Detection

YARA Rule

rule CVE_2024_35250_ks_sys {
    meta:
        description = "Detects vulnerable version of ks.sys (pre-patch)"
        cve = "CVE-2024-35250"
        author = "KernelSight"
        severity = "high"
    strings:
        $mz = { 4D 5A }
        $driver_name = "ks.sys" wide ascii nocase
        $version = "10.0.22621.3672" wide ascii
        $dispatch = "KsDispatchDeviceControl" ascii
        $method_neither = { 83 ?? 03 }  // METHOD_NEITHER comparison
    condition:
        $mz at 0 and $driver_name and $version and ($dispatch or $method_neither)
}

ETW Indicators

Provider Event / Signal Relevance
Microsoft-Windows-KSVC KS IOCTL dispatch events Monitors Kernel Streaming control requests to ks.sys device objects, including METHOD_NEITHER property requests
Microsoft-Windows-Kernel-Audit Privilege escalation events Detects token manipulation following successful exploitation of the R/W primitive
Microsoft-Windows-Security-Auditing Event 4672 — Special privileges assigned Fires when the attacking process acquires SYSTEM token privileges after token swap
Microsoft-Windows-Kernel-IoTrace IOCTL dispatch tracing Captures DeviceIoControl calls to KS filter/pin objects with METHOD_NEITHER transfer type
Microsoft-Windows-Kernel-Process Process token change Detects unexpected token replacement on a user-mode process

Behavioral Indicators

  • A low-privileged user-mode process opens a handle to a Kernel Streaming device (\Device\KSENUM#...) and issues rapid METHOD_NEITHER IOCTLs via DeviceIoControl with unusually large or kernel-range buffer pointers
  • The IOCTL input buffer contains pointer values in the kernel address range (above 0xFFFF800000000000 on x64), indicating an attempt to direct the driver to dereference arbitrary kernel memory
  • Process token replacement occurs without a corresponding logon event: the process EPROCESS.Token field changes from a low-privilege token to the SYSTEM token mid-execution
  • NtQuerySystemInformation calls (class SystemHandleInformation or SystemModuleInformation) precede the IOCTL exploitation, used to leak kernel object addresses for targeting the R/W primitive
  • A single user-mode process escalates from medium/low integrity to SYSTEM integrity without spawning a child process or invoking a privileged service

References