Format String Vulnerability
A format string vulnerability is a bug where user input is passed as the format argument to printf
, scanf
, or another function in that family.
The format argument has many different specifiers which could allow an attacker to leak data if they control the format argument to printf
. Since printf
and similar are variadic functions, they will continue popping data off of the stack according to the format.
For example, if we can make the format argument "%x.%x.%x.%x", printf
will pop off four stack values and print them in hexadecimal, potentially leaking sensitive information.
printf
can also index to an arbitrary "argument" with the following syntax: "%n$x" (where n
is the decimal index of the argument you want).
While these bugs are powerful, they're very rare nowadays, as all modern compilers warn when printf
is called with a non-constant string.
Example
#include <stdio.h>
#include <unistd.h>
int main() {
int secret_num = 0x8badf00d;
char name[64] = {0};
read(0, name, 64);
printf("Hello ");
printf(name);
printf("! You'll never get my secret!\n");
return 0;
}
Due to how GCC decided to lay out the stack, secret_num
is actually at a lower address on the stack than name
, so we only have to go to the 7th "argument" in printf
to leak the secret:
$ ./fmt_string
%7$llx
Hello 8badf00d3ea43eef
! You'll never get my secret!