Why I built it
Offensive skills fade without repetition. Scanning through a proxy, building tunnels, spraying credentials, moving files, escalating privileges and reading packet captures all come down to muscle memory. I wanted the whole chain on my own machine, ready whenever I had an hour, and different every time so I couldn't coast on remembered answers.
What's in it
- A Kali desktop in the browser. One command starts the lab and opens Kali in a browser tab. A lighter terminal-only mode covers machines that struggle with the desktop.
- A small network to work through. A jumphost, a router and three targets, each built around a different technique, with eight objectives that chain from reconnaissance to root.
- Notes that persist. A notes folder in Kali is mounted from the host, so operator notes survive resets and rebuilds.
- Unlimited reps. A reset rebuilds every target with new flags and new passwords.
Forcing the pivot
The topology makes the rules. Kali sits on an edge network, the targets sit on an internal network, and only the jumphost is on both. There is no shortcut around the tunnel, so reaching a target means actually building and using one. The internal network has no route to the internet, so nothing deliberately vulnerable can reach out, and the browser ports are bound to localhost.
Fresh secrets every run
Flags and passwords are generated randomly at first start and again on every reset. A small local script checks submitted flags against that run's values and tracks progress across objectives, with no server involved. Because every run is different, the only way to finish is to do the work again.
Portable by design
I wanted the range to run on any machine I sit down at, which took more engineering than the targets themselves.
- A preflight check that tests, not assumes. It runs each dependency and checks the result. On Windows that matters: WSL's command always exists, and a placeholder Python opens the Microsoft Store instead of running.
- Matching launchers for every platform. Bash scripts on Mac and Linux, and double-click wrappers on Windows that run the PowerShell scripts without touching execution policy.
- Defensive defaults. Line endings are forced so Windows checkouts don't break the Linux containers, and a fixed project name means a second copy of the folder manages the same lab instead of colliding with it.
- Troubleshooting by error message. The README maps each error I'd expect to see, word for word, to an exact fix.
Tested like production
Kali and Debian are rolling releases, so a lab that builds today can break next week. Continuous integration builds every image from a clean checkout on each change, boots Kali as a user would, stands up the real topology and asserts the isolation rules still hold: Kali can't reach the internal network, and the targets can't reach the internet. That test caught a subtle bug, where Docker quietly reserves the first address of each subnet for itself and collided with the router's planned address.
The base images are pinned to exact digests, so every build produces an identical environment, and security updates arrive as a deliberate, reviewable change instead of silent drift.
What it reinforces
Running the attacker's side keeps my defensive work honest: it's easier to write a detection for a tunnel or a credential spray once you've built a few yourself. Building the range also exercised the same instincts I use at work. Isolate what's dangerous, generate secrets instead of hard-coding them, and test the guarantees you depend on rather than assuming them.