Information

  • We know that HRGN handle which is used in GetDCEx is a shared GDI handle. We suspect that this handle is created when sending messages to the desktop. That result calling the syscall NtUserBeginPaint which create that shared handle. We retrieve the shared handle from peb->GdiSharedHandleTable.
  • We need to pass GetDCEx correct flags which is DCX_LOCKWINDOWUPDATE DCX_INTERSECTUPDATE DCX_WINDOW
  • In order to trigger the crash, it’s essential to enable special pool for win32kbase.sys and win32kfull.sys using the verifier.
  • This crash occur at win32kfull!GreUnlockRegion when trying to unlock freed memory

BugCheck:

DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL (d5)
Memory was referenced after it was freed.
This cannot be protected by try-except.
When possible, the guilty driver's name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arguments:
Arg1: fffffd28cb106f2c, memory referenced
Arg2: 0000000000000002, value 0 = read operation, 1 = write operation
Arg3: fffffd5c9962990b, if non-zero, the address which referenced memory.
Arg4: 0000000000000000, (reserved)

Stack at crash:

nt!DbgBreakPointWithStatus
nt!KiBugCheckDebugBreak+0x12
nt!KeBugCheck2+0x957
nt!KeBugCheckEx+0x107
nt!MiSystemFault+0x1938c0
nt!MmAccessFault+0x1a6
nt!KiPageFault+0x349
win32kbase!GreUnlockRegion+0xb
win32kfull!NtUserGetDCEx+0xce
nt!KiSystemServiceCopyEnd+0x25
win32u!NtUserGetDCEx+0x14
poc!repro+0x242 [r:\poc\poc\main.c @ 120]

Registers:

Some register values may be zeroed or incorrect.
rax=0000000000000000 rbx=0000000000000000 rcx=fffffd28cb106f20
rdx=0000000000000001 rsi=0000000000000000 rdi=0000000000000000
rip=fffffd5c9962990b rsp=ffffe00a73e6fa48 rbp=fffffd28cb106f20
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000001
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei ng nz na pe nc
win32kbase!GreUnlockRegion+0xb:
fffffd5c`9962990b f0ff490c        lock dec dword ptr [rcx+0Ch] ds:fffffd28`cb106f2c=????????

Reproduce:

  1. Compile the poc attached and copy it to the target machine
  2. Make sure Special pool is ON for win32kbase.sys and win32kfull.sys using the verifier
  3. Run the compiled poc and machine will crash with BSOD

PoC:
attached


Attachments:
main.c

References:
https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-1054