Exploit-DB #37918
Description: Microsoft Windows - 'win32k.sys' TTF Font Processing win32k!scl_ApplyTranslation Pool-Based Buffer Overflow
Type: dos
Platform: windows
Date: 2015-08-21
Author: Google Security Research

Exploit:
Source: https://code.google.com/p/google-security-research/issues/detail?id=370&can=1

We have encountered a number of Windows kernel crashes in the win32k!scl_ApplyTranslation function while processing corrupted TTF font files, such as:

---
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except,
it must be protected by a Probe.  Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: ff6c7000, memory referenced.
Arg2: 00000001, value 0 = read operation, 1 = write operation.
Arg3: 94860935, If non-zero, the instruction address which referenced the bad memory
	address.
Arg4: 00000000, (reserved)

[...]

FAULTING_IP: 
win32k!scl_ApplyTranslation+9b
94[PII_REDACTED]87          add     dword ptr [edi+eax*4],edx

MM_INTERNAL_CODE:  0

DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT

BUGCHECK_STR:  0x50

PROCESS_NAME:  csrss.exe

CURRENT_IRQL:  0

LAST_CONTROL_TRANSFER:  from 94862292 to 94860935

STACK_TEXT:  
8ad915ec [PII_REDACTED] [PII_REDACTED] win32k!scl_ApplyTranslation+0x9b
8ad91610 9485f419 ff6ae250 ff6b24d8 ff6ae2c4 win32k!fsg_GridFit+0xdd
8ad9[PII_REDACTED]c 00000001 8ad916a4 94868fc3 win32k!fs__Contour+0x287
8ad91694 94868fc3 ff6ae010 ff6ae07c 8ad916c0 win32k!fs_ContourGridFit+0x12
8ad916a4 9486991f ff6ae010 ff6ae07c 000000a4 win32k!fs_NewContourGridFit+0x10
8ad916c0 94869960 fc380e78 000000a4 8ad916fc win32k!bGetGlyphOutline+0xd7
8ad916e8 94869b59 fc380e78 000000a4 00000001 win32k!bGetGlyphMetrics+0x20
8ad9182c 9485ec63 fc380e78 000000a4 8ad91918 win32k!lGetGlyphBitmap+0x2b
8ad91850 9485eab6 [PII_REDACTED] 000000a4 win32k!ttfdQueryFontData+0x158
8ad918a0 9485dce2 ff7af010 fbb4acf0 00000001 win32k!ttfdSemQueryFontData+0x45
8ad918e8 94863774 ff7af010 fbb4acf0 00000001 win32k!PDEVOBJ::QueryFontData+0x3e
8ad91960 948dbc8d 8ad91c3c fba6cd68 ff6deca8 win32k!xInsertMetricsPlusRFONTOBJ+0x120
8ad9[PII_REDACTED]d 0000000a ff7bf090 8ad91ce2 win32k!RFONTOBJ::bGetGlyphMetricsPlus+0x179
8ad919c8 948db78b 8ad91c1c 8ad91c3c 00000008 win32k!ESTROBJ::vCharPos_H3+0xf0
8ad91a0c 948555d0 8ad91cd0 0000000a 8ad91c1c win32k!ESTROBJ::vInit+0x268
8ad91c2c [PII_REDACTED] 8ad91cd0 fbb4acf0 win32k!GreGetTextExtentExW+0x12a
8ad91d0c [PII_REDACTED] 007c0bac 0000000a win32k!NtGdiGetTextExtentExW+0x141
8ad91d0c 772470f4 03010292 007c0bac 0000000a nt!KiSystemServicePostCall
WARNING: Frame IP not in any known module. Following frames may be wrong.
0021f9ac [PII_REDACTED] [PII_REDACTED] 0x772470f4
---

Depending on the malformed font file, the crashes are triggered at various locations in the win32k!scl_ApplyTranslation function:
win32k!scl_ApplyTranslation+43
win32k!scl_ApplyTranslation+9b

The crashes always occur while trying to access memory outside of a dynamically allocated destination buffer, leading to a pool-based buffer overflow, potentially allowing for remote code execution in the context of the Windows kernel. While we have not determined the specific root cause of the vulnerability, we have pinpointed the offending mutations to reside in the "maxp" and "hmtx" 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 win32k!scl_ApplyTranslation or another location in kernel space, as caused by the corrupted pool state, depending on the specific testcase used. 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.

Attached is an archive with three proof of concept font files together with corresponding kernel crash logs.

---------------------------------------------------------------------------------------------------------------------------------------------

While performing further analysis of some of the offending samples, we have found that sometimes buffers and structures in the pools align such that this condition causes an overwrite of function pointers residing in the font's fnt_GlobalGraphicStateType structure, consequently leading to crashes at invalid EIPs when one of these pointers is subsequently called. Several crashes such as the one shown below have been reproduced on Windows 7 32-bit with Special Pools enabled for win32k.sys:

---
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except,
it must be protected by a Probe.  Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: c1c00dc1, memory referenced.
Arg2: 00000008, value 0 = read operation, 1 = write operation.
Arg3: c1c00dc1, If non-zero, the instruction address which referenced the bad memory
	address.
Arg4: 00000002, (reserved)

[...]

FAULTING_IP: 
+0
c1c00dc1 ??              ???

MM_INTERNAL_CODE:  2

DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT

BUGCHECK_STR:  0x50

PROCESS_NAME:  csrss.exe

CURRENT_IRQL:  0

LAST_CONTROL_TRANSFER:  from 9224a9cc to c1c00dc1

STACK_TEXT:  
WARNING: Frame IP not in any known module. Following frames may be wrong.
994574b4 9224a9cc 99457504 fb5a2efc fb5a2e94 0xc1c00dc1
994574c8 [PII_REDACTED] [PII_REDACTED] win32k!scl_CalcComponentOffset+0x21
99[PII_REDACTED]1ef8 00000800 fb5a2e94 fb5a2e94 win32k!fsg_MergeGlyphData+0x12a
99[PII_REDACTED]238c fb5a2250 fb5a2f1c fb5a348c win32k!fsg_ExecuteGlyph+0x268
994575d0 92262202 fb5a2250 fb5a348c fb5a2ddc win32k!fsg_CreateGlyphData+0xea
99[PII_REDACTED]f419 fb5a2250 fb5a348c fb5a22c4 win32k!fsg_GridFit+0x4d
99[PII_REDACTED]906c 00[PII_REDACTED]76a4 92268fc3 win32k!fs__Contour+0x287
99[PII_REDACTED]8fc3 fb5a2010 fb5a207c 994576c0 win32k!fs_ContourGridFit+0x12
994576a4 9226991f fb5a2010 fb5a207c 00000080 win32k!fs_NewContourGridFit+0x10
994576c0 92269960 fbc5ee78 00000