堆溢出-Unsorted Bin Attack
被利用的前提是控制 Unsorted Bin Chunk 的 bk 指针,可以达到的效果是实现修改任意地址值为一个较大的数值。
原理
Unsorted Bin 的产生
- 当一个较大的 chunk 被分割成两半后,如果剩下的部分大于 MINSIZE,就会被放到 unsorted bin 中。
- 释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻时,该 chunk 会被首先放到 unsorted bin 中。
- 当进行 malloc_consolidate 时,如果不是和 top chunk 近邻的话,可能会把合并后的 chunk 放到 unsorted bin 中。
Unsorted Bin 的使用
- Unsorted Bin 在使用的过程中,采用的遍历顺序是 FIFO,即插入的时候插入到 unsorted bin 的头部,取出的时候从链表尾获取。
- 在程序 malloc 时,如果在 fastbin,small bin 中找不到对应大小的 chunk,就会尝试从 Unsorted Bin 中寻找 chunk。如果取出来的 chunk 大小刚好满足,就会直接返回给用户,否则就会把这些 chunk 分别插入到对应的 bin 中。
_int_malloc
中,当将一个 unsorted bin 取出的时候,会将 bk->fd
的位置写入本 Unsorted Bin 的位置,如果我们控制了 bk 的值,我们就能将 unsorted_chunks (av)
写到任意地址。
c
/* remove from unsorted list */ |
初始状态时
unsorted bin 的 fd 和 bk 均指向 unsorted bin 本身。
执行 free(p)
由于释放的 chunk 大小不属于 fast bin 范围内,所以会首先放入到 unsorted bin 中。
修改 p[1]
经过修改之后,原来在 unsorted bin 中的 p 的 bk 指针就会指向 target addr-16 处伪造的 chunk,即 Target Value 处于伪造 chunk 的 fd 处。
申请 400 大小的 chunk
此时,所申请的 chunk 处于 small bin 所在的范围,其对应的 bin 中暂时没有 chunk,所以会去 unsorted bin 中找,发现 unsorted bin 不空,于是把 unsorted bin 中的最后一个 chunk 拿出来。
c
victim = unsorted_chunks(av)->bk=p |
在将 unsorted bin 的最后一个 chunk 拿出来的过程中,victim 的 fd 并没有发挥作用,所以即使修改了其为一个不合法的值也没有关系。然而,需要注意的是,unsorted bin 链表可能就此破坏,在插入 chunk 时,可能会出现问题。
作用
- 通过修改循环的次数来使得程序可以执行多次循环。
- 可以修改 heap 中的 global_max_fast 来使得更大的 chunk 可以被视为 fast bin,这样就可以去执行一些 fast bin attack 了。
例 HITCON Training lab14 magic heap
功能
c
puts("--------------------------------"); |
漏洞点
- 创建堆。根据用户指定大小申请相应堆,并且读入指定长度的内容,但是并没有设置 NULL。
- 编辑堆。根据指定的索引判断对应堆是不是非空,如果非空,就根据用户读入的大小,来修改堆的内容,这里出现了任意长度堆溢出的漏洞。
- 删除堆。根据指定的索引判断对应堆是不是非空,如果非空,就将对应堆释放并置为 NULL。
当控制 v3 为 4869,同时控制 magic 大于 4869,就可以得到 flag 。
利用
- 释放一个堆块到 unsorted bin 中。
- 利用堆溢出漏洞修改 unsorted bin 中对应堆块的 bk 指针为 &magic-16。
- 触发漏洞
exp
python
# -*- coding: utf-8 -*- |