how2heap - fastbin_dup
미루고 미뤘던 힙 공부를 하는데 아무리 다른 블로그들을 봐도 그냥 how2heap 번역이랑 malloc.c 분석이 가장 도움이 될거 같아서 how2heap 번역을 한다....
그래서 그나마 젤 쉬운 fastbin_dup에 관해서 한번 봐 보려고 한다.
fastbin은 32bit는 64byte 까지, 64bit는 128byte까지의 크기를 가진다.
스택처럼 LIFO 방식을 사용하며 단일 연결리스트로 이루어져 있다.
int main() { fprintf(stderr, "This file demonstrates a simple double-free attack with fastbins.\n"); fprintf(stderr, "Allocating 3 buffers.\n"); int *a = malloc(8); int *b = malloc(8); int *c = malloc(8); fprintf(stderr, "1st malloc(8): %p\n", a); fprintf(stderr, "2nd malloc(8): %p\n", b); fprintf(stderr, "3rd malloc(8): %p\n", c); fprintf(stderr, "Freeing the first one...\n"); free(a); fprintf(stderr, "If we free %p again, things will crash because %p is at the top of the free list.\n", a, a); // free(a); fprintf(stderr, "So, instead, we'll free %p.\n", b); free(b); fprintf(stderr, "Now, we can free %p again, since it's not the head of the free list.\n", a); free(a); fprintf(stderr, "Now the free list has [ %p, %p, %p ]. If we malloc 3 times, we'll get %p twice!\n", a, b, a, a); fprintf(stderr, "1st malloc(8): %p\n", malloc(8)); fprintf(stderr, "2nd malloc(8): %p\n", malloc(8)); fprintf(stderr, "3rd malloc(8): %p\n", malloc(8)); }
이 기법의 핵심부터 말하면 같은 크기로 malloc을 3번 a,b,c 했을 때 a -> b -> a 순으로 free 한 담에 다시 malloc을 3번 했을 때 첫번째와 세번째 힙 공간이 같은 부분에 할당받는다는 것이다.
double free attack 을 이용하는 것인데 바로 a를 두번 free하면 crash가 나게 된다. a -> a free하는 것과 a -> b -> a순으로 하는 것이 뭐가 다른지 살펴보자
먼저 a->b->a순으로 free하는 경우를 살펴보자.
현재 이와같이 malloc(8)을 3번 호출하여 힙이 할당된 모습이다. 여기서 a를 free해보자
??? 변화가 없다... free 되었다고 나와야 되는데...?
fastbin에도 등록이 되지 않았다. 그런데 아까와 다른점은 tcache_entry라는 것이 생겼다.
음... 이게 뭐지...?
그러면 다시 b를 free하면???
또 변화가 없다.... fastbin에 들어갈 줄 알았는데.....
그대신 tcache_entry가 또 달라졌다.... 구글링해보니 tcache_entry가 fastbin의 역할을 하는듯?? 날 잡고 분석해야겠다.
어쨋든 tcache_entry의 상태는 b -> a를 가리키고 있다. fastbin과 비슷하다고 했으므로 이것도 single list에다가 lifo인듯 하다.
여기서 다시 a를 free해보자
tcache_entry의 형태가 이제 a-> b -> a의 형태로 변경되었다.
이제 그럼 malloc을 하면 a-> b -> a 순으로 영역이 할당될 것이다.
실제로 그렇게 할당이 된 것을 확인할 수 있었다.
그 다음으로 a-> a 순으로 free를 하면 double free라고 하면서 corruption이 나야 정상인데 안난다.....
fastbin에서는 두번 free하면 fd가 top chunk로 바뀌어서 double free가 났는데 tcache_entry는 그런거 없나보다... 그럼 fastbin이랑 tcache_entry로 들어가는 기준을 모르겠다 더 봐야할듯!!!
reference : http://code1018.tistory.com/193
https://www.lazenca.net/display/TEC/fastbin_dup#space-menu-link-content