学习 fastbin_dup_consolidate

借着 how2heap 这个专题,我们来研究一下 glibc2.25 中的 malloc_consolidate

0X00 例子

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

这个例子就是告诉我们,在分配 large bin chunk 的时候,会调用 malloc_consolidate(),这个函数会遍历所有的 fastbin 把里面的 chunk 该合并合并,该清楚使用就标志清楚使用标志,然后全部插入 unsorted bin 中。

在下一次 free 的时候,判断是不是 double free 仅仅根据从同一个大小的 fastbin 中拿出第一个 bin,比较地址是不是相同

而我们的 chunk 早到 unsorted bin 中去了。所以为 0。所以现在 fastbin 和 unsorted bin 中都有同一个 chunk

也就是我们可以把它 malloc() 出来两次

0X01 动手调试

调试一下,做个纪念

直接进入 malloc(400) 中:

进入 _int_malloc 中:

重点来了,进入 malloc_consolidate 中:

maxfb 是最大 size 的 fastbin 的地址,fb 是最小 size 的 fastbin 的地址,下面那个循环正是开始遍历,所有的 fastbin

由于现在就一个 fastbin 中间很多的代码都没有执行

大致意思就是把 fastbin 中所有的 chunk 拿了出来,该合并合并,该消除标记就消除标记。然后插入 unsorted bin 中

最后从 top_chunk 中分配一个 large bin chunk

我们再来看看 double free:重点都在这里

从相同大小的 fastbin 中拿出上一个被释放的 chunk,但是显然这里的 chunk 已经不存在了,在 unsorted bin 中了。所以 double free 被绕过了。

所以就会有一个 chunk 既在 unsorted bin 中又在 fastbin 中。

完结撒花。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。