sportsboy / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

Windows Kernel win32k.sys TTF font processing: pool-based buffer overflow with malformed TrueType program #507

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
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 410802          or      byte 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=00000000ffffffff  r9=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 410802          or      byte 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=000000000000021d  r9=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 4c8918          mov     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.

This bug is subject to a 90 day disclosure deadline. If 90 days elapse without 
a broadly available patch, then the bug report will automatically become 
visible to the public.

Original issue reported on code.google.com by mjurc...@google.com on 19 Aug 2015 at 2:28

Attachments:

GoogleCodeExporter commented 8 years ago

Original comment by mjurc...@google.com on 19 Aug 2015 at 2:31

GoogleCodeExporter commented 8 years ago

Original comment by mjurc...@google.com on 24 Aug 2015 at 6:24

GoogleCodeExporter commented 8 years ago

Original comment by mjurc...@google.com on 5 Nov 2015 at 5:56

GoogleCodeExporter commented 8 years ago
Fixed in https://technet.microsoft.com/library/security/MS15-115.

Original comment by mjurc...@google.com on 11 Nov 2015 at 12:13

GoogleCodeExporter commented 8 years ago

Original comment by mjurc...@google.com on 14 Nov 2015 at 11:59