bin链情况集合

image-20210720154252123

fast bin

基本结构

  • 大小范围:0x20 - 0x80

  • 单链表结构,只有fd指针

  • FILO(最后一个进入fastbin链表的,会被放在头部)
    总共有十个fastbin链表,每个链表中fastbin的size一样,0x10递增
    大小属于fastbin的chunk被free掉时,不会改变nextchunk的previnuse位,也就是说不会被合并。

image-20210720154343954

检查

  • 被释放的堆块的fd指针不能指向自己(这也就是想要double free的时候,还需要一个中间chunk的原因)
  • 将fastbin里面的chunk分配出去时,会检查size位会不会匹配chunk的大小,会才能分配

小技巧

构造两个相同 size 的堆块 a 和 b,我们先 free (a) 让他进入到 fast bin 中,再 free (b) 也让他进入到 fast bin中。这时候,在堆块 b 的 fd 位置就存在着堆块 a 的地址,我们 leak 出来就能够得到堆地址

unsorted bin

基本结构

  • 只有一个双向链表,存在fd和bk指针

  • 在unsorted bin中,对chunk的大小并没有限制,任何大小的chunk(未被归类)都可以归属到unsorted bin中,临时存储用

  • unsortedbin采用的遍历顺序是FIFO

  • chunk被释放进入unsortedbin时,fdbk字段会留下一个main_arena的地址信息

unsorted bin attack

libc-2.29.so以下:

利用前提是先有UAF,修改 unsorted chunk 中的 FD 字段为0,BK字段为 target addr - 0x10,然后 malloc 一个相同大小的chunk,即可完成攻击,在目标地址写入 unsorted bin 的地址,一般用来伪造堆头(制造出0x7f)、修改次数限制、上限信息、配合局部写

小技巧

当 unsorted bin 链上有两个堆块的时候,其中一个堆块的 fd 会指向另一个堆块,我们可以直接 leak 得到,可计算出堆基址

small bin

基本结构

image-20210726103140256
  • 大小范围:0x90 - 0x400
  • 由62个双向链表组成,每个链表中的chunk大小一样,大小以0x10递增,存在fd和bk指针
  • 相邻的free chunk会触发合并操作,即合并成一个大的free chunk
  • 采用的遍历顺序是FIFO

小技巧

small bin 中存在两个块时,第一个块的fd指针指向main_arena,bk指针指向了下一个堆块,所以可以泄露出libc以及堆地址

large bin

基本结构

image-20210720153655147

image-20210726103541056

  • 大小范围:0x410 以上
  • 63个双向链表,不仅存在fd和bk指针,同时还有fd nextsize 和 bk nextsize
  • 同一个双向链表中chunk大小可以不一样,但是在一定范围内,bins大小从小到大排列
  • 相邻的free chunk会触发合并操作,即合并成一个大的free chunk
  • 采用的遍历顺序是FIFO
  • 在这63个largebins中:第一组的32个largebin链依次以64字节步长为间隔,即第一个largebin链中chunksize为1024-1087字节,第二个large bin中chunk size为1088~1151字节。第二组的16个largebin链依次以512字节步长为间隔;第三组的8个largebin链以步长4096为间隔;第四组的4个largebin链以32768字节为间隔;第五组的2个largebin链以262144字节为间隔;最后一组的largebin链中的chunk大小无限制。

小技巧

如果堆块在 largebin 中,他的 fd_nextsizebk_nextsize 都会指向堆块地址,可以泄露出堆地址

如果largenbin上仅有一个堆块,那该堆块的fd_nextsize和bk_nextsize指向自身

malloc过程

  • 计算真正堆块大小(加上头部长度、对齐)

  • 是否在fastbin范围内?

    • 是,检查对应的bin链表中有没有chunk
      • 有,分配给用户,结束
  • 如果不在fastbin范围内,或者没有chunk可用

  • 是否在smallbin范围内?

    • 是,检查对应大小的bin链表中有没有chunk
      • 有,分配给用户,结束
  • 如果不在smallbin范围内,或者smallbin里面也没有

  • unsortedbin中有没有chunk?

    • 有,从尾部取出第一个chunk,看看大小是否满足需求
      • 满足,切分后大小是否大于minsize?(64位下minisize为0x20)
        • 大于,切分块,返回给用户,剩下的块放进unsortedbin
        • 小于或等于minsize,直接全部分配给用户,结束
      • 不满足,把这个块放入small/largebin对应的链表中,继续遍历下一个块
  • 如果unsortedbin中所有的块也不能满足需求

  • 大小是否在largebin范围?

    • 是,检查对应的bin链表中有没有符合的chunk
      • 有,找到满足需求最小的chunk,切分块返回,剩下的放进unsortedbin中
  • largebin也不行?再次遍历small/large寻找最合适的chunk

  • 还是没有,那就从topchunk中切割

  • topchunk也不够?mmap系统调用

查看评论