Project 3: The Format String Bug Lab

A vulnerable program that takes user input and passes it directly to printf. This lab has three stages: (1) Use format specifiers like %x to leak data from the stack. (2) Use the %s specifier to read a secret string from a known address. (3) Use the %n specifier to overwrite a variable in memory and gain admin privileges.

Quick Reference

Attribute Value
Primary Language C
Alternative Languages N/A
Difficulty Level 3: Advanced
Time Estimate 1-2 weeks
Knowledge Area Exploit Development / Memory Disclosure / Arbitrary Write
Tooling GCC/Clang, GDB, Python
Prerequisites Project 2 (Stack Smashing).

What You Will Build

A vulnerable program that takes user input and passes it directly to printf. This lab has three stages: (1) Use format specifiers like %x to leak data from the stack. (2) Use the %s specifier to read a secret string from a known address. (3) Use the %n specifier to overwrite a variable in memory and gain admin privileges.

Why It Matters

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

Core Challenges

  • Leaking stack data with %x → maps to understanding how printf walks the stack
  • Positioning an address on the stack for %s → maps to crafting a precise payload
  • Using %n to write a value → maps to the concept of an arbitrary-write primitive
  • Calculating offsets and padding for a precise write → maps to fine-grained payload construction

Key Concepts

  • Format String Exploitation: A classic paper on the topic is “Exploiting Format String Vulnerabilities” by scut / Team Teso.
  • Variadic Functions: Understanding how functions like printf(const char*, ...) work.

Real-World Outcome

// The C code
int check_auth() {
    char password[16];
    int auth_flag = 0; // Should be 1 for admin
    char secret_message[] = "TheLaunchCodesAre0123";

    printf("Enter password: ");
    fgets(password, sizeof(password), stdin);

    printf("Log: ");
    printf(password); // Vulnerable!

    if (auth_flag) {
        printf("\nAccess Granted. %s\n", secret_message);
    } else {
        printf("\nAccess Denied.\n");
    }
}

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
  • “The Shellcoder’s Handbook”