We again get their libc version. It gives us a leak, but this time it begins with 0x56
, so likely something in the binary. If we step through in a debugger again, we find the program actually gives us the address of main. This lets us calculate the binary base.
We're going to need to use the libc somehow, so we can use the PLT and the GOT to leak a libc address.
Because the GOT is inside of the binary itself and is a table of libc addresses, if we can read the GOT we can read a libc address.
Meanwhile, the PLT is also inside of the binary. The PLT has a bunch of stubs, allowing us to call a libc function without it's address.
printf is called before we input. So it's GOT entry will contain it's libc address.
Thus, we can call printf on printf in got to leak printf's address, subtract appropriately to get the libc base, and then do what we did last time. in 64-bit, arguments are in rdi, then rsi, then rdx, etc. We need a pop rdi gadget in order to call system("/bin/sh")
. The gadget would essentially be a piece of code within the binary that does "pop rdi ; ret"
, popping the next value off the stack into rdi and then returning to the next return address.
So our exploit must:
Use address of main to get binary base and address of gadgets and GOT and PLT
call printf on printf in got to leak it's address (and call vuln afterwards so we get another input)
Use this to calculate libc base and address of other things we want
On second input, do padding + pop rdi + address of /bin/sh + address of system