bin链情况集合
fast bin
基本结构
大小范围:0x20 - 0x80
单链表结构,只有fd指针
FILO(最后一个进入fastbin链表的,会被放在头部)
总共有十个fastbin链表,每个链表中fastbin的size一样,0x10递增
大小属于fastbin的chunk被free掉时,不会改变nextchunk的previnuse位,也就是说不会被合并。
检查
- 被释放的堆块的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
基本结构
- 大小范围:0x90 - 0x400
- 由62个双向链表组成,每个链表中的chunk大小一样,大小以0x10递增,存在fd和bk指针
- 相邻的free chunk会触发合并操作,即合并成一个大的free chunk
- 采用的遍历顺序是FIFO
小技巧
small bin 中存在两个块时,第一个块的fd指针指向main_arena,bk指针指向了下一个堆块,所以可以泄露出libc以及堆地址
large bin
基本结构
- 大小范围: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_nextsize 和 bk_nextsize 都会指向堆块地址,可以泄露出堆地址
如果largenbin上仅有一个堆块,那该堆块的fd_nextsize和bk_nextsize指向自身
malloc过程
计算真正堆块大小(加上头部长度、对齐)
是否在fastbin范围内?
- 是,检查对应的bin链表中有没有chunk
- 有,分配给用户,结束
- 是,检查对应的bin链表中有没有chunk
如果不在fastbin范围内,或者没有chunk可用
是否在smallbin范围内?
- 是,检查对应大小的bin链表中有没有chunk
- 有,分配给用户,结束
- 是,检查对应大小的bin链表中有没有chunk
如果不在smallbin范围内,或者smallbin里面也没有
unsortedbin中有没有chunk?
- 有,从尾部取出第一个chunk,看看大小是否满足需求
- 满足,切分后大小是否大于minsize?(64位下minisize为0x20)
- 大于,切分块,返回给用户,剩下的块放进unsortedbin
- 小于或等于minsize,直接全部分配给用户,结束
- 不满足,把这个块放入small/largebin对应的链表中,继续遍历下一个块
- 满足,切分后大小是否大于minsize?(64位下minisize为0x20)
- 有,从尾部取出第一个chunk,看看大小是否满足需求
如果unsortedbin中所有的块也不能满足需求
大小是否在largebin范围?
- 是,检查对应的bin链表中有没有符合的chunk
- 有,找到满足需求最小的chunk,切分块返回,剩下的放进unsortedbin中
- 是,检查对应的bin链表中有没有符合的chunk
largebin也不行?再次遍历small/large寻找最合适的chunk
还是没有,那就从topchunk中切割
topchunk也不够?mmap系统调用
- 本文作者:ShouCheng
- 本文链接:http://shoucheng3.github.io/2021/07/16/2021-07-23-bin%E9%93%BE%E6%83%85%E5%86%B5%E5%90%88%E9%9B%86/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!