A real from-scratch 64-bit kernel is booting below — QEMU compiled to
WebAssembly, not a replay. Its RAM disk hides a FLAG{…} in bytes
with no directory entry: ls will never show it, and
cat can't name it. Your job is to make the filesystem hand it to you
anyway — by crafting a disk image whose own rules betray it.
← the guided tour ·
plain live boot
You made the filesystem hand you a flag it was built to hide:
That's the whole primitive — one dishonest length field turned a bounds check into an out-of-bounds read. Remember this is the white-box sandbox: the flag lived in your tab, so it was always in reach. The uncheatable version, where the flag lives only on a server and the exploit must land over the wire, is Tier 2.
Nice work — submit a writeup to get on the solvers list.
The kernel's load command mounts a base64 image you paste in. Start
from the presets — each one rebuilds the base64 below and explains what it does.
Then hit Load into the kernel and try ls / and
cat /notes.txt.
① A normal, well-formed disk with two files. The secret sits past
data_end, unlisted — ls won't show it and a normal
cat can't reach it.
ZranFS v3 is dead simple. A 16-byte superblock:
"ZRFS", version 3, a file count, the
total_size (must equal the image length), and a
data_end — the declared ceiling of the "real" data region. Then a
table of 32-byte directory entries (a 20-byte name, then a 32-bit
offset, length, and kind). Then the file
bytes. The flag is appended after data_end, with no entry
pointing at it.
The strict reader (Fs::mount) does confine every file's extent to
[.., data_end) — so an entry can't normally reach the flag past it.
But data_end is a field inside the image, and you supply the whole
image, superblock included. Validating an extent against a number the
attacker also controls isn't validation. Preset ② proves the confinement is
real (an over-long extent with an honest data_end is
rejected — ExtentEscapesData). Preset ③ removes the guard by lying.
Forge data_end = total_size (now the whole image counts as "data"),
and stretch a listed file's length so its extent runs off the end of
its own bytes and over the flag region. Mount passes every check — because you
moved the ceiling — and cat /notes.txt zero-copies from its declared
offset for its declared length: its own bytes, then
everything after them, including the flag. That's preset ③. One dishonest
field turns a bounds check into an out-of-bounds read.
Everything here runs in your tab, so the flag was always in your reach; the
lesson is the primitive, not the secret. Tier 2 makes it a real
capture: the kernel runs on a server, the flag lives only in that process's RAM
(never in this page, never in git), and the only way to get it is to land this
same exploit over the wire — develop it here, capture it there. That's the
version worth bragging about.
Tier 2 is built and being hardened for public launch — it is
not live yet. Develop your exploit here in the meantime; when the remote
capture opens, this same crafted image is what you'll fire over the wire.