Project 2: Stack Smashing 101 (ret2win)

A vulnerable C program with a password check and a hidden win() function that should never be called. Your goal is to write a Python script that crafts a special input string to overflow a buffer on the stack and overwrite the function’s return address, hijacking the program’s execution to call win().

Quick Reference

Attribute Value
Primary Language C
Alternative Languages Assembly (for understanding)
Difficulty Level 2: Intermediate
Time Estimate 1-2 weeks
Knowledge Area Exploit Development / Stack Overflows
Tooling GCC/Clang, GDB, Python (for exploit scripting)
Prerequisites Project 1, basic GDB knowledge.

What You Will Build

A vulnerable C program with a password check and a hidden win() function that should never be called. Your goal is to write a Python script that crafts a special input string to overflow a buffer on the stack and overwrite the function’s return address, hijacking the program’s execution to call win().

Why It Matters

This project builds core skills that appear repeatedly in real-world systems and tooling.

Core Challenges

  • Disabling security mitigations for the lab → maps to using GCC flags like -fno-stack-protector and -z execstack
  • Finding the buffer overflow → maps to identifying a vulnerable function like strcpy
  • Calculating the offset to the return address → maps to using GDB and pattern strings to find the exact number of bytes
  • Crafting the exploit payload → maps to combining padding with the address of win()

Key Concepts

  • Stack Frame Layout: “Hacking: The Art of Exploitation” Ch. 3
  • Controlling EIP/RIP: Numerous CTF writeups on “ret2win”
  • GDB with pwndbg/GEF: These GDB enhancers are essential for exploit dev.

Real-World Outcome

// The vulnerable C code
void secret_function() {
    printf("Congratulations! You've found the secret!\n");
    // In a real CTF, this would print a flag file.
}

void vulnerable_function() {
    char buffer[64];
    printf("Enter your password: ");
    gets(buffer); // Vulnerable!
}
// You are not supposed to be able to call secret_function().

Implementation Guide

  1. Reproduce the simplest happy-path scenario.
  2. Build the smallest working version of the core feature.
  3. Add input validation and error handling.
  4. Add instrumentation/logging to confirm behavior.
  5. Refactor into clean modules with tests.

Milestones

  • Milestone 1: Minimal working program that runs end-to-end.
  • Milestone 2: Correct outputs for typical inputs.
  • Milestone 3: Robust handling of edge cases.
  • Milestone 4: Clean structure and documented usage.

Validation Checklist

  • Output matches the real-world outcome example
  • Handles invalid inputs safely
  • Provides clear errors and exit codes
  • Repeatable results across runs

References

  • Main guide: LEARN_C_SECURE_CODING_DEEP_DIVE.md
  • “Hacking: The Art of Exploitation” by Jon Erickson