How the Labs Work
Sprinkled throughout this course are labs and challenges designed to test your knowledge. The labs ask you to put the previous lessons into practice, while challenges may draw on skills from several sections. These will be your first chance to write real exploits against real code.
What a lab is
Section titled “What a lab is”You get the complete source, a build script, and one sentence saying what you’re trying to make the program do. How you get there is up to you, with hints available if you need them.
The challenges in Section 6 are the same idea with the hints taken away and more than one section’s material in play at once.
The hints are free
Section titled “The hints are free”Each lab has a numbered ladder of hints. They go in order, and each one tells you more than the last:
- Where to look, without naming the bug.
- Which mechanism is involved.
- What to measure, and what to measure it with.
- The number or command that most people need.
- The step people actually get stuck on, which is usually not the one they expect.
After the hints, there’s a walkthrough you can expand to see the whole route. If you’re stuck, I’d rather you read it and try again than spend three evenings grinding on the same wall and quit.
Open as many hints as you like; there’s no score or record of which ones you used. Reading a solution isn’t the same as working it out, though. If you want to check how much stuck, come back in a couple of weeks with a fresh extraction and try it without the walkthrough.
Checking the flag
Section titled “Checking the flag”For a target whose goal is to reveal a flag, the program prints it when you succeed. Paste the complete flag into the lab page’s check field to see whether it matches. The check runs locally in your browser without sending your answer to a server. For a lab with a variable result, use the stated success criteria instead of looking for an exact count.
Notes and writeups are optional. Some versioned archives still describe a report or an evidence log in their task files; follow this course page’s completion check. Keep any source or scripts needed to repeat your run.
Getting the files
Section titled “Getting the files”Every lab page gives you a download link and a SHA-256 digest, which is a fingerprint of the expected archive. Comparing the downloaded file with that value tells you whether its bytes changed in transit; it does not tell you whether the program inside is safe. Replace <name> and <version>,
including the angle brackets, with the values from your download’s filename. For example, a file
called example-v1.0.0.tar would use example and v1.0.0.
Download the archive into ~/underdunn-course/downloads, then check it against the digest on the lab
page:
cd ~/underdunn-course/downloadssha256sum <name>-<version>.tarIf it differs, stop. Delete it, download a fresh copy, and check it again before you run anything.
mkdir -p ~/underdunn-course/labs/<name>tar -xf <name>-<version>.tar -C ~/underdunn-course/labs/<name>cd ~/underdunn-course/labs/<name>/<name>-<version>sha256sum -c CHECKSUMS.sha256Every file listed has to report OK. If any file fails or is missing, stop and use the recovery
instructions below. Only after all the checks pass should you build:
sh build.shThe archives are source only, so you compile the target yourself and can read everything that went into it.
Read TASK.md and the source, then use the program normally for a while so you know what to expect
before you start changing things.
Unless a lab says otherwise, work on the plain build from build.sh and leave address randomization
at its default. Address randomization changes where parts of a process are placed between runs. The
ASLR lesson explains the protection; until a page explicitly changes it, leave the VM setting alone.
When something looks broken
Section titled “When something looks broken”The archive or an internal checksum doesn’t match. Don’t build or run those files. If you’ve already worked in the extracted directory, save that attempt as described under Reset and cleanup. Download a fresh copy, extract it separately, and check it again.
A diagnostic tool changes the behavior. AddressSanitizer adds checks when you compile the program; Valgrind’s Memcheck runs it with extra checks. Both help find memory errors, but they can also change memory layout and timing. Compare results from the same build and tool configuration.
A payload that worked stops working. Run it again unchanged before you edit it. A few of these targets have an input path that a particular byte value will truncate, and the lab page says so where it applies.
Something disagrees with what a page claims. The numbers in this course were measured on the course VM’s GCC and glibc. If yours differ, that’s worth knowing about and my contact details are on the main site.
Reset and cleanup
Section titled “Reset and cleanup”Restarting the program gives you a fresh process. It doesn’t undo changes you’ve made to the files. For a clean extraction, keep the current attempt by renaming its directory first. That preserves your notes, modified source, and scripts together.
The example below uses attempt-1 for the backup. Choose another suffix if that name already
exists, and replace <name> and <version> as before:
cd ~/underdunn-course/labs/<name> &&mv -T -- <name>-<version> <name>-<version>-attempt-1If the rename fails, stop and check the path before continuing. Once your attempt is safely set aside, repeat Getting the files above using the verified archive. Check the extracted files before building again.
Cleanup is optional. Keep the verified archive and any notes, modified source, or scripts you’d want when you return to the lab. Remove build outputs or old attempts only when you’re sure there’s nothing in them you want to keep.