Microsoft Windows – ‘win32k.sys’ TTF Processing win32k!sbit_Embolden / win32k!ttfdCloseFontContext Use-After-Free (MS16-120)

  • 作者: Google Security Research
    日期: 2016-10-20
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/40599/
  • Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=868
    
    We have encountered Windows kernel crashes in the win32k!sbit_Embolden and win32k!ttfdCloseFontContext functions while processing corrupted TTF font files. Excerpts of them are shown below:
    
    ---
    KERNEL_MODE_EXCEPTION_NOT_HANDLED (8e)
    This is a very common bugcheck.Usually the exception address pinpoints
    the driver/function that caused the problem.Always note this address
    as well as the link date of the driver/image that contains this address.
    Some common problems are exception code 0x80000003.This means a hard
    coded breakpoint or assertion was hit, but this system was booted
    /NODEBUG.This is not supposed to happen as developers should never have
    hardcoded breakpoints in retail code, but ...
    If this happens, make sure a debugger gets connected, and the
    system is booted /DEBUG.This will let us see why this breakpoint is
    happening.
    Arguments:
    Arg1: c0000005, The exception code that was not handled
    Arg2: 8e70bba3, The address that the exception occurred at
    Arg3: 9b7e3a84, Trap Frame
    Arg4: 00000000
    
    Debugging Details:
    ------------------
    
    
    EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
    
    FAULTING_IP: 
    win32k!MultiUserGreTrackRemoveEngResource+1c
    8e70bba3 8901mov dword ptr [ecx],eax
    
    TRAP_FRAME:9b7e3a84 -- (.trap 0xffffffff9b7e3a84)
    ErrCode = 00000002
    eax=fa42ce68 ebx=fa42ce78 ecx=00000000 edx=00000000 esi=ff73a000 edi=fc4a4fc8
    eip=8e70bba3 esp=9b7e3af8 ebp=9b7e3af8 iopl=0 nv up ei pl zr na pe nc
    cs=0008ss=0010ds=0023es=0023fs=0030gs=0000 efl=00010246
    win32k!MultiUserGreTrackRemoveEngResource+0x1c:
    8e70bba3 8901mov dword ptr [ecx],eaxds:0023:00000000=????????
    Resetting default scope
    
    DEFAULT_BUCKET_ID:WIN7_DRIVER_FAULT
    
    BUGCHECK_STR:0x8E
    
    PROCESS_NAME:csrss.exe
    
    CURRENT_IRQL:2
    
    ANALYSIS_VERSION: 6.3.9600.17237 (debuggers(dbg).140716-0327) x86fre
    
    LAST_CONTROL_TRANSFER:from 82933d87 to 828cf978
    
    STACK_TEXT:
    9b7e303c 82933d87 00000003 1d46c818 00000065 nt!RtlpBreakWithStatusInstruction
    9b7e308c 82934885 00000003 9b7e3490 00000000 nt!KiBugCheckDebugBreak+0x1c
    9b7e3450 82933c24 0000008e c0000005 8e70bba3 nt!KeBugCheck2+0x68b
    9b7e3474 829092a7 0000008e c0000005 8e70bba3 nt!KeBugCheckEx+0x1e
    9b7e3a14 828929a6 9b7e3a30 00000000 9b7e3a84 nt!KiDispatchException+0x1ac
    9b7e3a7c 8289295a 9b7e3af8 8e70bba3 badb0d00 nt!CommonDispatchException+0x4a
    9b7e3af8 8e70bbe6 ff73a000 fb77cd28 9b7e3b20 nt!Kei386EoiHelper+0x192
    9b7e3b08 8e7ef63d ff73a010 8e7ef5c0 fb784cf0 win32k!EngFreeMem+0x16
    9b7e3b20 8e7ef67c fa42ce78 9b7e3b98 9b7e3b3c win32k!ttfdCloseFontContext+0x51
    9b7e3b30 8e7ef5d8 fb784cf0 9b7e3b74 8e7ef1f8 win32k!ttfdDestroyFont+0x16
    9b7e3b3c 8e7ef1f8 fb784cf0 fe38ccf0 9b7e3bd8 win32k!ttfdSemDestroyFont+0x18
    9b7e3b74 8e7ef41b fb784cf0 fe38ccf0 00000000 win32k!PDEVOBJ::DestroyFont+0x67
    9b7e3ba4 8e7749c3 00000000 00000000 00000001 win32k!RFONTOBJ::vDeleteRFONT+0x33
    9b7e3bcc 8e77660f 9b7e3bf0 fb784cf0 00000000 win32k!vRestartKillRFONTList+0x8d
    9b7e3c00 8e84100e 00000006 fb284fc0 8eaf8fc8 win32k!PFTOBJ::bUnloadWorkhorse+0x15f
    9b7e3c28 82891dc6 0500019c 002cf9cc 76e26bf4 win32k!GreRemoveFontMemResourceEx+0x60
    9b7e3c28 76e26bf4 0500019c 002cf9cc 76e26bf4 nt!KiSystemServicePostCall
    002cf9cc 00000000 00000000 00000000 00000000 ntdll!KiFastSystemCallRet
    ---
    
    And:
    
    ---
    PAGE_FAULT_IN_FREED_SPECIAL_POOL (cc)
    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: fc1ffa54, memory referenced
    Arg2: 00000001, value 0 = read operation, 1 = write operation
    Arg3: 82848a05, if non-zero, the address which referenced memory.
    Arg4: 00000000, Mm internal code.
    
    Debugging Details:
    ------------------
    
    
    WRITE_ADDRESS:fc1ffa54 Special pool
    
    FAULTING_IP: 
    nt!memset+45
    82848a05 f3abrep stos dword ptr es:[edi]
    
    MM_INTERNAL_CODE:0
    
    DEFAULT_BUCKET_ID:WIN7_DRIVER_FAULT
    
    BUGCHECK_STR:0xCC
    
    PROCESS_NAME:csrss.exe
    
    CURRENT_IRQL:2
    
    ANALYSIS_VERSION: 6.3.9600.17237 (debuggers(dbg).140716-0327) x86fre
    
    TRAP_FRAME:8fb73d58 -- (.trap 0xffffffff8fb73d58)
    ErrCode = 00000002
    eax=00000000 ebx=00000001 ecx=00000001 edx=00000000 esi=00000004 edi=fc1ffa54
    eip=82848a05 esp=8fb73dcc ebp=8fb73e28 iopl=0 nv up ei pl nz na po nc
    cs=0008ss=0010ds=0023es=0023fs=0030gs=0000 efl=00010202
    nt!memset+0x45:
    82848a05 f3abrep stos dword ptr es:[edi]
    Resetting default scope
    
    LAST_CONTROL_TRANSFER:from 828eed87 to 8288a978
    
    STACK_TEXT:
    8fb738ac 828eed87 00000003 766f335a 00000065 nt!RtlpBreakWithStatusInstruction
    8fb738fc 828ef885 00000003 00000000 0000000a nt!KiBugCheckDebugBreak+0x1c
    8fb73cc0 8289d94d 00000050 fc1ffa54 00000001 nt!KeBugCheck2+0x68b
    8fb73d40 8284ffa8 00000001 fc1ffa54 00000000 nt!MmAccessFault+0x104
    8fb73d40 82848a05 00000001 fc1ffa54 00000000 nt!KiTrap0E+0xdc
    8fb73dcc 8f15cca0 fc1ffa54 00000000 00000004 nt!memset+0x45
    8fb73e28 8f050c00 0000000b 00000004 c0000002 win32k!sbit_Embolden+0x34d
    8fb73e68 8efc3e10 fb972fd0 fc200ea0 faec6040 win32k!sbit_GetBitmap+0x18c
    8fb73eb4 8efc9ff1 fc200010 fc20007c faec6040 win32k!fs_ContourScan+0x192
    8fb73ff8 8efbef89 00000028 00000020 faec6000 win32k!lGetGlyphBitmap+0x1aa
    8fb74020 8efbedd6 00000000 00000001 00000020 win32k!ttfdQueryFontData+0x15e
    8fb74070 8efbdff2 fbf98010 fa794cf0 00000001 win32k!ttfdSemQueryFontData+0x45
    8fb740b8 8f14eef5 fbf98010 fa794cf0 00000001 win32k!PDEVOBJ::QueryFontData+0x3e
    8fb740e8 8f14ef48 fc586f20 ffa84130 8fb74114 win32k!RFONTOBJ::bInsertGlyphbitsLookaside+0xa7
    8fb740f8 8f050663 0000000a fc586f20 8fb74798 win32k!RFONTOBJ::cGetGlyphDataLookaside+0x1c
    8fb74114 8f03b2fc 8fb74798 8fb74148 8fb74144 win32k!STROBJ_bEnum+0x6c
    8fb7414c 8f03b4d9 00000001 8fb74358 00000d0d win32k!GetTempTextBufferMetrics+0x61
    8fb743d4 8ee34042 fc1cadb8 8fb74798 fa794cf0 win32k!EngTextOut+0x26
    WARNING: Stack unwind information not available. Following frames may be wrong.
    8fb74410 8f13cce0 fb16edb8 8fb74798 fa794cf0 VBoxDisp+0x4042
    8fb7446c 8f03dbcb fef7cc90 8fb74798 fa794cf0 win32k!WatchdogDrvTextOut+0x51
    8fb744b8 8f03de38 8f13cc8f 8fb74724 fb16edb8 win32k!OffTextOut+0x71
    8fb7473c 8f03d9a8 fb16edb8 8fb74798 fa794cf0 win32k!SpTextOut+0x1a2
    8fb74a38 8efcc2d4 8fb74bfc fc0b8e20 fc0b8e7c win32k!GreExtTextOutWLocked+0x1040
    8fb74ab4 8f01f251 00000000 ff7bf064 00001000 win32k!GreBatchTextOut+0x1e6
    8fb74c24 8284cd5c 000000bc 001afd88 001afdb4 win32k!NtGdiFlushUserBatch+0x123
    8fb74c34 76f16bf3 badb0d00 001afd88 00000000 nt!KiSystemServiceAccessTeb+0x10
    8fb74c38 badb0d00 001afd88 00000000 00000000 ntdll!KiFastSystemCall+0x3
    8fb74c3c 001afd88 00000000 00000000 00000000 0xbadb0d00
    8fb74c40 00000000 00000000 00000000 00000000 0x1afd88
    ---
    
    While the two above crashes look differently, we believe they manifest a single security issue, as they occur interchangeably with our proof of concept files. The first one is a NULL pointer dereference while performing a list unlinking operation, while the second is an attempt to write to memory which has already been freed, and they both indicate a use-after-free condition. While we have not determined the specific root cause of the vulnerability, we have pinpointed the offending mutations to reside in the "OS/2" and "VDMX" tables.
    
    The issue reproduces on Windows 7 and 8.1. It is easiest to reproduce with Special Pools enabled for win32k.sys (leading to an immediate crash when the bug is triggered), but it is also possible to observe a crash on a default Windows installation. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes. It is also required for the "Adjust for best performance" option to be set in "System > Advanced system settings > Advanced > Performance > Settings", most likely due to the "Smooth edges of screen fonts" getting unchecked.
    
    Attached is an archive with three proof of concept font files.
    
    
    Proof of Concept:
    https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40599.zip