HITCON 2016 babyheap Write Up
0. introduce
문제를 푸는데 완전 신기했습니다. leak을 할 수 있는 취약점이 안보이면 format string을 이용해야한다는것을 알았습니다.
1. binary
heap문제인데 Full RELRO가 아니므로 heap 취약점을 통하여 got를 덮을것이라고 예상했다.
1. new
- read name, size, content
- allocate chunk1 : [size] + [name] + [*content]
- allocate chunk2(content) : [variable value]
2. delete
- check 0x6020A8 != 1
- free chunk1
- free chunk1_[*content]
- 0x6020A8 ++
3. edit
- check 0x6020A4 != 0
- read content(size)
- 0x6020A4 ++
4. exit
- print Really? (Y/n)
- read value from stdin by scanf
2. Vulnerability
name에서 data를 읽은 함수에 off by one 취약점이 발생하여 *content의 하위 1바이트를 null로 수정할 수 있다.
3. Exploit
익스전에 알아야할 내용이 있는데 scanf가 stdin에서 data를 받을때, heap영역에 입력받은 data를 복사한다.
분석을 해보면서 발견한건데 pwntool을 이용하지않고 프로그램을 시작해서 디버깅을하거나 gdb를 이용해 바로 디버깅을하면 0x410크기의 chunk를 할당하는데 pwntool을 이용해서 실행한 바이너리에 디버깅을하면 0x1010크기의 chunk를 할당한다.
그 이유는 뭔지 잘 모르겠지만 u_flow라는 함수에서 heap을 할당하던데 나중에 분석을 해봐야겠다. 그래서 이것을 이용하여 fake_chunk를 만들고 free해준뒤 fake_chunk크기만큼 new로 만들면 overlapping chunk 버그가 발생하여 원하는 모든 위치에 값을 쓸 수 있다.
그래서 exit의 got를 ret으로 덮어 edit을 계속 할 수 있게 바꿔주고 atoi의 got를 printf_plt+6의 값으로 덮어서 포맷스트링을 이용해 leak을 할 수 있다.
leak 이후에는 edit으로 atoi를 system으로 덮어서 /bin/sh를 인자로 쉘을 얻을 수 있다.
Full Exploit
(https://github.com/LYoungJoo/CTF-Write-Up/blob/master/2016_HITCON%20Write%20Up/babyheap.py)