Today has been released the source code
of the Jailbreakme exploit, so maybe this explanation comes a bit late. In the update of the previous post
about this subject I knew that I was right about the overflow in the arguments stack when parsing the charstrings in the Type 2 format, so here is a little more info.
After decoding the stream of the object 13 we can see the following bytes (talking about this file):
The selected bytes are the important ones for this exploit because the overflow occurs when parsing them. Like I mentioned, the Type 2 format is composed of operands, operators and numbers, and use the stack to push and pop values. This stack has a maximum size of 48 elements. We can understand better the meaning of these bytes with this tips:
- The 0xFF byte means that the next 4 bytes are interpreted as a 32-bit two’s-complement number that will be pushed into the stack.
- 0x0C17 is the random operator that returns a pseudo random number greater than zero and less than or equal to one. This operator doesn't take any argument from the stack.
- The operator 0x0C04 is an or that takes two arguments from the stack and puts a 0 is both arguments are zero and a 1 otherwise.
- 0x0C0D is the index operator, which takes an argument num from the stack and puts the argument in the position num of the stack on the top of it.
- The drop operator is composed by the bytes 0x0C12 and removes the stack top element.
Then, from the stack modification perspective we can separate the bytes in 4 "instructions" set:
- 0xFFXXXXXXXX (45*5 bytes): we put XXXXXXXX into the stack. There is a limit here in the amount of this type of "instruction" because of the stack arguments size, that is checked in this case. So the maximum number that we can push is 45.
- 0x0C170C170C040C1D (20*8 bytes): it pushes the stack element in position 1 (one position after the top element) into the stack. The position is always 1 because the random elements pushed are always non-zero. So in this case will be 0x00C00000.
- 0x0C170C1D (170*4 bytes): we push the element in the position specified by the random number into the stack. The random number always has 16 bits and after a 16-bits movement to the right it becomes 0, so the pushed value will be always the top of the stack, 0x00C00000.
- 0x0C1D0C12 (42*4 bytes): it pushes the stack element in the position C0 into the stack and removes it. The first "instruction" of this type will push F00DF00D (the 4th last number pushed with FF), and the next "instructions" will write into the stack the 41 previous numbers.
These "instructions", except the FF one, don't check if the stack is full before pushing values, so after parsing and executing them the stack state will be similar to this image, being 48*4 the maximum size for the stack:
After the last 0x0C12
"instruction" is executed, checking the stack size and returning from the function with an error code. The successful exploitation will depend on the program and the architecture where the PDF file is parsed. As you know, this affects to Apple products (now patched
) and to the Foxit Reader
. In the case of the latter we can exploit it easily through a SEH overflow, putting the shellcode into the bytes pushed by the FF
"instructions". Here we'll have more than 100 bytes for it, depending on the SEH position. Anyway we can jump from here to the rest of the decoded stream and really do what we want.
출처 : http://eternal-todo.com