I came across this code showing format string exploitation while reading this article.
#include <stdio.h>
int main(void)
{
char secret[]="hack.se is lame";
char buffer[512];
char target[512];
printf("secret = %pn",&secret);
fgets(buffer,512,stdin);
snprintf(target,512,buffer);
printf("%s",target);
}
Executing it with following input
[root@knark]$ ./a.out
secret = 0xbffffc68
AAAA%x %x %x %x %x %x %x //Input given
AAAA4013fe20 0 0 0 41414141 33313034 30326566
- [root@knark]$
What I understand till now is the sequence of %x‘s will keep on printing the values at addresses above current %esp (I’m assuming that stack is growing downwards towards lower address).
What I’m unable to understand is the input given is stored in buffer array which can’t be less than 512 bytes away from current %esp. So, how can the output contain 41414141 (the hex representation of AAAA) just after the 4 %x, i.e, just above the 4 addresses of current %esp. I tried hard to stare at assembly code too but I think I couldn’t follow the manipulation of strings on stack.
On entry to
snprintf, the stack has the following:targetgets overwritten with the result ofsnprintfbeforesnprintfgets to use its words as arguments: It first writes “AAAA” (0x41414141) at 0xbfd25800, then “%x” reads the value at 0xbfd257ec and writes it at 0xbfd25804, …, then “%x” reads the value at 0xbfd25800 (0x41414141) and writes it at 0xbfd25814, …