Skip to content

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

  • xxxClientAllocWindowClassExtraBytes
  • NtUserConsoleControl

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_added
  • handle_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 NtUserConsoleControl to set the ConsoleWindow flag on that window, and subsequently triggers xxxClientAllocWindowClassExtraBytes callback processing -- this specific syscall sequence is the hallmark of CVE-2022-21882 exploitation
  • During the xxxClientAllocWindowClassExtraBytes callback, the process calls NtCallbackReturn with crafted data to replace the WndExtra contents with a pointer to a fake tagWND structure 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 tagWND structure 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

References