Information

  • This crash occurs as result of Use After Free
  • We noticed that on windows 10 it is caught during safe unlinking and on windows 8.1 when the free chunk is used
  • We suspect that this behaviour is due to the type isolation mitigation

Windbg Windows 8.1:

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: fffff90147046cb0, memory referenced
Arg2: 0000000000000000, value 0 = read operation, 1 = write operation
Arg3: fffff9600026c93b, if non-zero, the address which referenced memory.
Arg4: 0000000000000000, (reserved)

Stack at crash:

nt!DbgBreakPointWithStatus
nt!KiBugCheckDebugBreak+0x12
nt!KeBugCheck2+0x8a2
nt!KeBugCheckEx+0x104
nt!MiSystemFault+0x1048
nt!MmAccessFault+0x219
nt!KiPageFault+0x31d
win32k!EngNineGrid+0x102bb
win32k!EngNineGrid+0x10150
win32k!EngNineGrid+0xee4f
win32k!EngNineGrid+0xfcde
win32k!EngNineGrid+0x11e12
nt!KiSystemServiceCopyEnd+0x13
GDI32!GdiReleaseDC+0x12a
dwmcore!CRedirectedGDISurface::SetInformation+0x84
dwmcore!CGdiSpriteBitmap::~CGdiSpriteBitmap+0xb2
dwmcore!CGdiSpriteBitmap::`vector deleting destructor'+0x19
dwmcore!CMILCOMBase::InternalRelease+0x65
dwmcore!CResource::UnRegisterNotifierInternal+0x6e
dwmcore!CWindowNode::GetContentBounds+0x2eac1
dwmcore!CPreComputeContext::PreSubgraph+0x7fe
dwmcore!CGraphIterator::WalkSubtree<CPreComputeContext>+0x10f
dwmcore!CPreComputeContext::PreCompute+0x162
dwmcore!CDesktopRenderTarget::PreRender+0x1be
dwmcore!CCrossThreadComposition::PreRender+0x405
dwmcore!CComposition::ProcessComposition+0x45f
dwmcore!CComposition::Compose+0x5c
dwmcore!CPartitionVerticalBlankScheduler::ProcessFrame+0x32b
dwmcore!CPartitionVerticalBlankScheduler::Run+0x9e1
dwmcore!CPartitionThread::ThreadMain+0x2b
KERNEL32!BaseThreadInitThunk+0x22
ntdll!RtlUserThreadStart+0x34

Registers:

Some register values may be zeroed or incorrect.
rax=0000000000000023 rbx=0000000000000000 rcx=fffff90148728ec0
rdx=fffff90147046ca8 rsi=0000000000000000 rdi=0000000000000000
rip=fffff9600026c93b rsp=ffffd001cdaa6200 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=fffff90140403bf8
r11=ffffd001cdaa6250 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na pe nc
win32k!EngNineGrid+0x102bb:
fffff960`0026c93b 488b4b20        mov     rcx,qword ptr [rbx+20h] ds:00000000`00000020=????????????????

Windbg Widnows 10:

BugCheck:

KERNEL_SECURITY_CHECK_FAILURE (139)
A kernel component has corrupted a critical data structure.  The corruption
could potentially allow a malicious user to gain control of this machine.
Arguments:
Arg1: 0000000000000003, A LIST_ENTRY has been corrupted (i.e. double remove).
Arg2: fffff00ba81ca700, Address of the trap frame for the exception that caused the bugcheck
Arg3: fffff00ba81ca658, Address of the exception record for the exception that caused the bugcheck
Arg4: 0000000000000000, Reserved

Stack at crash:

nt!DbgBreakPointWithStatus
nt!KiBugCheckDebugBreak+0x12
nt!KeBugCheck2+0x952
nt!KeBugCheckEx+0x107
nt!KiBugCheckDispatch+0x69
nt!KiFastFailDispatch+0xd0
nt!KiRaiseSecurityCheckFailure+0x325
win32kbase!SURFACE::RemoveLSurf+0x4c
win32kfull!SFMLOGICALSURFACE::UnlockSurface+0x31
win32kfull!SFMLOGICALSURFACE::SetShape+0xf1
win32kfull!SFMLOGICALSURFACE::DeInitialize+0x77
win32kfull!bhLSurfDestroyLogicalSurfaceObject+0x7f
win32kfull!GreSfmCloseCompositorRef+0xf9
win32kfull!NtGdiHLSurfSetInformation+0x297
nt!KiSystemServiceCopyEnd+0x25
win32u!NtGdiHLSurfSetInformation+0x14
dwmcore!CRedirectedGDISurface::~CRedirectedGDISurface+0x23
dwmcore!CRedirectedGDISurface::`scalar deleting destructor'+0x14
dwmcore!CDirtyRegion::Release+0x32
dwmcore!CGdiSpriteBitmap::~CGdiSpriteBitmap+0x4d
dwmcore!CGdiSpriteBitmap::`scalar deleting destructor'+0x14
dwmcore!CMILCOMBase::InternalRelease+0x30
dwmcore!CResource::UnRegisterNotifierInternal+0x54
dwmcore!CWindowNode::ProcessReadyGdiSpriteBitmaps+0xfb
dwmcore!CWindowNode::SetSpriteImage+0x128
dwmcore!CWindowNode::ProcessSetSpriteImage+0x60
dwmcore!CComposition::ProcessMessage+0x1c13
dwmcore!CGlobalComposition::ProcessDataOnChannelSameProcess+0x179
dwmcore!CKernelTransport::DispatchBatches+0x77
dwmcore!CComposition::PreRender+0x1d5
dwmcore!CPartitionVerticalBlankScheduler::ProcessFrame+0x386
dwmcore!CPartitionVerticalBlankScheduler::ScheduleAndProcessFrame+0xac
dwmcore!CConnection::RunCompositionThread+0x186
KERNEL32!BaseThreadInitThunk+0x14
ntdll!RtlUserThreadStart+0x21

Registers:

rax=fffff00ba81ca8c0 rbx=0000000000000000 rcx=0000000000000003
rdx=ffffa4b74089f530 rsi=0000000000000000 rdi=0000000000000000
rip=ffffa48e3cc4a9ac rsp=fffff00ba81ca890 rbp=0000000000000000
 r8=fffff00ba81ca868  r9=0000000000000001 r10=fffff80251921fb0
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na po cy
win32kbase!SURFACE::RemoveLSurf+0x4c:
ffffa48e`3cc4a9ac cd29            int     29h

Reproduce:

  1. Compile the poc attached and copy it to the target machine
  2. Enable verifier flags 0x1 to win32k drivers
  3. Run the compiled poc and machine will crash with BSOD

PoC:
attached


Attachments:
syscalls.asm
win10-poc.c
win8.1-poc.c

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