UPDATE – July 18 2011
Wednesday, @comex came out with a new user-level jailbreak available on jailbreakme.com. I wanted to understand exactly how this exploit is able to get root so easily. Here is my workflow, and preliminary analysis of the exploit.
The first obvious step is to obtain the page that exploits the iPhone:
curl -A "Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5" http://www.jailbreakme.com > exploit.7.6.2011.pdf
After opening up the file, you can see a set of comments which are quite amusing:
Analyzing the page, the bulk of it is in a base64 encoded pdf blob on line 1044:
There are some % notation characters in there that you must convert; specifically %2B=+ and %2F=/. The blob can now be base64 decoded with your favorite method, and you will get a pdf file that is only 16k in size:
$ ls -lah exploit.7.6.2011.pdf -rw-r--r--@ 1 wuntee staff 16K Jul 6 19:48 exploit.7.6.2011.pdf
$ file exploit.7.6.2011.pdf
exploit.7.6.2011.pdf: PDF document, version 1.3
Examining the PDF file with Didier Stevens pdf-parser tool, there is one object (obj 12 0) that sticks out, consuming most of the file:
Further examining that object, you will see that it is a FlatDecode stream:
After playing around a bit more with the file using Didier Steves tools, and attempting to dump the raw stream, I ended up running the following command that made my terminal freak out. It minimizes, then restores, over and over again for about 60 seconds (more on this shortly).
NOTE: Do not run this command unless you want your terminal to minimize and restore over and over again.
$ pdf-parser.py --object 12 --raw --filter exploit.7.6.2011.pdf
Finally, I switched over to Sogeti ESEC Lab’s Origami framework, in order to dump the raw stream using the PDF walker GUI:
Looking at the file, you can see it is a PostScript Type 1 font:
$ file raw.stream.12.bin raw.stream.12.bin: PostScript Type 1 font program data
Examining the contents of file in a text editor, you can see a few interesting things:
First, the header comment, which is explaining that it is “blatantly invalid”, followed by the ‘/TerminalFun’ object, which is what was causing my terminal to freak out when printing the raw contents, as described earlier… Thanks @comex
Now, I am not very familiar with AdobeFont file formats, or font file formats in general, so I started looking at the AdobeFont 1.0 file format spec (Note: The linked PDF is causing my Chrome to crash… Maybe another vuln?) and started stepping through the jailbreakme.com‘s AdobeFont file. I started to compare tis font file to the examples that were given in the AdobeFont document, there are a lot of similarities:
Then I got to the ‘/Private’ portion, and I noticed the ‘/lenIV -1 def’. The AdobeFont spec states:
The lenIV entry is an integer specifying the number of random bytes at the beginning of charstrings for charstring encryption. The default value of lenIV is 4.
Setting an integer (lenIV) to -1 would seem to be a logical place for a vulnerability to trigger. Reading further in the spec document, it also says:
To Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence of Plaintext Bytes
1. Initialize an unsigned 16-bit integer variable R to the encryption key (the same key as used to encrypt).
2. For each 8-bit byte, C, of ciphertext the following steps are executed:
a. Assign the high order 8 bits of R to a temporary variable, T.
b. Exclusive-OR C with T, producing a plaintext byte, P.
c. Compute the next value of R by the formula ((C + R) × c1 + c2) mod 65536, where c1 and c2 are the same constants that were used to encrypt.
3. Discard the first n bytes of plaintext; these are the random bytes added during encryption. The remainder of the plaintext bytes are the original sequence.
I think we found our bug… Discard the first -1 bytes of plaintext…
I hosted the pdf file on my local machine, and pointed my 4.3.1 jailbroken iPhone at the PDF while MobileSafari was connected to GDB and see an exception being triggered:
The exception occurred from a ‘KERN_PROTECTION_FAILURE’ which leads me to believe that the exploit may not work with 4.3.1, but it also gives me an insight into where the exception is happening. Specifically:
__CFPLDataDecodeTable () - t1_decoder_parse_glyph () - t1_decoder_parse_charstrings () - T1_Parse_Glyph_And_Get_Char_String () - T1_Load_Glyph () - FT_Load_Glyph () - FT::font::load_glyph () ...
This makes sense, and confirms my assumption above that the problem is with “decrypting” the /Private blob shown above.
So, this seems to be a single vulnerability/exploit which allows Cydia to be installed (vs a multi-phased exploit that performs a Safari exploit, followed by a privilege escalation).
The next step is to understand how the exploit actually works.
There was some twitter chatter about the exploit having a kernel driver by @saurik:
I have some speculations of my own on how this exploit is actually working. I think the reason this works is because processing/installing fonts happens at an escalated privilege level. Since the exploit is actually happening during the processing of the font, that same security level would have the ability to install an application, such as Cydia, and disabled protections against running un-signed applications.
After examining the AdobeFont file further, it is unclear to me if the ‘/Private’ portion is encrypted/encoded. The /Private section consists of an array of 9 objects, where the 9th one looks like the payload for the exploit:
That is all I have for now. I hope to have an update on how the exploit actually works in the future.
Both comments and trackbacks are currently closed.