Fastbin dup consolidate는 fastbin에 들어간 힙 청크들을 병합시켜 small bin에 넣어 Double Free검증을 우회하는 기법이다.
small bin에 들어간 fastbin 크기의 힙 청크를 한 번 더 해제하면 다시 fastbin에 들어가기 때문에 검증을 우회할 수 있다.
_int_malloc
#define have_fastchunks(M) (((M)->flags & FASTCHUNKS_BIT) == 0)
else
{
idx= largebin_index (nb);
if (have_fastchunks (av))
malloc_consolidate (av);
}
malloc 함수 내부에서 large bin크기의 할당 요청이 들어올 때 have_fastchunks 매크로를 통해 fastbin에 할당된 청크가 존재하는지 확인하고, 존재한다면 malloc_consolidate 함수를 통해 존재하는 청크들을 병합한다.
if (__builtin_expect (old == p, 0)
{
errstr = "double free or corruption (fasttop)";
goto errout;
}
이 과정에서 old와 p 포인터를 다르게 만들어 검증을 우회할 수 있다.
consolidate.c
// gcc -o consolidate consolidate.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
void *p1 = malloc(0x10);
void *p2 = malloc(0x10);
free(p1);
void *p3 = malloc(0x400);
free(p1);
char *ptr = malloc(0x10);
char *ptr2 = malloc(0x10);
printf("ptr: %p\n", ptr);
printf("ptr2: %p\n", ptr2);
}
fastbin 크기의 힙을 두 개 할당하고 첫 번째 청크를 해제한다.
만약 첫 번째 청크를 다시 해제한다면 old와 p 포인터가 같으므로 에러가 발생한다. 그러나 large bin크기의 힙을 할당하면 malloc_consolidate를 호출하여 fastbin에 존재하는 청크를 small bin에 삽입하고, 다시 첫 번째 청크를 해제하면 이는 fastbin에 삽입되기 때문에 에러 없이 Double Free를 발생시킬 수 있다.
p1이 해제되면서 fastbin에 들어간 것을 확인할 수 있다.
large bin 크기의 힙을 할당한 후의 상태이다.
large bin 크기의 힙이 할당되면서 fastbin이 small bin으로 병합된 것을 확인할 수 있다.
다시한번 p1을 해제하면 0x602000 주소가 fastbin에 들어가게 되는 것을 확인할 수 있다.
이후 0x10 크기의 힙을 두 번 할당하면 fastbin에 들어간 주소를 먼저 가져오고, 이후 small bin에 들어간 주소를 가져오기 때문에 두 개의 다른 포인터가 같은 힙 영역을 가리킬 수 있게된다.
consolidate의 실행 결과이다.
'Pwnable > Techniques' 카테고리의 다른 글
Memory Leak (0) | 2021.03.03 |
---|---|
Unsafe unlink (0) | 2021.03.01 |
Fastbin dup (0) | 2021.02.23 |
Double Free Bug (0) | 2021.02.23 |
_int_free (0) | 2021.02.22 |
댓글