堆块重叠构造总结

两种堆溢出利用方法总结

Posted by X1ng on September 16, 2020

记录一些堆利用思路方便复习(实验环境为glibc-2.27以下)

查笔记时发现之前写的有些问题和遗漏,补了一下

off-by-one

  • 扩大堆块

    1. 申请四个chunk,第四个chunk防止chunk释放后与topchunk合并,并且在其priv_size填充前两个chunk大小的和,用于绕过之后的unlink机制

    2. 溢出,修改chunk1的size的最低位为前两个chunk大小之和

    3. 释放chunk1,由于其size此时被修改成两个chunk大小之和,所以释放时这两个chunk相当于一个chunk被放入unsorted_bin中

    4. 此时再申请相应大小的chunk,能从unsorted_bin中申请到chunk即可构造堆块重叠

off-by-null

  • 利用前一个chunk的向后合并

    1. 先申请4个chunk,第四个chunk防止chunk释放后与topchunk合并

    2. 溢出,把chunk2的prev_inuse位覆盖成0,free的时候会检查是否可以合并,所以这里需要填充chunk2的prev_size位为上面两个chunk的大小

    3. 先释放chunk0到unsorted_bin中,再释放chunk2,则chunk0发生向后合并,产生重叠的堆块

    4. 将chunk1释放到tcache/fastbin中,再从unsorted_bin申请一大块chunk就可以随意修改重叠的chunk了

  • 利用被改chunk

    1. 申请四个chunk,第四个chunk防止chunk释放后与topchunk合并

      在chunk1的0x100偏移处填充0x100,伪造下一个chunk的priv_size,用于绕过之后的unlink检查

    2. 先释放chunk1,放入unsorted_bin中,然后溢出,覆盖chunk1的prev_inuse位为0,因为malloc的时候不会检查是否需要合并,所以chunk1的priv_size没有要求

      此时chunk1的大小已经被当成成了0x100,下面还有一段内存不被算在chunk1内

    3. 申请两次,将unsorted_bin中的内存分为两个chunk

      此时chunk1和chunk4的prev_size的0x90和0x70已经没有意义了,但是下面chunk2的prev_size还是0x170

    4. 然后先后释放chunk1和chunk2,释放chunk2时由于chunk0的向后合并,两个chunk就会合并到unsorted_bin中

    5. 将chunk4释放到tcache/fastbin中,再从unsorted_bin申请一大块chunk就可以随意修改重叠的chunk了