Lion Cipher Lab
Exploit an integer overflow into a heap overflow — then fix it
- Penetration Testing / Red Team
- Advanced
- ~90 min
- Free · no account required
Why it matters
Some of the most expensive memory-corruption bugs in history are not dramatic — they are a single multiplication that quietly gave the wrong answer. A program computes how many bytes to allocate, the arithmetic overflows and wraps around to a small number, the allocation comes back far too small, and then a loop writes the amount the program THOUGHT it needed. The bounds were 'checked'; the check just ran on the wrong (wrapped) value. MITRE tracks the arithmetic fault as CWE-190 (Integer Overflow or Wraparound) and the exact pipeline you build here — an integer overflow that leads to an…
What you'll learn
- writing a tiny deliberately-vulnerable C program whose heap allocation size is computed by attacker-influenced multiplication (malloc(n * sizeof(record)))
- seeing a 32-bit size calculation WRAP — a huge count produces a tiny allocation — and reading the wrapped value out of the program's own output
- reproducing the resulting heap buffer overflow and reading AddressSanitizer's heap-buffer-overflow report: the out-of-bounds write, the region bounds, and the '0 bytes after a 16-byte region' line that proves the allocation was too small
- explaining WHY a size/bound check passed yet the loop still overran the buffer — the check tested the wrapped product, the loop trusted the original count
- fixing it with checked arithmetic (__builtin_mul_overflow and calloc's built-in multiply check) plus a sane upper bound, and proving the fixed binary rejects the malicious count cleanly
- the judgment: signed-vs-unsigned pitfalls, why calloc already checks the multiply, and why UBSan/-ftrapv do NOT catch an unsigned wrap (it is defined behaviour) so ASan and tests are what surface it
Steps in this lab
- Read this first: the target is your own program, on your own machine
- What this bug class is — an arithmetic mistake that becomes memory corruption
- How this differs from the stack buffer overflow lab — and why both matter
- Get a Linux machine, a compiler, and AddressSanitizer
- Write the deliberately-vulnerable program
- Compile with AddressSanitizer — and a legit run to show it works
- Trigger it: one crafted count, a tiny allocation, a heap overflow
- Why the check passed yet the buffer was too small
- Honest detour: what does and does NOT catch this automatically
- Fix it: checked arithmetic, calloc, and a sane bound — then prove it
- When, why, better — and the honest limits