Disclosure or Patch Date: Jan 13, 2022
Product: Microsoft Windows
Affected Versions: Before the January 2022 patch update. Windows 10,Windows 11,Windows Server 2019,Windows server 2022 (Currently only full exploits found under windows10 and windows server 2019)
First Patched Version: CVE-2022-21882,January 2022 patch update.
Issue/Bug Report: N/A
Patch CL: N/A
Bug-Introducing CL: N/A
Reporter(s): RyeLv (@b2ahex)
Exploit sample: N/A
Did you have access to the exploit sample when doing the analysis? Yes
Bug class: win32k object type confusion
The attacker can call the relevant GUI API at the user_mode to make the kernel call like xxxMenuWindowProc, xxxSBWndProc, xxxSwitchWndProc, xxxTooltipWndProc, etc. These kernel functions will trigger a callback xxxClientAllocWindowClassExtraBytes. Attacker can intercept this callback through hook xxxClientAllocWindowClassExtraBytes in KernelCallbackTable,and use the NtUserConsoleControl method to set the ConsoleWindow flag of the tagWND object, which will modify the window type.
After the final callback, the system does not check whether the window type has changed, and the wrong data is referenced due to type confusion. The difference before and after the flag modified is that before setting the flag, the system thinks that tagWND.WndExtra saves a user_mode pointer; after the flag is set, the system thinks that tagWND.WndExtra is the offset of the kernel desktop heap,and attacker can control this offset, then cause out-of-bounds R&W.
The patch added check code. Before the xxxClientAllocWindowClassExtraBytes method ends, the system will check the ConsoleWindow flag(0x800). If the flag is set, xxxClientAllocWindowClassExtraBytes returns false.
Thoughts on how this vuln might have been found (fuzzing, code auditing, variant analysis, etc.):
Code auditing for user-mode callbacks related functions is feasible, and there is a lot of excellent research on this attack surface.
(Historical/present/future) context of bug:
(The terms exploit primitive, exploit strategy, exploit technique, and exploit flow are defined here.)
Exploit strategy (or strategies):
Through the vulnerability to achieve out-of-bounds read and write, and modify the kernel object of another window to obtain the kernel arbitrary address read and write primitive
1.Trigger the vulnerability to get out-of-bounds write, modify the cbWndExtra of the window object to 0x0FFFEFFF, so use the window object WndExtra can access a large memory.
2.Modify the WS_CHILD flag of another window and set a specially constructed Menu(fake menu) for the other window
3.Get arbitrary read primitive by GetMenuBarInfo API and fake menu.
4.Use the SetWindowLongPtrA API to modify the ExtraBytes of another window object to get arbitrary write primitive.
5.Find the system eprocess with PID 4 through EPROCESS ActiveProcessLinks
6.Read the system token and replace the current process token
Known cases of the same exploit flow:
It is the same as the previous CVE-2021-1732 exploit, and is a common way of exploiting privilege escalation vulnerabilities.
Part of an exploit chain?
The Next Steps
Areas/approach for variant analysis (and why):
Here's a quick way to check CVE-2021-1732 & CVE-2022-21882:
After the xxxClientAllocWindowClassExtraBytes callback is completed, determine whether the window object contains the 0x800 flag before the function return.
when flag has been set,it can be identified according to the calling path of xxxClientAllocWindowClassExtraBytes.
When the stack path is xxxCreateWindowEx -> xxxClientallocxxxxExtraBytes (CVE-2021-1732).
In other cases it is (CVE-2022-21882).
Found variants: N/A
Ideas to kill the bug class:
Improve the kernel 0day bounty, let more security researchers participate in the bounty program, and help the system to be more perfect.
Ideas to mitigate the exploit flow:
Mitigating common exploit techniques.
Other potential improvements:
Improve the kernel 0day bounty.
0-day detection methods
What are potential detection methods for similar 0-days? Meaning are there any ideas of how this exploit or similar exploits could be detected as a 0-day?
Detect strings in memory for dynamically get addresses/offset.
Detect the behavior of user-mode process loading kernel modules like ntoskrnl.exe.
Check if KernelCallbackTable is hooked.