Microsoft Windows Kernel – ‘win32k.sys’ Malformed TrueType Program TTF Font Processing Pool-Based Buffer Overflow (MS15-115)

  • 作者: Google Security Research
    日期: 2015-11-16
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/38713/
  • Source: https://code.google.com/p/google-security-research/issues/detail?id=507
    
    We have observed a number of Windows kernel crashes in the win32k.sys driver while processing corrupted TTF font files. An example of a crash log excerpt generated after triggering the bug is shown below:
    
    ---
    DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION (d6)
    N bytes of memory was allocated and more than N bytes are being referenced.
    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: fffff900c49ab000, memory referenced
    Arg2: 0000000000000001, value 0 = read operation, 1 = write operation
    Arg3: fffff96000324c14, if non-zero, the address which referenced memory.
    Arg4: 0000000000000000, (reserved)
    
    [...]
    
    FAULTING_IP: 
    win32k!or_all_N_wide_rotated_need_last+70
    fffff960`00324c14 410802orbyte ptr [r10],al
    
    MM_INTERNAL_CODE:0
    
    DEFAULT_BUCKET_ID:VISTA_DRIVER_FAULT
    
    BUGCHECK_STR:0xD6
    
    CURRENT_IRQL:0
    
    TRAP_FRAME:fffff88007531690 -- (.trap 0xfffff88007531690)
    .trap 0xfffff88007531690
    NOTE: The trap frame does not contain all registers.
    Some register values may be zeroed or incorrect.
    rax=fffff880075318ff rbx=0000000000000000 rcx=0000000000000007
    rdx=00000000000000ff rsi=0000000000000000 rdi=0000000000000000
    rip=fffff96000324c14 rsp=fffff88007531820 rbp=fffffffffffffff5
     r8=00000000ffffffffr9=fffff900c1b48995 r10=fffff900c49ab000
    r11=0000000000000007 r12=0000000000000000 r13=0000000000000000
    r14=0000000000000000 r15=0000000000000000
    iopl=0 nv up ei ng nz na po nc
    win32k!or_all_N_wide_rotated_need_last+0x70:
    fffff960`00324c14 410802orbyte ptr [r10],al ds:0b08:fffff900`c49ab000=??
    .trap
    Resetting default scope
    
    LAST_CONTROL_TRANSFER:from fffff8000294a017 to fffff800028cd5c0
    
    STACK_TEXT:
    fffff880`07531528 fffff800`0294a017 : 00000000`00000050 fffff900`c49ab000 00000000`00000001 fffff880`07531690 : nt!KeBugCheckEx
    fffff880`07531530 fffff800`028cb6ee : 00000000`00000001 fffff900`c49ab000 fffff900`c4211000 fffff900`c49ab002 : nt! ?? ::FNODOBFM::`string'+0x4174f
    fffff880`07531690 fffff960`00324c14 : 00000000`0000001f fffff960`000b8f1f fffff900`c4ed2f08 00000000`0000001f : nt!KiPageFault+0x16e
    fffff880`07531820 fffff960`000b8f1f : fffff900`c4ed2f08 00000000`0000001f 00000000`00000002 00000000`00000007 : win32k!or_all_N_wide_rotated_need_last+0x70
    fffff880`07531830 fffff960`000eba0d : 00000000`00000000 fffff880`07532780 00000000`00000000 00000000`0000000a : win32k!draw_nf_ntb_o_to_temp_start+0x10f
    fffff880`07531890 fffff960`000c5ab8 : 00000000`00000000 fffff900`c49aad60 fffff900`c4ed2ed0 00000000`00ffffff : win32k!vExpandAndCopyText+0x1c5
    fffff880`07531c30 fffff960`00874b4b : fffff900`0000000a fffff880`00000002 fffff900`c4484ca0 fffff880`07532368 : win32k!EngTextOut+0xe54
    fffff880`07531fc0 fffff900`0000000a : fffff880`00000002 fffff900`c4484ca0 fffff880`07532368 00000000`00000000 : VBoxDisp+0x4b4b
    fffff880`07531fc8 fffff880`00000002 : fffff900`c4484ca0 fffff880`07532368 00000000`00000000 fffff880`07532110 : 0xfffff900`0000000a
    fffff880`07531fd0 fffff900`c4484ca0 : fffff880`07532368 00000000`00000000 fffff880`07532110 fffff900`c49b6d58 : 0xfffff880`00000002
    fffff880`07531fd8 fffff880`07532368 : 00000000`00000000 fffff880`07532110 fffff900`c49b6d58 fffff900`c49b6de8 : 0xfffff900`c4484ca0
    fffff880`07531fe0 00000000`00000000 : fffff880`07532110 fffff900`c49b6d58 fffff900`c49b6de8 fffff900`c49b6c30 : 0xfffff880`07532368
    ---
    
    While the above is only one example, we have seen the issue manifest itself in a variety of ways: either by crashing while trying to write beyond a pool allocation in the win32k!or_all_4_wide_rotated_need_last, win32k!or_all_N_wide_rotated_need_last, win32k!or_all_N_wide_rotated_no_last or win32k!or_all_N_wide_unrotated functions, or in other locations in the kernel due to system instability caused by pool corruption. In all cases, the crash occurs somewhere below a win32k!EngTextOut function call, i.e. it is triggered while trying to display the glyphs of a malformed TTF on the screen, rather than while loading the font in the system.
    
    We believe the condition to be a pool-based buffer overflow triggered by one of the above win32k.sys functions, with a binary -or- operation being performed on bytes outside a pool allocation. This is also confirmed by the fact that various system bugchecks we have observed are a consequence of the kernel trying to dereference addresses with too many bits set, e.g.:
    
    ---
    rax=fffff91fc29b4c60 rbx=0000000000000000 rcx=fffff900c4ede320
    rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
    rip=fffff96000271f6a rsp=fffff880035b8bd0 rbp=fffff880035b9780
     r8=000000000000021dr9=fffff900c4edf000 r10=fffff880056253f4
    r11=fffff900c4902eb0 r12=0000000000000000 r13=0000000000000000
    r14=0000000000000000 r15=0000000000000000
    iopl=0 nv up ei ng nz na po nc
    win32k!PopThreadGuardedObject+0x16:
    fffff960`00271f6a 4c8918mov qword ptr [rax],r11 ds:0030:fffff91f`c29b4c60=????????????????
    ---
    
    While we have not determined the specific root cause of the vulnerability, the proof-of-concept TTF files triggering the bug were created by taking legitimate fonts and replacing the glyph TrueType programs with ones generated by a dedicated generator. Therefore, the problem is almost certainly caused by some part of the arbitrary TrueType programs.
    
    The issue reproduces on Windows 7 and 8.1. It is easiest to reproduce with Special Pools enabled for win32k.sys (typically leading to an immediate crash in one of the aforementioned functions when the overflow takes place), but it is also possible to observe a system crash on a default Windows installation as a consequence of pool corruption and resulting system instability. In order to reproduce the problem with the provided samples, it is necessary to use a custom program which displays all of the font's glyphs at various point sizes.
    
    Attached is an archive with several proof-of-concept TTF files, together with corresponding kernel crash logs from Windows 7 64-bit.
    
    Proof of Concept:
    https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/38713.zip