Sunday, November 29, 2015

NtUserBeginPaint Stack Memory Disclosure

Few month ago I was researching in Windows Kernel using binary diffing technique. I have discovered that it is possible to disclose portions of uninitialized kernel stack memory to user-mode applications in Windows 7-8 through the win32k!NtUserBeginPaint (*Patched*) system call. This leaks PAINTSTRUCT fields that were not filled out/overwritten properly by NtUserBeginPaint. More specifically, exactly 16 bytes of uninitialized kernel stack memory are copied to ring-3 in one of two execution contexts. User application should pass two arguments (HWND, LPPAINTSTRUCT) to NtUserBeginPaint system call. The HWND argument that has been sent in this function will first be validated with ValidateHwndEx function:

The internal win32k!BeginPaint function then filled out a local copy of the structure (PAINTSTRUCT field) on the kernel stack.


Src variable is PAINTSTRUCT field to store PAINT information. But, I have found that 16 bytes of that structure are uninitialized. When it is copied back to user-mode in its entirety, its contents disclose leftover kernel stack bytes containing potentially sensitive information (kernel address etc.).

After calling memcpy function some bytes are clearly visible in the below hex dump. These bytes are contained a number of kernel-space addresses etc.

kd> dd eax < === user space now contains kernel stack information

010af3c4  0401037d 00000000 00000000 00000000
010af3d4  000000a0 00000035 00000000 00000000
010af3e4  fffffffe 8f71f864 81970e17 ae7f7b80
010af3f4  ae7f7b8c ae7f7b80 ae7f7b74 10000000
010af404  41414141 41414141 41414141 41414141
010af414  41414141 41414141 41414141 41414141
010af424  41414141 41414141 41414141 41414141
010af434  41414141 41414141 41414141 41414141

kd> u 81970e17 
nt!KiSystemServicePostCall:
81970e17 f6456c01        test    byte ptr [ebp+6Ch],1
81970e1b 7434            je      nt!KiSystemServicePostCall+0x3a (81970e51)
81970e1d 8bf0            mov     esi,eax
81970e1f ff153041a781    call    dword ptr [nt!_imp__KeGetCurrentIrql (81a74130)]
81970e25 0ac0            or      al,al
81970e27 0f85c9010000    jne     nt!KiSystemCallExit2+0x97 (81970ff6)
81970e2d 8bc6            mov     eax,esi
81970e2f 648b0d24010000  mov     ecx,dword ptr fs:[124h]



stack contained address:
 8f71f864 <==== win32k!NtUserCreateWindowEx 
 81970e17 <==== nt!KiSystemServicePostCall address


The proof-of-concept program demonstrates the disclosure by spraying the kernel stack with a large number of 0x41 ('A') marker bytes, and then calling the affected system call. An example output is as follows:

No comments:

Post a Comment