CTF pwn题堆入门 -- Unsorted bin

CTF pwn题堆入门 – Tcache bin
CTF pwn题堆入门 – Fast bin
CTF pwn题堆入门 – Large bin

序言

  无奈于pwn题中与堆相关的东西实在是比较多,加上到了2021年的现在,ctf比赛中一来就是堆题,还都是新版本libc,对我这种新手中的新手实在不太友好,以此写下这个系列文章,记录自己学习堆漏洞利用过程中的点滴,同时也是个总结吧。结合自己做题的理解,将堆攻击常见的手段和方式按照一定的规律记录下来。
  本文章系列将分成五大块,即tcache bin --> fast bin --> unsorted bin --> small bin --> large bin。

概述

  Unsorted bin也是堆题中常见的,当一个堆块被释放时,且该堆块大小不属于fast bin(libc-2.26之后要填满tcache),那么在进入small bin和large bin之前,都是先加入到unsorted bin的。之后当我们需要再次分配内存时,如果tcache bin和fastbin上都找不到合适的匹配就会到unsorted bin上寻找,如果申请的内存堆块小于寻找的unsorted bin,那么会将该内存块切割后返回给用户,剩下的仍然保存在unsorted bin上;如果申请的内存堆块大于unsorted bin上存放的,那么会从Top chunk上重新分割,此时就会把unsorted bin上的堆块按照大小放回small bin和large bin中。
  所以这里我们可以将unsorted bin看成一个缓存机制,这样可以加快内存的分配。除此之外,unsorted bin采用的也是双链表结构,先进先出策略,同时需要注意的是unsorted bin只有一条链,该链上会存放不同的堆块大小。

攻击方式

  这里记录一下我做题常见的利用unsorted bin的方式。

unlink

  接下来介绍的方法就是堆中的unlink,该机制的存在就是为了防止内存过度碎片化。当一个chunk被释放时,该chunk非fast bin,当然也不能是tcache,此时libc会检查堆块前后是否有chunk处于被释放的状态。如果存在,那么前后的堆块将会被bins中取出并进行合并,即使相邻的堆块是在fast bin或者tcache中。上述的过程就是unlink,按理说和unsorted bin没啥关系,这是系统内存整理的一种机制。不过要知道unlink之后的堆块也是放在unsorted bin中,所以将这种方法归纳在这里,具体攻击方式见下面阐述。
  其实unlink方法并不能将堆分配到目标地址上,它能实现的效果是将目标地址的值修改为自身地址减去0x18(64位),这样通过在目标地址时写入值的时候加上0x18的padding就可以对该内存地址的数据进行修改,所以和分配堆块到这里的目的一样。实现unlink攻击不算复杂,但要追究其具体原理的话得看源码或者参见ctf-wiki,这里我直接展示攻击方式和效果,当大家熟悉整个过程后再看源码,想必印象更加深刻。具体操作如下代码所示:假设要分配得目标地址为ptr,该地址必须对应要修改的chunk(见代码中的ptr = malloc(0x20));然后修改伪装chunk的size大小以及其fd和bk指针,即fd = &ptr-0x18, bk=&ptr-0x10;最后修改要释放chunk的prev_size和prev_inuse。

#include <stdio.h>
#include <stdlib.h>

long long *ptr;

int main()
{
   
    long long *ptr = malloc(0x20);  // 这里非常重要,并非任意给定的地址
    long long *vic = malloc(0x80);
    malloc(0x1);   // 防止堆块合并,同时prev_inuse也会被检查

    printf("target addr is %p, value is %p\n", &ptr, ptr);
    ptr[0] = 0;
    ptr[1] = 0x21;   // 设置size
    ptr[2] = (long long)&ptr-0x18;  // fd
    ptr[3] = (long long)&ptr-0x10;  // bk
    vic<
  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值