The Linux Exploitation Fundamentals series walks through a progression of binary exploitation techniques. Every tutorial analyses a purpose-built vulnerable binary; this guide shows you how to build them and set up a working lab environment.
All source code lives in the linux-tutorial-tools repository on GitLab.
Warning
These binaries are intentionally vulnerable. Use a disposable VM that contains no valuable data or credentials. A container is process isolation, not a security boundary for a privileged exploit-development lab.
What’s Included
Each directory contains a C source file, a Makefile with the exact compiler flags needed to reproduce the vulnerability, and a README explaining how to verify offsets on your system.
| Directory | Binary | Tutorial | Arch | NX | PIE | Canary | RELRO |
|---|---|---|---|---|---|---|---|
01-hidden-function/ | reader | Redirecting Execution | x86 | Off | Off | Off | Partial |
02-basic-overflow-x86/ | vuln | Basic Stack Overflow | x86 | Off | Off | Off | Partial |
03-overflow-x64/ | vulnerable | Stack Overflow x64 | x64 | Off | Off | Off | Partial |
04-ret2libc-x86/ | vulnerable | Return-to-libc | x86 | On | Off | Off | None |
05-rop-x64/ | bypass_nx | ROP NX Bypass | x64 | On | Off | Off | Partial |
06-mprotect-rop/ | target | mprotect ROP | x64 | On | Off | Off | N/A |
07-aslr-bypass/ | target | ASLR Bypass | x64 | On | Off | Off | Partial |
08-socket-reuse/ | server | Socket Reuse | x86 | Off | On | Off | Partial |
09-format-string-x86/ | vuln | Format String x86 | x86 | On | Off | On | Partial |
NX is disabled for the first three exercises (shellcode on the stack) and on for most of the later ones (forcing ret2libc and ROP techniques); exercise 8 turns NX off again so the socket-reuse tutorial can demonstrate stack-resident shellcode in a remote service. PIE is only enabled for exercise 8, where the tutorial demonstrates leaking addresses to defeat it. Exercise 6 is statically linked so that mprotect is available directly in the binary. Exercise 9 leaves the stack canary on intentionally, the format string bug doesn’t smash the saved return pointer, and the same binary is used in the next tutorial to demonstrate canary leakage.
Docker setup inside a disposable VM
The provided image includes GCC with multilib, GDB-PEDA, pwntools, ROPgadget, ropper, and checksec, with the exercise binaries pre-built. Run it on a disposable VM host, not directly on a workstation that holds credentials or production access.
git clone https://gitlab.com/sfoerster/linux-tutorial-tools.git
cd linux-tutorial-tools
docker compose up -d
docker compose exec lab bashOnce inside the container, verify the build:
checksec --file=01-hidden-function/readerRELRO STACK CANARY NX PIE
Partial RELRO No canary found NX disabled No PIEThe repository’s Compose profile is intentionally privileged so GDB can attach
and the exercises can control process layout. Linux does not namespace
kernel.randomize_va_space; a privileged container that writes that sysctl can
change ASLR on its host. That is why the host for this lab should itself be a
disposable VM. Stop the stack when the lab is over and confirm ASLR on the VM
host with sysctl kernel.randomize_va_space.
Native Setup (Alternative)
If you prefer to build natively on a Debian or Ubuntu system:
# Install dependencies
sudo apt update
sudo apt install -y gcc gcc-multilib gdb python3 python3-pip python3-venv \
socat nasm netcat-openbsd checksec make curl git
# Clone and build
git clone https://gitlab.com/sfoerster/linux-tutorial-tools.git
cd linux-tutorial-tools
make
# Disable ASLR on this disposable VM (not on a general-purpose workstation)
echo 0 | sudo tee /proc/sys/kernel/randomize_va_spaceNote
kernel.randomize_va_spaceis host-wide. Run this only on the disposable VM, and re-enable it when you finish:echo 2 | sudo tee /proc/sys/kernel/randomize_va_space.
You’ll also want GDB-PEDA and pwntools:
# GDB-PEDA
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit
# pwntools + gadget finders
python3 -m venv ~/pwn
source ~/pwn/bin/activate
pip install pwntools ROPGadget ropperDirectory Structure
linux-tutorial-tools/
├── 01-hidden-function/ # reader binary (SUID exercise)
├── 02-basic-overflow-x86/ # vuln binary
├── 03-overflow-x64/ # vulnerable binary
├── 04-ret2libc-x86/ # vulnerable binary (NX on)
├── 05-rop-x64/ # bypass_nx binary
├── 06-mprotect-rop/ # target binary (static)
├── 07-aslr-bypass/ # target binary
├── 08-socket-reuse/ # server binary (PIE on)
├── 09-format-string-x86/ # vuln binary (canary on)
├── Dockerfile
├── docker-compose.yml
├── Makefile
└── tests/
└── test_binaries.shEach exercise directory contains a Makefile with the exact flags used to compile the binary and a README.md that documents expected offsets and how to rederive them with GDB-PEDA if your compiler produces different results.
Verifying the Build
Run the included test script to validate that every binary has the correct security properties:
./tests/test_binaries.shOr verify an individual binary with checksec:
checksec --file=05-rop-x64/bypass_nxRELRO STACK CANARY NX PIE
Partial RELRO No canary found NX enabled No PIE[!important] Buffer offsets depend on your compiler version, glibc version, and build flags. If your exploit doesn’t work with the offsets shown in a tutorial, each exercise README explains how to rederive the correct offset with GDB-PEDA’s
pattern create/pattern offsetworkflow.
Tooling Overview
The Docker image (and the native setup above) includes everything the tutorials reference:
- GDB + PEDA, debugging, pattern creation, offset calculation
- pwntools, Python exploit scripting (
from pwn import *) - ROPgadget / ropper, automated gadget search for ROP chains
- checksec, verify binary security properties (NX, PIE, canary, RELRO)
- socat, network forwarding for the socket reuse exercise
- nasm, assembler for custom shellcode
- netcat, connecting to remote services