一种基于smallbin的任意写的攻击手法 不过要求非常高 需要先修改ptr_addr处 以此来绕过检查 所以我感觉是非常鸡肋的一种手法 不过还是记录一下
源码分析
if (in_smallbin_range (nb)) |
这段源码调用是在申请smallbin中的free chunk时
idx = smallbin_index (nb); |
这两句的作用在于获取smallbin的指针 idx的值为5 bin_at函数依据idx来搜寻对应的chunk
last (bin)实际上是一个宏定义
如果其与bin本身相等 则无法进入判断 wiki上的解释是说明此时链表为空 但是我测试如果利用malloc_consolidate来把fastbin放入smallbin 貌似也过不了判断
过了if后 还会进行一次判断 此时是判断small bin有没有进行初始化 如果初始化了就进入第二个分支
__glibc_unlikely (bck->fd != victim) |
如果绕过这个判断就是实现本次攻击手法的关键
对于bck->fd指向的地址做了检测 而bck是通过这条赋值的
bck = victim->bk; |
也就是说我们要构造成下面这样
之所以还要一个fake chunk2 是因为 如果只有fake chunk1 那么我们通过的是将attack_chunk从smallbin中申请出来的那次判断 此时plmalloc误判把fake chunk接到了 smallbin的倒数第二个 下次再次申请合适大小的chunk 就会申请到fake chunk
而要把fake chunk申请出来的话 就得再进行一次判断 也就用到了fake chunk2 不过这一点倒不是很需要担心 这需要对fake chunk的地址延申几个字长出来 用来充当fake chunk2就可以了
实际利用
演示程序: 由我自己编写 包含UAF 堆溢出等漏洞
演示环境: ubuntu20 替换libc为libc2.23
fake_chunk1 = elf.bss(0x500) |
首先需要泄露堆地址 以便我们进行fake chunk的构造
随后进行fakechunk1和fakechunk2的构造 为了省事我程序自带了一个任意写的函数 具体题目的话 需要自己根据情况来构造
payload = p64(0)+p64(fake_chunk1) |
随后就是申请两个和smallbin chunk同样大小的chunk 第二个就会申请到fake chunk1的位置
add(0x100)#4 |
同时你可以注意到 fake chunk1和fake chunk2其实就隔一点字长就行 我上面还给空了0x100字节 其实就利用同一次任意写输入即可
总结
我是对这个办法不太报希望 因为利用难度比较高 需要前提就具备一个已知地址任意写的漏洞 少数题目可能会提供 或者需要跟其他链配合利用 属于是单个存在没有什么用的链吧 我感觉 以后可能会打脸