Cache the Frames, Catch the Vulnerabilities in Kernel Streaming

Angelboy Yang (Senior Security Researcher · DEVCORE)

CODE BLUE 2025 · Day 1 · Track 1 (Hall B)

Overview

In this compelling talk at CODE BLUE, Angelboy Yang, a Senior Security Researcher at DEVCORE, delves deep into the intricate world of Windows Kernel Streaming (KS), a critical framework within the Windows operating system responsible for handling multimedia data from devices like webcams and microphones. Building upon previous research that uncovered over a dozen vulnerabilities, including a "passing to kernel" primitive discussed at CODE BLUE last year, Yang reveals a new wave of highly exploitable vulnerabilities. These discoveries highlight fundamental flaws in how the kernel processes multimedia frames, particularly concerning memory management and buffer handling.

Watch on YouTube

Visual summary for Cache the Frames, Catch the Vulnerabilities in Kernel Streaming by Angelboy Yang
Visual summary for Cache the Frames, Catch the Vulnerabilities in Kernel Streaming by Angelboy Yang

Key moments

  1. 0:00 Introduction to Windows Kernel Streaming and Research
  2. 4:40 Understanding Kernel Streaming Frames and MDLs
  3. 10:50 MDL Cache Buffer Overflow Vulnerability Explained
  4. 16:00 MDL Chain Mismatch Leading to Buffer Overflow
  5. 27:00 Demo: Arbitrary Physical Memory Write to EOP
  6. 36:40 Demo: Arbitrary Memory Write via Lookaside List Corruption
  7. 38:00 Key Takeaways and Future Research Directions

Cache the Frames, Catch the Vulnerabilities in Kernel Streaming

Speakers: Angelboy Yang (Senior Security Researcher, DEVCORE)

Conference: CODE BLUE

YouTube: https://www.youtube.com/watch?v=vi4oyDcihiM

Overview

In this compelling talk at CODE BLUE, Angelboy Yang, a Senior Security Researcher at DEVCORE, delves deep into the intricate world of Windows Kernel Streaming (KS), a critical framework within the Windows operating system responsible for handling multimedia data from devices like webcams and microphones. Building upon previous research that uncovered over a dozen vulnerabilities, including a "passing to kernel" primitive discussed at CODE BLUE last year, Yang reveals a new wave of highly exploitable vulnerabilities. These discoveries highlight fundamental flaws in how the kernel processes multimedia frames, particularly concerning memory management and buffer handling.

The presentation focuses on several novel bug classes that emerge during the lifecycle of kernel streaming frames, from their allocation and caching to their alignment and interaction with various kernel components. Yang meticulously dissects issues such as MDL (Memory Descriptor List) cache buffer overflows, MDL mismatches in 32-bit to 64-bit request processing, uninitialized PFN (Page Frame Number) arrays leading to arbitrary physical memory writes, and frame buffer misalignments that can be chained with Lookaside Lists for powerful arbitrary memory write primitives. The implications of these vulnerabilities are severe, often leading to Elevation of Privilege (EOP), allowing an attacker to gain full control over the compromised system.

This talk is crucial for security researchers, Windows kernel developers, and incident responders alike. It not only exposes specific weaknesses in a widely used Windows subsystem but also provides a masterclass in identifying complex memory corruption issues that arise from subtle logical flaws and incorrect API usage in highly optimized kernel code. The detailed technical explanations and proof-of-concept demonstrations underscore the ongoing importance of scrutinizing core operating system components for latent security risks.

Background

▶ Watch: Introduction to Windows Kernel Streaming and Research (0:00)

To understand the vulnerabilities discussed, it's essential to grasp the fundamentals of Windows Kernel Streaming. When a user interacts with multimedia devices like a webcam or microphone on a Windows system, the operating system needs an efficient way to transfer large volumes of data (e.g., video frames, audio samples) between the device and system memory. Microsoft provides the Kernel Streaming (KS) framework for this purpose. KS defines a model where multimedia class drivers interact with device hardware through abstract objects.

Key components in the KS architecture include:

  • KS Filters: Representing the device itself (e.g., a webcam).
  • KS Pins: Endpoints on a filter used for reading or writing data streams. To interact with a device, an application opens a device handle, then creates a pin on the corresponding filter.
  • KSec.sys: The entry point for kernel streaming requests, responsible for converting 32-bit requests to 64-bit requests and sometimes pre-allocating memory.
  • KS.sys: The core kernel streaming library, handling request forwarding and stream-related functions.

When reading data, such as an image from a webcam, the system allocates K-frames to store and describe the multimedia data. Crucially, these frames often involve a frame buffer to hold the actual imagery. To manage these buffers efficiently, especially when mapping them between user space and kernel space, MDLs (Memory Descriptor Lists) are employed. An MDL describes the physical memory mapping of a virtual address, ensuring that both user and kernel buffers can refer to the same physical memory, facilitating high-speed data access.

Prior research by Angelboy Yang and DEVCORE, including a presentation at CODE BLUE last year on "passing to kernel" vulnerabilities, demonstrated that KS can be a rich source of security flaws. These previous findings often involved the ability to re-send IOCTL requests as a proxy, bypassing security checks and leading to issues like arbitrary function calls. This initial success motivated a deeper dive into kernel streaming, which subsequently uncovered the more than 20 frame-handling vulnerabilities that form the core of this presentation.

Key Findings

▶ Watch: MDL Cache Buffer Overflow Vulnerability Explained (10:50)

The research uncovered several distinct and highly impactful bug classes within the Windows Kernel Streaming framework, primarily revolving around the handling of multimedia frames and MDLs:

  • MDL Cache Buffer Overflow: A logical flaw in the MDL caching mechanism where only the buffer address is compared, not its size, leading to situations where a smaller-sized MDL is reused for a larger buffer request, resulting in an out-of-bounds write.
  • MDL Mismatch: An inconsistency arising from the interaction between KSec.sys (handling 32-bit requests) and KS.sys when the MDL cache flag is used with multiple frames. This can cause a mismatch between the expected buffer size in the KSSTREAM_HEADER and the actual size of the mapped MDL, leading to buffer overflows.
  • Forgotten Lock in MDL (Uninitialized PFN Array): A critical error in MDL handling where the MmProbeAndLockPages API is omitted, leaving the PFN (Page Frame Number) array within an MDL uninitialized. This can be exploited through heap spraying to achieve an arbitrary physical memory write, a powerful primitive for Elevation of Privilege.
  • Frame Buffer Misalignment with Lookaside Lists: A subtle bug in the KsCreateAllocator function, allowing non-standard alignment masks. When these misaligned buffers are freed and managed by Lookaside Lists, the internal Next pointer can be corrupted due to the misalignment, eventually leading to an arbitrary memory write primitive.

These findings collectively demonstrate that despite its maturity, Windows Kernel Streaming remains a fertile ground for discovering critical vulnerabilities, many of which are exploitable for system-level compromise.

Technical Deep Dive

▶ Watch: MDL Chain Mismatch Leading to Buffer Overflow (16:00)

The core of Angelboy Yang's presentation lies in the detailed technical dissection of each vulnerability class. The process of reading data from a device like a webcam typically involves several steps: opening a device, creating a pin on a filter, setting the pin to a "run" state (activating the device), and then sending an IOCTL to read frames. When reading a stream, a KSSTREAM_HEADER structure is provided as input, specifying crucial information like the DataBuffer address and BufferSize. The kernel then maps a frame buffer based on this information, often using an MDL to describe the physical memory. The KSSTREAM_HEADER also includes OptionsFlags to specify frame attributes, such as enabling the MDL cache.

MDL Cache Buffer Overflow

The MDL caching mechanism is designed to speed up frame processing by reusing previously allocated frame buffers and their corresponding MDLs. This is enabled by setting an OptionsFlag to 0x8000 or 0x10000. When a request with the cache flag is processed for the first time, KS.sys allocates an MDL, maps the frame buffer, and stores an MDL cache entry containing both the MDL and the user-space buffer address. For subsequent requests with the cache flag, KS.sys first checks the MDL cache. The vulnerability arises because KS.sys only compares the user-space buffer address when looking for a suitable MDL in the cache; it does not check the size.

This logical flaw allows for a classic buffer overflow scenario:

  1. First Request: An attacker sends an IOCTL with the cache flag, providing a KSSTREAM_HEADER with a smaller BufferSize, for example, 0x1000 bytes. The kernel allocates a 0x1000 byte frame buffer and caches its MDL.
  2. Second Request: The attacker sends another IOCTL using the same user-space buffer address but specifies a larger BufferSize, for example, 0x20000 bytes, still with the cache flag enabled.
  3. KS.sys finds the cached MDL based on the matching address, but it reuses the MDL that was originally for a 0x1000 byte buffer. However, the KSSTREAM_HEADER's BufferSize (0x20000) is stored in the new K-frame structure.
  4. When the device worker attempts to copy 0x20000 bytes of data into the frame buffer, it uses the size from the K-frame but the underlying MDL maps only 0x1000 bytes. This leads to a buffer overflow as the copy operation writes beyond the bounds of the actual mapped buffer.

MDL Mismatch

This vulnerability highlights the complexities of 32-bit to 64-bit request handling and flag interactions. When a 32-bit IOCTL request is sent to a KS device, KSec.sys acts as an intermediary. It converts the request to 64-bit and, for standard frame requests, pre-allocates the necessary MDLs and maps frame buffers. However, if the KSSTREAM_HEADER has the MDL cache flag set, KSec.sys skips this MDL pre-allocation step.

The issue becomes critical when multiple frames are submitted in a single request, and some frames have the cache flag while others do not.

  1. KSec.sys Processing: For a batch of KSSTREAM_HEADERs, KSec.sys processes each. If a header doesn't have the cache flag, KSec.sys allocates and maps an MDL. If it does have the cache flag, KSec.sys skips MDL allocation.
  2. KS.sys Processing: The request is then passed to KS.sys. KS.sys also iterates through the KSSTREAM_HEADERs. If a header doesn't have the cache flag, KS.sys assumes the MDL is already ready (because KSec.sys would have handled it) and skips allocation. If it does have the cache flag, KS.sys then allocates an MDL (or retrieves it from the cache).
  3. The Mismatch: Due to this differing logic, it's possible for the order of MDLs in the internal MDL chain to be different from the order of KSSTREAM_HEADERs. For example, the first KSSTREAM_HEADER might be paired with the MDL intended for the second, and vice-versa.
  4. Exploitation: When the device worker copies data, it refers to the BufferSize in the KSSTREAM_HEADER associated with a K-frame, but uses the buffer mapped by the (misaligned) MDL. If a header with a large BufferSize is paired with an MDL mapping a small buffer, a buffer overflow occurs during the data copy, similar to the MDL cache overflow.

Forgotten Lock in MDL (Uninitialized PFN Array)

This vulnerability stems from a fundamental misuse of Windows kernel memory management APIs related to MDLs. A typical and secure flow for using an MDL to access user memory involves:

  1. IoAllocateMdl: Allocates the MDL structure.
  2. MmProbeAndLockPages: Validates the user buffer, locks the physical memory pages, and populates the PFN (Page Frame Number) array within the MDL with the physical addresses.
  3. MmMapLockedPagesSpecifyCache: Maps a kernel virtual address to the physical pages described by the MDL's PFN array.
  4. MmUnlockPages and IoFreeMdl: Release resources.

The "forgotten lock" bug occurs when MmProbeAndLockPages is skipped. In such a scenario, the PFN array within the allocated MDL remains uninitialized data. If MmMapLockedPagesSpecifyCache is then called directly on this uninitialized MDL, it attempts to use garbage values from the PFN array to map memory. This often leads to a BSOD (Blue Screen of Death).

Yang found that this mistake is prevalent in Kernel Streaming. Specifically, when KS.sys handles an MDL chain, it might only check the MdlFlags of the first MDL to see if it's locked, assuming the entire chain is similarly processed. If a subsequent MDL in the chain was not properly probed and locked (e.g., due to specific flag combinations or execution paths), its PFN array will contain uninitialized data.

Exploitation: IoAllocateMdl typically allocates from the non-paged pool. By employing heap spraying techniques (e.g., using named pipes to allocate a large number of objects with controlled data), an attacker can influence the contents of the uninitialized PFN array. When MmMapLockedPagesSpecifyCache is called on such an MDL, it will map physical memory based on the attacker-controlled PFNs. This provides a powerful arbitrary physical memory write primitive.

To make this primitive fully controlled, Yang identified the buffer mode attribute in KS. If buffer mode is enabled, KS.sys allocates an intermediate buffer, copies device data into it, and then, upon stopping streaming, copies the content back from this intermediate buffer into the frame buffer. By mapping the frame buffer to a controlled physical address (e.g., NT kernel image, which was observed to have a fixed physical address on 24H2 systems), and then using buffer mode, the attacker gains an arbitrary physical memory write with fully controlled data, enabling direct modification of kernel code for Elevation of Privilege.

Frame Buffer Misalignment with Lookaside Lists

This final vulnerability involves a subtle interaction between a custom allocator, buffer alignment, and kernel Lookaside Lists. KS allows developers to pre-allocate a set of frame buffers using KsCreateAllocator and configure them with KSALLOCATOR_FRAMING, including specifying an AlignmentMask. KS.sys implements its own allocation function, internally using ExAllocatePool. If an AlignmentMask is provided, KS.sys adds a 4-byte value (representing the "ping size") in front of the frame buffer.

The bug lies in the AlignmentMask validation: KS.sys only checks if the mask is greater than 0xFFF, meaning an attacker can supply values less than 0xFFF that are not a power of 2 minus 1 (e.g., 0x7). This leads to a misaligned buffer. For example, if a buffer is allocated with an alignment mask that causes a 1-byte padding, the buffer address might end in 0x8 instead of 0x0 or 0xF.

This misaligned buffer becomes problematic when it interacts with Lookaside Lists. Lookaside Lists are per-processor caches for fixed-size memory blocks, designed for fast allocation and deallocation. A critical property of Lookaside Lists is that their entries (pointers to memory chunks) must be 16-byte aligned. When ExAllocatePool returns a chunk, it aligns the address to 16 bytes. Similarly, when freeing memory back to a Lookaside List, the free routine aligns the first entry in the list.

The Exploit Chain:

  1. An attacker configures KsCreateAllocator with an AlignmentMask that causes a misaligned buffer (e.g., 0x7), leading to a padding byte.
  2. Multiple frame buffers are pre-allocated. Due to the padding, these buffers might have addresses ending in 0x8.
  3. When these misaligned buffers are freed back into the Lookaside List, the Next pointer (which is 8 bytes) of a freed entry can be written into the padding area of the next entry in the list.
  4. This corruption causes the Next pointer to point to a misaligned address, specifically one that now falls within the "ping" area (where the 4-byte ping size is stored). When viewed as a 64-bit pointer, this corrupted Next pointer might become a user-space address (e.g., 0xA8000).
  5. Exploitation: By controlling the user-space memory at that address, an attacker can construct a fake Lookaside List entry. Through a sequence of allocations and frees, the attacker can manipulate the Lookaside List to eventually return a user-controlled address as a "free" chunk. This effectively transforms a seemingly minor alignment bug into an arbitrary memory write primitive. With this primitive on Windows 232 (likely 22H2), standard EOP techniques can be applied.

Demo / Proof of Concept

▶ Watch: Demo: Arbitrary Memory Write via Lookaside List Corruption (36:40)

Angelboy Yang provided compelling live demonstrations of the most critical vulnerabilities, showcasing their real-world impact.

The first demonstration highlighted the exploitation of the Forgotten Lock in MDL vulnerability. Yang successfully achieved Elevation of Privilege (EOP) on a Windows 24H2 system. The demo commenced with a normal user account and, without requiring any prior information leaks, leveraged the uninitialized PFN array bug to gain an arbitrary physical memory write. By strategically using the buffer mode feature, the attacker was able to inject fully controlled data into the targeted physical memory region, ultimately leading to direct modification of kernel code and immediate system compromise. This demonstrated the power of turning a seemingly crash-inducing bug (BSOD from uninitialized PFNs) into a full EOP by controlling the memory layout.

The second demonstration focused on the Frame Buffer Misalignment with Lookaside Lists vulnerability. This exploit also resulted in Elevation of Privilege on a Windows 232 (likely Windows 22H2) system. Starting from a standard user account with a webcam device attached, the exploit involved setting up the custom allocator with a malicious alignment mask to trigger the Lookaside List corruption. This allowed the attacker to gain an arbitrary memory write primitive, which was then used to achieve EOP. Both demos showcased the sophisticated chain of logic bugs and memory manipulation required to escalate privileges from seemingly innocuous flaws within the kernel streaming subsystem.

Defensive Implications

▶ Watch: Key Takeaways and Future Research Directions (38:00)

The vulnerabilities disclosed in this talk underscore critical areas for both developers and system defenders to focus on:

  • Rigorous Input Validation: Kernel drivers, especially those handling user-mode input like KSSTREAM_HEADER structures, must perform exhaustive validation of all parameters—addresses, sizes, and flags. Relying solely on address comparison without size checks (as seen in the MDL cache overflow) or assuming correct pre-processing (as in the MDL mismatch) is dangerous.
  • Correct MDL Handling: Developers must strictly adhere to the documented MDL (Memory Descriptor List) usage pattern: always IoAllocateMdl, then MmProbeAndLockPages (or an equivalent API to lock pages and populate PFNs), then MmMapLockedPagesSpecifyCache, and finally MmUnlockPages and IoFreeMdl. Skipping MmProbeAndLockPages leads to uninitialized PFN arrays and critical vulnerabilities. Microsoft's own documentation examples should be reviewed for accuracy and completeness.
  • Careful with Caching Mechanisms: While designed for performance, custom caching mechanisms, like the MDL cache, introduce complexity and new attack surfaces. Their implementation must account for all possible edge cases, especially when combining different flags or processing modes.
  • Alignment and Memory Allocators: Any custom memory allocation routines or interactions with kernel memory management components like Lookaside Lists must pay extreme attention to memory alignment. Subtle misalignments, even by a single byte, can lead to pointer corruption and powerful arbitrary memory write primitives when interacting with fixed-size, aligned structures.
  • 32-bit to 64-bit Request Handling: The interaction between 32-bit and 64-bit request pathways, particularly how different components (KSec.sys, KS.sys) handle shared state (like MDLs), is a source of complex logical bugs. Developers must ensure consistent state management across these boundaries.
  • Patch Management: System administrators and users should prioritize applying security updates from Microsoft. These vulnerabilities are patched, and timely updates are crucial to protect against exploitation.
  • Security Audits: The findings suggest that other drivers, especially those dealing with multimedia or complex memory operations, may contain similar MDL-related issues. Security researchers and internal development teams should conduct thorough audits of such components.

Key Takeaways

  • Windows Kernel Streaming remains a rich attack surface: Despite being a mature component, it still harbors complex, exploitable vulnerabilities.
  • MDL handling is critically complex and error-prone: Incorrect or incomplete usage of MDL APIs is a common source of severe memory corruption bugs, including uninitialized PFN arrays.
  • Caching mechanisms can introduce new bug classes: Performance optimizations, like the MDL cache, must be implemented with extreme care, as logical flaws (e.g., incomplete validation) can lead to buffer overflows.
  • Subtle alignment issues can be weaponized: Frame buffer misalignments, especially when interacting with kernel memory allocators like Lookaside Lists, can be chained to achieve powerful arbitrary memory write primitives.
  • Understanding Windows API implementation is key: Deep knowledge of how Windows APIs (e.g., IoAllocateMdl, MmProbeAndLockPages) are implemented and how different kernel components (KSec.sys, KS.sys) interact is crucial for finding and exploiting vulnerabilities.
  • "Useless" bugs can be turned into powerful primitives: What might appear as a simple crash (BSOD) or a minor memory alignment issue can be transformed into an arbitrary physical memory write or arbitrary memory write through creative exploitation techniques like heap spraying and logical manipulation.

About the Speaker(s)

Angelboy Yang, also known as MJ Boy, is a Senior Security Researcher at DEVCORE. His primary focus lies in Windows vulnerability research, particularly within kernel components. He is a seasoned presenter, having previously shared his findings on "passing to kernel" vulnerabilities in Windows kernel streaming at CODE BLUE, demonstrating his ongoing expertise and dedication to uncovering critical security flaws within the operating system.

Reviews

Dr. Zero (Offensive Security Researcher) — MUST SEE

This is elite-tier Windows kernel exploitation research. Angelboy drops four distinct bug classes in a single subsystem, each with its own exploitation path, culminating in two working EOP demos on current Windows builds. The MDL handling bugs alone would make a strong talk; the Lookaside List corruption via alignment is genuinely clever.

Heather Calloway (CISO) — STRONG ACCEPT

Deep kernel exploitation research in a core Windows subsystem. Four distinct bug classes, two live EOP demos, patched vulnerabilities. Every CISO with a Windows fleet should know this attack surface exists—your patching cadence and endpoint detection strategy need to assume kernel streaming is actively targeted.

→ Top-rated talks at CODE BLUE 2025

All talks from CODE BLUE 2025