내가 보려고 만든 ctf의 ctf를 위한 ctf에 의한 힙 익스 아이디어

=====================



일단 ctf에 자주나오는 하우스 시리즈 힙 유형을 살펴본다

기법들에 대해 자세히 설명하지는 않는다. 전체적으로 훑어 보기로 한다.

제일 잘나오는건 세 가지다




#### 1.fastbin dup attack


 정말 제일 만만하고 제일 많이 쓰인다. 0x80까지의 동적메모리의 해제가 자유롭고

 arbitrary overwrite이든 overflow든 해제한 메모리의 next bin ptr영역에 overwrite가 가능하다면 이 기법을 사용할 수 있다. 

fastbin dup으로 overwrite를 할때는 bin의 사이즈 단위가 중요한데(같은 단위가 아니면 abort 0x10단위로 존재) 


특히 0x70단위의 경우 0x0000007f가 써져있는 메모리 영역에 접근이 가능한데 64비트의 경우 0x7f는 libc주소의 앞자리임으로 요긴하게 사용할 수 있다.(0x7f는 malloc_hook 앞에도 늘 존재하기 떄문에 malloc_hook을 덮을 때 꿀을 빨자)



#### 2.1byte overflow로 발생하는 poison null byte


0x18 0x28이런식으로 8로 끝나는 주소로 할당(32bit의 경우 4)하는 경우 청크가 딱 붙게 된다. 

그래서 1byte라도 오버플로우나는 경우 또는 입력의 마지막을 null 처리 해주는데 그게 다른 청크로 침범이 가능할 경우에는 바로 이 기법이다.(후자는 거이 이 기법을 유도했다고 볼 수 있다)


마지막이 null이 된다는 건 chunk/bin의 flag를 건들일 수 있다는 것이다. flag의 마지막 비트는 prev_inuse비트로 바로 뒤의 청크가 할당된 상태인지 해제된 상태인지를 나타낸다. 이 비트가 원래 1이었는데 0이 된다는 것은 뒤의 청크가 할당이 되어있지만 해제 되어있는 것처럼 여긴다는 것이다. 

prev_inuse가 0인 chunk을 free 할때는 이전 청크가 free된 청크라고 생각해서 consolidate 즉 병합하려고 한다. 이전 청크를 찾아갈때는 pre_size를 이용해서 찾아가는데 size를 덮을 수 있는 overwrite이면 당연히 prev_size 도 overwrite가 가능하다. 이를 이용해서 fake청크와 병합되게 한후 malloc하면 fake chunk로 할당이 된당(fake chunk의 size는 small bin 크기여야하고 fake chunk의 fd bk는 fakechunk의 주소를 넣으면 unlink assertion 을 우회할수 있다) 





#### 3.unsorted bin attack 


libc메모리릭할때 요긴하게 쓰인다

small/large bin 을 free하고 전후로 해제했던 다른 bin 이 없으면 fd/bk가 main_arena랑 연결이 됨. 해제한 메모리에 접근이 가능할때 libc릭으로 요긴하게 쓰인다.

그리고 임의의 주소를 free할 수 있을 때 특정주소에 main_arena의 주소를 쓸 수 있다. 이거는 자주 쓰이진 않지만 언제 쓰일지 모름으로 염두에 항상 두자






이 세가지가 가장 많이 나오고 자주나오진 않지만 핵심이 될 수 있는 기법은

top_chunk를 덮어버리는 기법들이다 


#### 1.house of force

 

top chunk를 덮어서 엄청 크게 만든다음 다른 메모리 영역을 건드린다.


#### 2.house of orange


top_chunk free를 이용한 최초의 문제가 hitcon2016의 house of orange 문제였기 때문에 house of orange 기법이라 칭하겠다


분명히 heap 문제인 것 같은데 free하는 부분이 없다거나 약간 모자른데 오버플로우가 난다?하면 이거다. 게다가 size가 덮어진다?하면 100프로 이거다.

처음에 할당했던 heap영역이 다 차게 되면 top_chunk를 free해버리고 mmap을 다시함. 아무튼 중요한건 top_chunk가 ㄹfree된다는것. top_chunk의 사이즈를 조절해서 fastbin attack으로 쓸 수도 있고 unsorted bin attack으로 릭이나 overwrite로 쓸 수도 있다, 이때 top_chunk가 무너지면서 abort를 출력할때 IO_FILE을 사용하는걸 이용해서 취약점 트리거에 이용하거나 int_free를 공격벡터로 사용하기도 한다.


#### 3.마지막으로 main_arena를 전체적으로 건드릴수 있을 때 top chunk와 unsorted bin 포인터를 덮어버릴 수도 있다.





만약에??


1. unlink 함수를 직접 구현해 놨다? -> 백퍼센트 unlink 취약점이다. unlink는 최신 glibc에 막혀있다.

막혀있기 전에는 unlink 할떄 bk->fd->bk=obj 또는 fd->bk->fd=obj를 확인하지 않았다.

그래서 obj의 fd bk overwrite만 가능하면 unlink취약점을 어렵지 않게 트리거 할 수 있다.


2. 당장 생각이 안나니 추후 추가




**이래도 취약점이 안보이면?**


_만약에 heap바이너리가 너무 크다 하면 왠만하면 uaf가 숨어있다. 잘 찾자! c++의 경우 vtable을 유념해서 봐보도록하자_

또는 how2heap의 다른 기법을 뒤져보자

+ Recent posts