unik.cx · the wargame
Capture the flag
Nineteen boxes, one ladder. Each level hands you the password to the next — but only once you've used the right tool to pry it loose. It's Bandit, rebuilt around the Applied Linux book: every rung reinforces a chapter. Levels 00–08 are live Nanos unikernel boxes with a browser practice mode; levels 09–18 are a second, harder track — real Firecracker microVMs, network-only, no practice mode.
Play in the browser
Boot the arena right here — a real Linux shell, client-side,
nothing to install. All nine levels are planted on this box the moment
it boots; you land as player. Find each flag with the skill
it trains, then paste it into the matching level below.
Runs via v86, entirely client-side. Practice mode: because the box runs in your tab, the flags are planted locally — a determined reader can dig them out of the page source. The live boxes are the cheat-resistant, graded version. Covers levels 00–08 only — 09–18 have no browser practice mode, see below.
Attack the live boxes
Each level is its own Nanos unikernel — a single-app
machine with no shell, no users, exposing one service over TCP. Talk to it
with nc, solve what it asks, and it hands you the flag.
$ nc unik.cx 13370 # level 0 $ nc unik.cx 1337N # level N → port 13370+N
One unikernel per level on unik.cx, ports
13370–13378. Each flag you pry loose unlocks
the next rung below; progress is kept in this browser only.
Levels 09–18: the hard track
A second, unrelated backend: each of these boxes is a full Linux guest
kernel in its own Firecracker microVM, not a unikernel
— real users, real processes, a root-owned watcher doing something
exploitable in the background. No SUID binaries work here on purpose;
every box enforces no_new_privs, so the bug is always logic,
never a setuid bit.
$ nc ctf.unik.cx 27295 # play level 09 $ echo 'AL{...}' | nc ctf.unik.cx 37295 # submit level 09's flag
Two ports per level: one to play (connect and explore), a separate one to submit the flag you find — submission is checked server-side against a stored SHA-256 digest and never touches the play session. The level board below still keeps a personal checklist in this browser the same way it does for 00–08; submitting on the real port is the graded, cheat-resistant proof of solve.
| Level | Play port | Submit port |
|---|---|---|
| 09 | 27295 | 37295 |
| 10 | 24251 | 34251 |
| 11 | 26462 | 36462 |
| 12 | 27575 | 37575 |
| 13 | 20824 | 30824 |
| 14 | 21292 | 31292 |
| 15 | 21338 | 31338 |
| 16 | 29492 | 39492 |
| 17 | 20918 | 30918 |
| 18 | 27751 | 37751 |
-
level 00
Foothold
50 ptsreinforces · Logging In
Connect to the level-0 box. It hands you the flag just for showing up — get comfortable with
nc.ncconnect -
level 01
Hidden in plain sight
75 ptsreinforces · Learning the Terminal
The box prints a noticeboard. One line is the flag, only encoded — read it, decode it.
ncbase64 -d -
level 02
Needle, meet haystack
100 ptsreinforces · Learning the Terminal
The box streams thousands of lines; exactly one carries the token. Filter the stream, don't scroll it.
ncgreppipes -
level 03
Permission denied
125 ptsreinforces · Security Configuration
The box guards the flag behind a pass-word. Read the prompt and send the right word back.
ncstdinprotocols -
level 04
In the logs
150 ptsreinforces · Storage, Monitoring, and Troubleshooting
Ask the box for its logs, then dig the token out of the noise it dumps.
nccommandsgrep -
level 05
Cron and on
175 ptsreinforces · Automation
The box flashes a token once, on a timer. Stay connected and catch it as it goes by.
ncstreamspatience -
level 06
Listening
200 ptsreinforces · Network Configuration
The box poses a challenge and wants the answer before it yields the flag. Parse it, compute, reply.
ncparserespond -
level 07
Mounted
225 ptsreinforces · Storage, Monitoring, and Troubleshooting
The box has an undocumented command its help won't list. Enumerate until it gives.
ncenumeration -
level 08
The vault
300 ptsreinforces · Everything
The flag is split across two of the box's commands. Pull both halves and combine them.
ncsynthesis -
level 09
Trusted by name
250 ptsreinforces · Security Configuration · hard track, ctf.unik.cx
A root-owned watcher runs a helper program by name only, never a full path. If you control where it looks first, you control what it runs.
PATHexecvetrust -
level 10
Echo chamber
275 ptsreinforces · Security Configuration · hard track, ctf.unik.cx
A root-owned watcher builds a shell command out of a value you get to set. It never checks what's inside it before running it.
shell injectionquoting -
level 11
Borrowed script
300 ptsreinforces · Security Configuration · hard track, ctf.unik.cx
A root process runs a script on a timer. Nothing stops you from rewriting that script before it runs again.
file permissionsrace -
level 12
Old sessions
175 ptsreinforces · Learning the Terminal · hard track, ctf.unik.cx
Somebody worked here before you. Their shell still remembers what they typed — including where they put things.
historyfind -
level 13
One line in ten thousand
200 ptsreinforces · Storage, Monitoring, and Troubleshooting · hard track, ctf.unik.cx
Four thousand access-log lines. Exactly one of them isn't like the others. Isolate it.
greplog analysis -
level 14
Taken literally
325 ptsreinforces · Security Configuration · hard track, ctf.unik.cx
A root-owned watcher evaluates a value you control as if it were shell code, not data.
evalenv vars -
level 15
Wrong turn
350 ptsreinforces · Security Configuration · hard track, ctf.unik.cx
A root-owned watcher reads a file whose name you choose. Nothing stops that name from walking upward.
path traversal.. -
level 16
Overflowing
500 ptsreinforces · Security Configuration · hard track, ctf.unik.cx
A tiny network service reads more than it should into a fixed-size buffer. Control the overflow, redirect execution.
buffer overflowret2win -
level 17
More privileged than you look
400 ptsreinforces · Security Configuration · hard track, ctf.unik.cx
This box runs as an ordinary user — except for one Linux capability nobody meant to leave switched on.
capabilitiesgetcap -
level 18
The deploy hook
450 ptsreinforces · Everything · hard track, ctf.unik.cx, capstone
Final box. A deploy log hints at an optional hook script the box will run if you leave one in the right place. Chain what you've learned to get there.
log readinghookssynthesis
The level board validates flags in your browser against
SHA-256 hashes — it never holds the answers. The browser arena above is
the exception: in practice mode it plants the flags into the client-side
emulator so you can actually solve each level offline. Want the real thing? The live boxes are Nanos unikernels —
one per level on unik.cx (tcp 13370–13378), each a single Go
app that hands over its flag when you solve it.