A closer look
at what breaks.

The archive pairs deliberately vulnerable programs with their original source and solution files. This guide helps you find a starting point and understand what each file contributes.

Begin with a small program.

You do not need to understand every technique before opening a challenge. Familiarity with C variables, function calls, basic Python, and a Linux command line gives you a useful foundation.

Blessing Registry Hack is a compact introduction to a stack buffer overwrite. Iftar Rush Registration focuses on something different: reading prompts and automating an interaction. Those are separate skills, and both help when reasoning about a program.

For the next step, The Secret Iftar Recipe introduces format-string disclosure. The more advanced collection adds questions about address layout, control flow, and the assumptions a solution makes about its environment.

Choose a challenge by technique or difficulty

Each file answers a different question.

Challenge brief Description.md
What is the intended task? The original description provides the competition framing and any supplied connection details.
Source .c
What does the program actually do? Read its inputs, checks, and important state changes. Comments are useful context; executable code is the stronger evidence.
Solution .py / solver.md
How does the included solution interpret that behavior? Compare its assumptions with the source and supplied binary rather than treating it as a universal recipe.
Environment Dockerfile / compose.yml
Which environment was packaged with the challenge? These files describe build steps, dependencies, and service configuration.
Supporting files ELF / libc / loader
When supplied, these identify the actual executable and runtime components. Addresses, behavior, and protections can depend on these exact artifacts.

Competition endpoints and hardcoded values are historical context. An archived solver’s assumptions may need review before it matches a different local environment.

A small vocabulary,
a clearer mental model.

Stack buffer overflow

A program writes beyond a stack buffer’s bounds. The effect depends on nearby data and the compiled layout; changing a neighboring variable is different from changing control flow.

Format-string vulnerability

User-controlled text becomes the format argument of a function such as printf. Formatting directives can make the function interpret unintended values as arguments.

Information disclosure

Program state or memory becomes visible when it should not be. A leaked value can matter even when the same input does not directly modify memory.

PIE & ASLR

Position-independent executables and address-space randomization change where code or data appears in memory. They complicate fixed-address assumptions; they do not remove the underlying bug.

GOT & RELRO

The Global Offset Table supports dynamic symbol resolution. RELRO affects whether relevant relocation data remains writable after loading. Reading a table entry and overwriting one are different operations.

NX

Non-executable memory protections restrict where instructions can run. They change which approaches are possible, while leaving separate questions about memory safety and control flow.

Stack canary

A value placed near sensitive stack state can reveal some overwrites before a function returns. Its presence does not mean every memory error is detected.

ROP & ret2libc

These describe ways of reusing code already present in a process. Understanding them starts with function calling conventions, runtime libraries, and the state a program carries between calls.

Explain the transition,
not just the result.

  1. Describe the normal path.

    Identify the inputs, the state they change, and the condition the program expects to enforce.

  2. Separate facts from assumptions.

    Distinguish what the source guarantees from what depends on a particular compiler, binary, library, or runtime setting.

  3. Follow the solution’s reasoning.

    Connect each meaningful action to a specific part of the program. If a comment and the code disagree, record the discrepancy.

  4. Return to the defensive lesson.

    Ask which input boundary, formatting decision, or memory-management choice introduced the bug. Then separate a root-cause fix from a mitigation that only limits its consequences.

The archive’s reader keeps the brief, source, solution, and environment together. Use the contents list to move between them, wrap long source lines when needed, and copy or download the original file for closer study.

Go back to the definitions.

The CWE entry on stack-based buffer overflows explains the weakness and its mitigations. The GNU linker documentation covers options that affect executable layout and memory protections.