CVE-2022-21882
Win32k — ConsoleWindow flag misinterprets WndExtra causing type confusion EoP
Exploited in the Wild
This vulnerability was exploited in the wild before or shortly after patching.
Summary
| Field | Value |
|---|---|
| Driver | win32kbase.sys |
| Vulnerability Class | Type Confusion |
| Vulnerable Build | 10.0.22621.1 (RTM) |
| Fixed Build | 10.0.22621.382 (KB5019509) |
| Exploited ITW | Yes |
Affected Functions
xxxClientAllocWindowClassExtraBytesNtUserConsoleControl
Root Cause
The vulnerability exists in win32kbase.sys's handling of window objects when the
ConsoleWindow flag is set. When a window is created with specific flags, Win32k stores
extra data in the WndExtra region of the window structure. The ConsoleWindow flag causes
the kernel to interpret the WndExtra data differently than it would for a normal window.
Under normal circumstances the WndExtra region holds opaque, application-defined bytes,
but when the ConsoleWindow flag is present the kernel treats that same region as a pointer
to an internal tagWND structure.
An attacker can create a window with the ConsoleWindow flag and then manipulate the
WndExtra data through normal window management operations. Specifically, the
NtUserConsoleControl syscall can be used to set the ConsoleWindow flag on an existing
window, and then NtCallbackReturn can be abused during the
xxxClientAllocWindowClassExtraBytes callback to replace the window's WndExtra contents
with attacker-controlled data. Because the kernel still assumes the WndExtra region
contains a valid tagWND pointer, a subsequent operation dereferences the
attacker-supplied value as though it were a legitimate kernel object.
This is a classic type confusion: the same memory region is interpreted as two different
types depending on the code path. Along the normal window path the data is treated as raw
bytes, but along the console-window path it is cast to a tagWND* and dereferenced. The
mismatch between these two interpretations gives an attacker full control over a pointer
the kernel trusts.
AutoPiff categorizes this as type_confusion with detection rules:
object_type_validation_addedhandle_object_type_check_added
Exploitation
The type confusion provides a controlled pointer dereference inside the kernel, which can
be pivoted into an arbitrary write primitive. The exploitation flow proceeds as follows:
first, the attacker creates a normal window; second, they call NtUserConsoleControl to
set the ConsoleWindow flag on that window; third, during a subsequent
xxxClientAllocWindowClassExtraBytes callback they use NtCallbackReturn to inject a
pointer to a fake tagWND structure at a known user-mode address. When the kernel returns
from the callback it reads the fake tagWND and follows the attacker-controlled pointers
embedded within it.
The fake tagWND structure is carefully crafted so that its internal fields (such as the
pointer to the extra-bytes buffer and the associated offsets) redirect a later kernel write
to an arbitrary address. This yields a write-what-where primitive: the attacker can
overwrite any kernel memory location with a controlled value. The standard escalation
technique is to locate the current process's EPROCESS token field and overwrite it with
the token of a SYSTEM process, achieving a full Elevation of Privilege from a sandboxed or
low-privilege context to SYSTEM.
The exploit is highly reliable because the fake tagWND object can be placed at a
predictable address. The Win32k desktop heap is deterministic enough that a desktop heap
spray -- allocating many window objects of known size -- positions the fake structure at a
calculable offset, eliminating the need for a separate information leak in most scenarios.
Patch Analysis
The patch adds explicit object type validation when processing windows that carry the
ConsoleWindow flag. Before the fix, the kernel blindly cast the WndExtra data to a
tagWND* without verifying that the referenced memory actually belonged to a valid window
object. In the patched build, the code checks the object type before dereferencing: if the
WndExtra value does not point to a legitimate tagWND allocated through the expected
kernel pool path, the operation is rejected and the potentially corrupted pointer is never
followed.
AutoPiff detects this behavioral change through the object_type_validation_added and
handle_object_type_check_added rules, which flag functions where the patched binary
introduces type-tag or handle-table validation that was absent in the vulnerable build.
Detection
YARA Rule
rule CVE_2022_21882_Win32k {
meta:
description = "Detects vulnerable version of win32kbase.sys (pre-patch)"
cve = "CVE-2022-21882"
author = "KernelSight"
severity = "high"
strings:
$mz = { 4D 5A }
$driver_name = "win32kbase.sys" wide ascii nocase
$vuln_build = "10.0.22621.1" wide ascii
$func_alloc_extra = "xxxClientAllocWindowClassExtraBytes" ascii
$func_console_ctrl = "NtUserConsoleControl" ascii
condition:
$mz at 0 and $driver_name and $vuln_build and ($func_alloc_extra or $func_console_ctrl)
}
ETW Indicators
| Provider | Event / Signal | Relevance |
|---|---|---|
| Microsoft-Windows-Win32k | Window creation / class registration events | Detects creation of windows whose WndExtra region is later reinterpreted via the ConsoleWindow flag |
| Microsoft-Windows-Win32k | Console control operations | Fires when NtUserConsoleControl sets the ConsoleWindow flag on an existing window, the key step in triggering the type confusion |
| Microsoft-Windows-Kernel-Audit | Token modification events | Detects the EPROCESS token overwrite from standard user to SYSTEM following the write-what-where primitive |
| Microsoft-Windows-Security-Auditing | Event ID 4672 (Special privileges assigned) | Low-privilege GUI process suddenly acquiring SeDebugPrivilege or SeTcbPrivilege after Win32k callback manipulation |
| Microsoft-Windows-Security-Auditing | Event ID 4688 (Process creation) | Post-exploitation child process running as SYSTEM spawned from a desktop application context |
Behavioral Indicators
- A user-mode process creates a window, then calls
NtUserConsoleControlto set the ConsoleWindow flag on that window, and subsequently triggersxxxClientAllocWindowClassExtraBytescallback processing -- this specific syscall sequence is the hallmark of CVE-2022-21882 exploitation - During the
xxxClientAllocWindowClassExtraBytescallback, the process callsNtCallbackReturnwith crafted data to replace the WndExtra contents with a pointer to a faketagWNDstructure in user-mode memory, causing the kernel to dereference attacker-controlled data as a kernel object - Desktop heap spray activity: rapid creation of many window objects of identical size to position the fake
tagWNDstructure at a predictable offset within the Win32k desktop heap - The write-what-where primitive is used to overwrite the current process's EPROCESS token field, resulting in a process running with SYSTEM privileges from a context that was previously at medium or low integrity level
- Post-exploitation, the elevated process performs actions inconsistent with its original GUI application role, such as accessing LSASS memory, modifying system services, or spawning command shells as SYSTEM