How to contact us
Via email: email@example.com
How it all works
tl;dr: Given a debugger and a device, find an input that unlocks it. Solve the level with that input.
You've been given access to a device that controls a lock. Your job: defeat the lock by exploiting bugs in the device's code.
You're playing "Capture The Flag". You collect points for each level you beat, working your way through steadily more complicated vulnerabilities. Most levels showcase a single kind of real-world software flaw; some levels chain a series of them together.
This device has a simple input: you provide a passcode, and if the passcode is correct, the lock unlocks. Just one problem: you don't know the passcode. Unlock it anyways.
We've done the tedious work for you: we got the device working, hooked a rudimentary debugger up to it, dumped the code for each level and disassembled it for you.
You'll use the debugger to reverse-engineer the code for each level. You can provide the device with input, then step through the code watching what the device does what that input. You're looking for a specific input that unlocks the device. Maybe that input is the correct passcode. More likely, though, it's something else: an input that exploits a bug in the device's code.
What you'll need to know
Start by reading the manual.
You'll want to grok assembly language. Don't know assembly language? Awesome: we designed this CTF for you. You're playing with one of the simplest CPU architectures that GCC can compile code for. You're about to learn assembly. There's a terse intro to the assembly code for this device in the manual; Wikipedia will tell you everything else you need to know.
You'll want to know how to use a low-level debugger. Haven't done that before? Awesome: we designed this CTF for you. You're playing with the dumbest debugger anyone ever built for a web browser. Type "help" at the debugger console. You can single-step instructions. You can look at register values. You can scroll through the (small) memory of the device. Click on an instruction in the disassembly to set a breakpoint. When in doubt, type "reset" and try again.
You'll want to know a bit about memory corruption vulnerabilities. Feeling lost? Let's see if we can't clear that up in just a few sentences:
- Trick a device into consuming more input than it allocated memory for and you've caused a buffer overflow.
- Overflow a buffer that lives on the program stack and you've "smashed the stack"; look that up on Google if you like, but the exploit is simple: overwrite another stack variable, often the return address of the function you're in, and use that to take control of the device, often by aiming the CPU at memory you control.
- Overflow a buffer that was created by an allocator and you've "corrupted the heap": allocators keep metadata to track the memory they're managing, and they trust that only the program can manipulate that metadata; corrupt to trick the program into writing to arbitrary places in memory.
- Zero bottles of beer on the wall, zero bottles of beer; take one down, pass it around, 65535 bottles of beer on the wall.
There's more stuff to find, but them's the basics.