一种比较麻烦的Rop链构造——ret2dlresolve

本文介绍了ret2dlresolve的原理,分析了0ctf 2018新人赛babystack题目,探讨了在开启NX保护、无法内存泄露和计算libc偏移的情况下,如何利用ret2dlresolve构造exploit。分析了两种不同的exploit实现方式,并解释了exploit中关键步骤的细节。
摘要由CSDN通过智能技术生成

ret2resolve

题目:0ctf 2018 babystack

上周末做了TCTF(0ctf 2018)的新人赛,题目难度适中,但垃圾如我一如既往没有做出几道题。在7o8v大佬的帮助下,弄懂了babystack的考察点和ret2resolve的利用原理,因此对照着wp记录一波。

0x01 ret2dlresolve原理

当一个程序第一次调用libc中的函数时,必须首先对libc中函数的真实地址进行重定位,而这个绑定寻找真实地址的过程由dl_runtime_resolve完成。
dl_runtime_resolve需要两个参数,一个是link_map=*(GOT[1]),即链接器标志信息和reloc_arg(标志该函数重定位入口偏移),我们需要做的就是控制reloc_arg从而使dl_runtime_resolve将函数重定位到我们能控制的地方。

利用方法:

1.控制eip为PLT[0]的地址,只需传递一个index_arg参数
2.控制index_arg的大小,使reloc的位置落在可控地址内
3.伪造reloc的内容,使sym落在可控地址内
4.伪造sym的内容,使name落在可控地址内
5.伪造name为任意库函数,如system

详细内容参照:
7o8v大佬的博客
http://pwn4.fun/2016/11/09/Return-to-dl-resolve/
CTFwiki
这里写一下我在研究的过程中出现的问题:

pwn4fun:

  1. 构造payload的时候为什么会需要 ppp_ret这个gadgets,而7o8v的博客里这个地方写的却是overflow(程序本来溢出点的地址)??
    答:read函数的参数是通过栈传递的(我刚开始以为是寄存器传递所以需要ppp_ret,类似于ret2syscall),所以当read函数执行完时,程序会返回ppp_ret的地址,会将写入栈中的3个参数全都pop出来,此后栈的样子和调用read之前是一样的。而7o8v的博客里这个地方写overflow是直接返回程序本来溢出的地址。所以两个方法的功能是一样的。

  2. payload2的刚开始为什么是“AAAA”
    答:payload2接上一个paylaod的leave->pop ebp ; ret(pop eip),所以“AAAA”将会被作为ebp(我们并不需要关注ebp是什么)被pop出来,而下一项将会被pop到eip中

  3. index_offset = (base_stage + 28) - rel_plt 这里的28是怎么来的?
    答:其实这里不一定非得是28,你可以改成任何的数,但注意最后的fake_reloc在栈上的位置要和这里的一致。

0x02 题目分析

程序打开了NX保护,有明显的栈溢出
这里写图片描述
这里写图片描述

但是这道题的问题在于:

  1. 没有输出,找不到write函数,所以无法进行内存泄露
  2. 没有提供libc,所以不可能计算偏移(ret2libc不可行)
  3. 开启NX保护,所有把shellcode布置到栈中的操作都不可行

这三条限制了绝大多数的rop方法,所以只能使用ret2dlresolve
在本题利用这个漏洞的方法中,我学习了两个exp,一个出自7o8v大佬,一个出自https://kileak.github.io/ctf/2018/0ctf-qual-babystack/
,先将两个exp都做下分析

0x03 exploit

exp1

from pwn 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值