Monorail Project: project-zero Issues People Development process History Sign in
New issue
Advanced search Search tips
Starred by 2 users
Status: Fixed
Owner:
Closed: May 2015
Cc:



Sign in to add a comment
Adobe Reader CoolType unlimited out-of-bounds stack manipulation via BLEND operator
Project Member Reported by mjurczyk@google.com, Feb 6 2015 Back to list
The `blend` operator - as described in "The Type 2 Charstring Format, 18 March 1998" - is supposed to take n + 1 parameters from the operand stack, with the 16-bit signed value "n" being passed as the first argument. The implementation of the operator found in the Adobe Reader CoolType.dll font library does not expect that value to be negative and mishandles this corner case, leading to catastrophic consequences for application security.

Specifically, the `blend` handler does perform some validation checks against "n" in order to check that the (again, signed) number is not greater than the current size of the stack, or that the stack pointer is not already out of stack bounds when entering the code:

---
      case cf2_cmdBLEND:
        if ( op_sp - &op_stk < 1 )
          return -8;
        master_designs = font->master_designs;
        n = *(op_sp - 1);
        --op_sp;
        if ( master_designs < 2 || master_designs > 16 || op_sp - &op_stk < master_designs * n )
          return -8;
        op_sp = DoBlend(n, master_designs, font->weight_vector, op_sp);
---

A negative 16-bit number passes all of the above checks and is further provided as the first parameter to the "DoBlend" function. When confronted with such a number, that function shifts the operand stack pointer up by the following number of bytes:

-n * (master_designs - 1) * 4

This condition is badly dangerous because of the fact that the 48-item long operand stack is implemented as a regular array on the interpreter function's stack, thus being able to shift the operand stack pointer out of bounds gives the power to manipulate the regular thread stack in any desired way. An attacker is able to illegally add a maximum value of 32768 * 15 * 4 = 1966080 (0x1E0000) to the stack pointer; on the other hand, by setting "master_designs" to 2 (in case of CoolType.dll, this can be achieved by inserting a PostScript array "WeightVector" with two elements into the font dict), one is able to shift the pointer with great accuracy (any multiply of 4). For example, if the return address of the interpreter function is positioned 128 dwords ahead of the "op_stk" array, the two instructions below will set "op_sp" to that address:

-128 blend

At first glance it is not trivial to turn the condition into an arbitrary stack manipulation primitive, because the standard opcodes used for pushing values to the stack do check that "op_sp" has not gone beyond the "op_stk" memory area. However, various operators which write to the stack but don't increase "op_sp" (because they also take parameters from the stack) don't perform such checks, and so can be used to manipulate the data under any "op_sp". These operators are:

1) not
2) neg
3) abs
4) sqrt
5) index
6) div
7) add
8) sub
9) mul
10) get

In particular, a sequence of `put`, `blend`, and several `sqrt` followed by `get` instructions can be used to successfully manipulate the data on stack in any desired way. This is not just about reading and writing - the CharString can perform arithmetic operations such as addition or subtraction, thus it is possible to build a full ROP chain on the stack and reliably hijack code execution solely from within the font VM, with no external help. This is very similar to a FreeType vulnerability exploited by comex in his iOS jailbreak [1], only here the attacker gets even more control over the control flow, because the entire stack is fully controlled.

The vulnerability is reproducible with Type1 fonts. It is not reproducible (to our current knowledge) with OpenType fonts, because it requires the number of master designs in the font to be non-zero. The attached testcase ("poc.pfm" + "poc.pfb") crashes a fully patched Adobe Reader 11.0.10 for Windows, by using the following charstring for letter 'a':

/a ## -| { -75 blend exch endchar } |-

together with a "WeightVector" of length 2. This causes the "op_sp" pointer to be shifted forward by 0x12c bytes (4 bytes ahead of the interpreter function's return address), and further dereferenced by the `exch` operator. Therefore, the following crash occurs due to an attempt to execute a non-executable stack address (as the return address and stack frame pointer are exchanged), when opening a PDF file with the offending font file embedded:

---
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=cbfd8b33 edx=00000000 esi=00002000 edi=00000001
eip=002dc9e0 esp=002dc90c ebp=6e040e09 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210246
002dc9e0 40              inc     eax
0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

FAULTING_IP: 
+0
002dc9e0 40              inc     eax

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 002dc9e0
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000008
   Parameter[1]: 002dc9e0
Attempt to execute non-executable address 002dc9e0
---

A full crash log can be found in the "crash.txt" file. Adobe Reader 11.0.10 is confirmed to be affected, but we expect all prior versions of the software to be prone to the bug, too. A Type1 Proof of Concept font is attached ("poc.pfm" + "poc.pfb"), together with its source code to be compiled with the type1 tool ("poc.pfa"), and an actual PDF file with the offending font file embedded.

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.

References:
[1] http://esec-lab.sogeti.com/post/Analysis-of-the-jailbreakme-v3-font-exploit
 
Project Member Comment 1 by mjurczyk@google.com, Feb 6 2015
Labels: Reported-2015-Feb-6
Project Member Comment 2 by mjurczyk@google.com, Feb 11 2015
Labels: Id-3282
Comment 3 by cevans@google.com, May 5 2015
Labels: Deadline-Grace Deadline-Exceeded
Patch due May 12th -- 5 days into 14 day grace period.
Project Member Comment 4 by mjurczyk@google.com, May 7 2015
Labels: -Id-3282 Id-3278 CVE-2015-3052
Tagging a CVE and fixing mismatched PSIRT-ID.
Comment 5 by cevans@google.com, May 12 2015
Labels: Fixed-2015-May-12
Status: Fixed
https://helpx.adobe.com/security/products/reader/apsb15-10.html
Project Member Comment 6 by mjurczyk@google.com, Jun 12 2015
Labels: -Restrict-View-Commit
Comment 7 Deleted
Project Member Comment 8 by mjurczyk@google.com, Jun 7 2016
Fixing the attachments.
poc.pfa
53.5 KB Download
poc.pfb
19.7 KB Download
poc.pfm
668 bytes Download
poc.pdf
20.4 KB Download
crash.txt
1.1 KB View Download
Sign in to add a comment