해킹/Write Up

0ctf 2017 babyheap WriteUp

NextLine 2017. 5. 22. 11:43

0. introduce

babyheap은 취약점도 쉽고 익스도 쉽긴한데 libc_leak이 calloc때문에 좀 어려웠습니다. 요세 약간 malloc과 free가 헷갈렸는데 이 문제를 풀어보니까 malloc과 free에 대한 이해도를 높이는데 도움이 되었습니다. 그리고 확실히 계속 heap문제를 풀다보니 stack보다는 heap쪽 취약점이 더 재미있는것 같습니다.


1. Binary

요세는 거의 보호기법이 전부 걸려있는 바이너리를 보다 보니까 좀 익숙해진것 같다. 여기서 좀 거슬리는건 디버깅속도를 늦추는 PIE밖에 없다.


메뉴는 다음과 같다.


1. Allocate

- 처음에 무작위의 주소값을 mmap으로 할당해주고 그 주소값에 chunk들의 정보를 넣는다.

- size를 받아 calloc으로 chunk를 할당해준다.

- chunk의 정보는 아래와같이 넣어준다.


2. Fill

- index와 size를 입력받아 아래와 같이 chunk의 data를 채워준다. (sub_11b2의 첫번째 인자가 입력주소, 두번째 인자가 크기)


3. Free

- index를 받아 아래와 같이 free해준다.


4. Dump

- index를 입력받아 아래와같이 chunk의 data를 출력한다. (sub_11b2의 첫번째 인자가 입력주소, 두번째 인자가 크기)


2. Vulnerability

취약점은 fill에서 원하는만큼 값을 덮어쓸 수 있어서 heap overflow취약점이 발생한다. 매우 큰 취약점이기 때문에 이 취약점 하나로 leak과 exploit둘다 할 수 있다.


3. Exploit

1) libc leak

leak 원리는 아래 그림과 같다.

저렇게 free를 해주고 다시 0x50을 할당해주면 3번째 청크가 2번째 청크에 남아있는 상태가 된다. 하지만 calloc로 인해 0xa0의 chunk header가 0으로 지워지므로 fill로 header를 다시 만들어준뒤에 3번째 청크를 free하면 2번째 청크를 읽는것으로 3번째 chunk의 fd와 bk를 읽을 수 있다. 그래서 unsortedbin에 들어간 0xa0의 fd와 bk를 읽음으로써 libc를 leak할 수 있다. (투명한 주황색 chunk를 fill로 만들어주는 이유는 두번째 chunk를 free하기 위해서이다.)


2) fastbin fd overwrite

이건 단순하다. 두개의 fastbin chunk를 만들고 둘다 free하게 되면 두번째로 free한 chunk에 fd가 남는데 그 fd를 조작함으로써 원하는 위치에 malloc을 할당받을 수 있다. 실제 익스에서는 malloc hook을 덮었으므로 malloc hook 근처에있는 주소값을 이용해 0x7f의 chunk를 설정해 주고 fd를 그 주소로 덮어써서 malloc hook을 덮을 수 있었다.


Full Exploit Code

(https://github.com/LYoungJoo/CTF-Write-Up/blob/master/2017_0ctf%20Write%20Up/babyheap.py)