Font Parsing Vulnerabilities

Apple’s 10.10.4 OS X update brought a high number of security patches for vulnerabilities reported by the Yahoo Pentest Team. During my research into various OS X frameworks I chose to focus on OS X font parsing and spent a week fuzzing and reversing native libraries. This research resulted in six CVEs, five of which are shared between OS X and iOS.

Client side font parsing is often a good target because the file formats are varied and complicated. For example, TrueType comes with its own turing complete instruction set which you can learn more about here. OTF and the less popular PostScript file formats are complex and also supported.

Many of these flaws are the result of using untrusted length values extracted directly from the file without validation. In one example CoreText, a low level font layout framework, the ArabicLookups::AddLookup function (shown below) reads a length value from the memory mapped font file, using it to increment a pointer out of bounds. The pointer is held in the rdi register which is later dereferenced in the ResolveLookup function.

loc_D27E3:
	mov     eax, ecx
	mov     ax, [rdx+rax*2+2]
	rol     ax, 8
	movzx   edi, ax
	add     rdi, rdx
	mov     rsi, r8
	mov     rdx, r9
	call    __ZL13ResolveLookupPKN3OTL11LookupTableEPKvS4_ ; ResolveLookup(OTL::LookupTable const*,void const*,void const*)

Apple Type Services is a process that manages fonts. The documentation states that, “The ATS server is a process that is responsible for maintaining the font database for Mac OS X. It activates and deactivates fonts, maintains and scales glyph outline data, maintains font caches, and communicates information about font availability between font clients and font utility applications.”  Since it parses font files, ATS makes a great client side target.

One of the vulnerabilities found in ATS had to do with the size argument being attacker controlled in a call to memcpy. A snippet of the stack trace is pasted below:

	Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
	0   libsystem_platform.dylib      	0x00007fff91599fc9 _platform_memmove$VARIANT$Unknown + 41
	1   libTrueTypeScaler.dylib       	0x00007fff943a2daa CreateScalerVariationBlock(fsg_SplineKey*, memoryContext*, unsigned int, FontVariation const*) + 281
	2   libTrueTypeScaler.dylib       	0x00007fff943a1e2f AssureStrikeBlocks(fsg_SplineKey*, memoryContext*, cacheStrike*, TStrikeDescription const*) + 121
	3   libTrueTypeScaler.dylib       	0x00007fff943a6879 TTGetStrikeSpecs + 129
	4   libFontParser.dylib           	0x00007fff910882a0 TConcreteFontScaler::GetFontInfo(FPFontInfo*) const + 48

To reach this part of the code the AssureScalerFontBlock function must find a null value in [rax+10h]. ScalarGetTableParts() is eventually called, retrieving an integer from the font file and byte swapping for endianness before storing it in [rcx+50h].

mov     ecx, [rcx+50h]    # read from file, set in ScalarGetTableParts
imul    ecx, eax
lea     edx, [rdx+rcx*2+40h]
mov     [r14+28h], edx    # edx is a controlled length
...
mov     r12d, [r14+28h]
sub     r12d, [r14+18h]    # 44h
...
movsxd  rdx, r12d       # size_t
call    _memcpy

It was interesting seeing how OS X handles different fonts. If you want to learn more about font attack surface and vulnerabilities then I suggest reading some of the high quality presentations on Windows kernel and browser font vulnerabilities.

https://cansecwest.com/csw11/Borken%20Fonts%20-%20Schoenefeld.pdf

https://media.blackhat.com/bh-eu-12/Lee/bh-eu-12-Lee-GDI_Font_Fuzzing-WP.pdf

https://media.blackhat.com/us-13/US-13-Chan-Smashing-The-Font-Scaler-Engine-in-Windows-Kernel-WP.pdf

The CVEs attributed to the Yahoo Pentest Team in the 10.10.4 patch are:

CVE-2015-3681
CVE-2015-3686
CVE-2015-3687
CVE-2015-3688
CVE-2015-3694
CVE-2015-3719

I can be reached on twitter at @day6reak

- John Villamil