【BUUCTF】roarctf_2019_realloc_magic---从一道题认识realloc函数+stdout泄露libc地址实战

realloc好题
摘要由CSDN通过智能技术生成


慢慢的接触到了FILE io的实战题目,很难想象这是2019年题目的水平,看来还是欠缺的太多了。
此外,realloc函数这里也是第一次碰到,之前一直都是用realloc_hook,今天也终于对realloc这个函数下手了!!!

一、题目分析

题目环境是BUUCTF的ubuntu18,利用的是2.27-3ubuntu1_amd64的libc版本,这个版本注意到tcache还是存在double free的漏洞的,
至于函数功能真的是非常简单的

  • 1.realloc功能
    在这里插入图片描述

  • 2.free功能
    在这里插入图片描述

  • 3.隐藏的666功能
    在这里插入图片描述

这么简单功能?到滴该咋办,第一时间看到的时候我整个人都懵逼了。

二、前置知识

如果想靠自己的本事做出来,至少要掌握下面两个基础知识:

(一)关于realloc函数

realloc函数功能比malloc更加复杂,与malloc也有一定的区分。

  • ①当ptr == nullptr的时候,相当于malloc(size), 返回分配到的地址
  • ②当ptr != nullptr && size == 0的时候,相当于free(ptr),返回空指针
  • ③当size小于原来ptr所指向的内存的大小时,直接缩小,返回ptr指针。被削减的那块内存会被释放,放入对应的bins中去
  • ④当size大于原来ptr所指向的内存的大小时,如果原ptr所指向的chunk后面又足够的空间,那么直接在后面扩容,返回ptr指针;如果后面空间不足,先释放ptr所申请的内存,然后试图分配size大小的内存,返回分配后的指针

(二)关于如何利用stdout泄露libc的方法

网上有很多优秀的博文,我在这里推荐hollk大神的博客,写的特别nice
好好说话之IO_FILE利用(1):利用_IO_2_1_stdout泄露libc

三、解题思路

(一)抛出解题的核心问题

这个题目有两个最核心的问题:

  • 第一,如何泄露libc的问题,如果不泄露libc,这么简单的程序时不可能达成利用的
  • 第二,如何实现攻击,无论是泄露libc还是实现攻击,都需要一种思路,这个一定和realloc的特性是密不可分的。

(二)解题思路

如果在已知libc地址的前提下,攻击方法我们还是希望攻击hook这种传统的方式,并且因为tcache double free可行,tcache dup就更容易利用了,其中就是需要我们仔细理解、设计realloc的用法。我们设(学习)计(大佬)的解题思路如下:

  • 第一步,通过realloc和free的组合,具备实现tcache dup的攻击条件
  • 第二步,利用main_arena与stdout相近的情况,爆破第二个低字节,利用利用_IO_2_1_stdout泄露libc
  • 第三步,用第一步相同的方法指向free_hook,最终getshell

(三)最终解题详细过程

想法很美妙,但是如果不看大神的wp,能够想出来一定还是很有挑战的!!!
第一步:构建tcache dup的条件,并且将地址指向_IO_2_1_stdout,事实就是这个构造就让我头秃欲裂
这里面细节太多了,建议一步一步看,结合代码注释看。
这里构造必须巧妙地运用realloc的特性:①当ptr != nullptr && size == 0的时候返回空指针;②当ptr == nullptr的时候,相当于malloc(size)两条性质。

  • 1.我们先看一下tcache dup应该如何布置空间
    realloc(0x30,"a")   # 块A 这一步很关键,是为了tcache dup篡改B的fd预留位置
    realloc(0,"")       # 这一步是关键,利用了性质①

    realloc(0x80,"b")   # 块B ,在上述步骤后realloc_ptr被置空,又可以利用②构造下一个位置的chunk,而不是在A的基础上扩展
    realloc(0,"")       # 同上

    realloc(0x40,"c")   # 块C ,纯粹的隔离作用,防止被top chunk 合并
    realloc(0,"")

    realloc(0x80,"b")   # 重新申请回B块
    [free() for x in range(7)]      # 利用tcache double free填满tcache chain
    realloc(0,"")       # 这一步有三层含义,非常关键
                        # 第一,清空realloc_ptr,为tcache dup必须的更改realloc_ptr创造条件
                        # 第二,将0x90大小的堆第8次释放,变成unsorted bin,这一步为realloc(A,size(A)+N)成功打下基础
                        # 第三,unsorted bin 会使得fd 变成main_arena + 96,这给我们篡改至_IO_2_1_stdout奠定了基础
    

布置完毕后堆空间是这样的
在这里插入图片描述
在这里插入图片描述

  • 2.利用tcache dup需要两次malloc如何实现?如何篡改main_arena指向_IO_2_1_stdout?
    realloc(0x30,"a")   # 将realloc_ptr指向Chunk A

    #break_here()       # 注释代码用于在测试时候用,保证tcache顺利指向
    #offset = int(input("please input offset : "))
    #offset = (offset<<4)+
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值