CVE-2024-38256
Win32k -- uninitialized resource usage leaks kernel memory to user mode
Summary
| Field | Value |
|---|---|
| Driver | win32k.sys |
| Vulnerability Class | Information Disclosure |
| Vulnerable Build | 10.0.22621.3958 (KB5040527) |
| Fixed Build | 10.0.22621.4169 (KB5043076) |
| Exploited ITW | No |
Affected Functions
NtGdiGetGlyphOutlineGreGetGlyphOutlineInternal
Root Cause
The Win32k subsystem handles the Windows graphical interface at kernel level. Among its many responsibilities is font rendering, which involves querying glyph data through system calls like NtGdiGetGlyphOutline. This system call retrieves the outline or bitmap data for a specific glyph in a font, returning it to a user-mode buffer.
Inside GreGetGlyphOutlineInternal, the kernel allocates stack variables and heap buffers to hold intermediate glyph data during processing. The vulnerability is that these allocations are not fully initialized before being copied to the user-mode output buffer. Stack variables used as scratch space retain whatever data was previously on the kernel stack, and heap buffers may contain residual data from prior allocations.
When the function writes the glyph outline data to the output buffer, the gaps between populated fields contain this uninitialized residual data. If the residual data includes kernel pointers, token values, or fragments of other kernel structures, these leak to user mode. An attacker can call NtGdiGetGlyphOutline repeatedly with different glyph indices, collecting leaked data from each call to build a picture of the kernel's address space.
AutoPiff categorizes this as info_disclosure with detection rules:
stack_variable_initialization_addedkernel_pointer_scrubbing_added
Exploitation
This vulnerability is an information leak, not a code execution bug. Its value is as a KASLR bypass and kernel address oracle.
An attacker calls NtGdiGetGlyphOutline in a loop with varying glyph indices and fonts, scanning the returned buffers for values that look like kernel pointers (addresses above 0xFFFF800000000000 on x64). These leaked addresses reveal the kernel base address, the locations of specific kernel objects, or offsets within data structures.
The leaked information is then used as input to a separate privilege escalation exploit. Many kernel write-primitive bugs (pool overflows, type confusions, MDL handling errors) require knowledge of kernel addresses to be weaponized. Without a leak, the attacker must guess or brute-force addresses, making exploitation unreliable. With a reliable GDI-based leak, the same bugs become deterministic.
Patch Analysis
The fix in KB5043076 adds explicit initialization of stack variables and heap buffers in GreGetGlyphOutlineInternal before they are populated with glyph data. The patched code zeros the output buffer at the start of the function, ensuring that any bytes not explicitly written contain zeros rather than residual kernel data. Kernel pointer values that appear in intermediate processing are scrubbed before the buffer is copied to user mode.
AutoPiff detects this via stack_variable_initialization_added and kernel_pointer_scrubbing_added.
Detection
YARA Rule
rule CVE_2024_38256_Win32k {
meta:
description = "Detects vulnerable version of win32k.sys (pre-patch)"
cve = "CVE-2024-38256"
author = "KernelSight"
severity = "high"
strings:
$mz = { 4D 5A }
$driver_name = "win32k.sys" wide ascii nocase
$vuln_build = "10.0.22621.3958" wide ascii
$func_glyph = "NtGdiGetGlyphOutline" ascii
$func_internal = "GreGetGlyphOutlineInternal" ascii
condition:
$mz at 0 and $driver_name and $vuln_build and any of ($func_*)
}
ETW Indicators
| Provider | Event / Signal | Relevance |
|---|---|---|
| Microsoft-Windows-Kernel-Audit | Syscall audit events for GDI operations | Monitors NtGdiGetGlyphOutline invocations that trigger the uninitialized read path |
| Microsoft-Windows-Security-Auditing | Event 4688 (Process Creation) | Detects unexpected processes calling GDI glyph APIs at high frequency to harvest leaked kernel memory |
| Microsoft-Windows-Win32k | GDI object allocation / deallocation events | Tracks glyph outline buffer allocations where stack variables may not be fully initialized |
Behavioral Indicators
- Repeated calls to
NtGdiGetGlyphOutlinewith varied glyph indices from a low-privilege process, indicating systematic kernel memory harvesting - User-mode process reading GDI output buffers and scanning for kernel pointer patterns (addresses in the
0xFFFFupper range) to defeat KASLR - Anomalous GDI handle creation rates from processes that do not typically perform font rendering
- Process without GUI context invoking GDI subsystem calls through direct syscall stubs rather than
gdi32.dllexports - Information disclosure used as a precursor stage followed by a secondary exploit targeting a separate EoP vulnerability
Broader Significance
Win32k has been one of the richest vulnerability surfaces in the Windows kernel for over a decade. While most Win32k bugs focus on use-after-free or type confusion for privilege escalation, information disclosure bugs like CVE-2024-38256 play an equally important role in the exploit ecosystem. They provide the KASLR bypass that turns unreliable write primitives into deterministic exploits. The GDI font rendering path is particularly prone to information leaks because it processes complex, variable-length data structures with many fields, creating abundant opportunities for partial initialization gaps.