test.js
var arr = new Array(1.1, 2.2, 3.3);
function test(obj) {
arr[0] = obj;
}
test({});
Print bytecode of test function:
d8.file.execute("wasm-module-builder.js"); | |
let builder = new WasmModuleBuilder(); | |
let array_type = builder.addArray(kWasmI32, true); | |
builder.addFunction('create_array', makeSig([kWasmI32], [wasmRefType(array_type)])) | |
.addBody([ | |
kExprLocalGet, 0, | |
kGCPrefix, kExprArrayNewDefault, array_type, | |
]) |
// Build d8 using: | |
// a) Run once | |
// git checkout 6f98fbe86a0d11e6c902e2ee50f609db046daf71 | |
// gclient sync | |
// gn gen ./out/x64.debug | |
// gn gen ./out/x64.release | |
// | |
// b) | |
// Debug Build: | |
// ninja -C ./out/x64.debug d8 |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <windows.h> | |
#include "nt_crap.h" | |
#define ArrayCount(arr) (sizeof(arr)/sizeof(arr[0])) | |
#define assert(expr) if(!(expr)) { *(char*)0 = 0; } |
<?php header("Status: 204"); ?> |
//v8 version 11.4.183.19 | |
//git checkout 56e5481171da3eacd3cb83db2be3b2d2b96b4abb | |
//MODIFY BUILD.gn in the root v8 folder to enable the memory corruption api | |
//v8_expose_memory_corruption_api = true | |
//ninja -C ./out/x64.debug d8 | |
//ninja -C ./out/x64.release d8 | |
const addr_of = (o) => { | |
return Sandbox.getAddressOf(o); |
test.js
var arr = new Array(1.1, 2.2, 3.3);
function test(obj) {
arr[0] = obj;
}
test({});
Print bytecode of test function:
DWARF has a clever (too clever?) VM representation for source line to asm mapping. | |
VM has state which represents virtual program and source line counters. | |
The DW_LNS_advance_pc instruction advances the program counter while the DW_LNS_advance_line instruction | |
advances the line counter. Both these instructions encode the "advance amount" value as a variably sized immediate operand. | |
The DW_LNS_copy instructions tells us that current VM pc and source counter states correspond together | |
both counter values can be copied to a array of line numbers and assembly addresses. When the VM reads a byte from the | |
instruction stream it compares this value with a VM specified "opcode base" variable. If the value is below the "opcode base" | |
then it represents an opcode for an instruction. If the value is above the "opcode base" then it represents the operand for | |
an implicit "instruction". This special implicit "instruction" advances both the program and source line counters at once | |
using this single byte value. But how |
<script type="text/javascript" src="utility.js"></script> |
// POC Exploit for v8 issue 1104608 (https://bugs.chromium.org/p/chromium/issues/detail?id=1104608) | |
// author: @mistymntncop | |
// bug discovered by: @r3tr0spect2019 | |
// Exploit strategy based on @r3tr0spect2019's "Real World CTF" presentation on the bug. | |
// https://www.youtube.com/watch?v=rSaIlBWwxsY | |
// | |
// Build d8 using: | |
// a) Run once | |
// git checkout 3505cf00eb4c59b87f4b5ec9fc702f7935fdffd0 | |
// gclient sync --with_branch_heads |