Format String Vulnerability: Reading Memory Without Buffers

September 4, 2025

Format String Vulnerability: Reading Memory Without Buffers

Challenge 3: Format String Vulnerability Analysis (3_simple.c)

Source Code:

#include <stdio.h>

int main() {
    char name[32] = {0};
    printf("What is your name: \n");
    read(0, name, 32);
    printf(name);  // Format string vulnerability
    return 0;
}

// Compiled: gcc -Wall -Wextra -Iinclude -g -fno-stack-protector -no-pie -Wl,-z,norelro -o bin/3_simple src/3_simple.c

Vulnerability Description

The 3_simple.c program contains a format string vulnerability on line 7:

printf(name);

This is unsafe because the user-controlled input name is passed directly as the format string to printf() without a format specifier.

How the Vulnerability Works

  1. The program reads up to 31 bytes of user input into a 32-byte buffer name
  2. The input is then passed directly to printf() as the format string
  3. An attacker can include format specifiers like %x, %s, %n in their input to:
    • Read memory: %x reads values from the stack
    • Read arbitrary memory: %s treats stack values as pointers and dereferences them
    • Write to memory: %n writes the number of characters printed so far to a memory location

Example Exploit

Input like %x %x %x %x would leak stack values, potentially revealing:

  • Return addresses
  • Stack canaries
  • Pointer values
  • Other sensitive data

Other Vulnerable Functions

The following functions are also vulnerable to format string attacks when user input is passed as the format string:

Standard Library Functions:

  • printf(user_input) - prints to stdout
  • fprintf(file, user_input) - prints to a file
  • sprintf(buffer, user_input) - prints to a string buffer
  • snprintf(buffer, size, user_input) - prints to a string buffer with size limit
  • vprintf(user_input, args) - variadic version of printf
  • vfprintf(file, user_input, args) - variadic version of fprintf
  • vsprintf(buffer, user_input, args) - variadic version of sprintf
  • vsnprintf(buffer, size, user_input, args) - variadic version of snprintf

System Logging Functions:

  • syslog(priority, user_input) - system logging
  • err(eval, user_input) - error reporting
  • errx(eval, user_input) - error reporting without errno
  • warn(user_input) - warning messages
  • warnx(user_input) - warning messages without errno

Mitigation

Always use a format specifier when printing user-controlled data:

// Vulnerable
printf(name);

// Safe
printf("%s", name);

Try it yourself with my Github Repo - Exploit Development Step-by-Step There you are able to check the whole code and also the full exploit script.