VegarLH / google-security-research

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

Adobe Reader CoolType unlimited out-of-bounds stack manipulation via BLEND operator #258

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
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

Original issue reported on code.google.com by mjurc...@google.com on 6 Feb 2015 at 12:14

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 6 Feb 2015 at 4:46

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 11 Feb 2015 at 11:53

GoogleCodeExporter commented 9 years ago
Patch due May 12th -- 5 days into 14 day grace period.

Original comment by cev...@google.com on 5 May 2015 at 11:23

GoogleCodeExporter commented 9 years ago
Tagging a CVE and fixing mismatched PSIRT-ID.

Original comment by mjurc...@google.com on 7 May 2015 at 9:35

GoogleCodeExporter commented 9 years ago
https://helpx.adobe.com/security/products/reader/apsb15-10.html

Original comment by cev...@google.com on 12 May 2015 at 6:23

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 12 Jun 2015 at 4:04