ROP实例分析(二)---------------------------DynELF使用

DynELF使用

DynELF是pwntools中专门用来应对没有libc情况的漏洞利用模块,其基本代码框架如下。

需要使用者进行的工作主要集中在leak函数的具体实现上,上面的代码只是个模板。

其中,address就是leak函数要泄漏信息的起始地址,而payload就是触发目标程序泄漏address处信息的攻击代码。


使用条件

不管有没有libc文件,要想获得目标系统的system函数地址,首先都要求目标二进制程序中存在一个能够泄漏目标系统内存中libc空间内信息的漏洞。同时,由于我们是在对方内存中不断搜索地址信息,故我们需要这样的信息泄露漏洞能够被反复调用。以下是大致归纳的主要使用条件:

1)目标程序存在可以泄露libc空间信息的漏洞,如read@got就指向libc地址空间内;

2)目标程序中存在的信息泄露漏洞能够反复触发,从而可以不断泄露libc地址空间内的信息。

当然,以上仅仅是实现利用的基本条件,不同的目标程序和运行环境都会有一些坑需要绕过。

 

通用GADGET:

__libc_csu_init函数是程序调用libc库用来对程序进行初始化的函数,一般先于main函数执行

而我们则是要利用__libc_csu_init中两端特殊的gadget(简单点理解,gadget就是一小段程序代码)

在gdb下查看程序的_libc_csu_init可以发现

Gadget1

0x40089a处的gadget
首先将栈中的数据pop到几个寄存器(顺序依次 rbx rbp r12 r13 r14 r15 )然后返回。
而我们知道, 如果要调用一个函数,那么我们要首先进行传参。

传参规则

在32位汇编下

将参数直接压栈


在64位汇编下

当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9

当参数大于等于7个时,前 6 个与前面一样, 但后面的依次从右向左放入栈中,即和32位汇编一样。


对于上面的gadget1,特别的要设置

rbx=0 ,为了配合gadgt2中call指令,使得call指令跳转到r12

rbp=1 ,为了配合gadgt2中call指令之后的add和cmp指令,使得cmp后转向add rsp,8

r12=target_function/call address,要调用的函数地址。注意是got地址而不是plt地址,因为用的是call指令

r13,r14,r15就是我们要调用的函数的参数,为了配合gadget2,r15中布置arg1,其他以此类推。

 

Gadget2

0x400880处的gadget

首先将 r13 r14 r15 的值和rdx rsi edi交换,进行了参数传递。(上面我们提到了64位参数传递规则,所以r15即arg1被保存到edi中,也即rdi中。其他以此类推)

然后call [ r12+rbx*8 ],因为前面我们设置了rbx为0,所以此处就是call [ r12],就是调用我们想要调用的函数。

再然后将rbx自加1即rbx+1(前面设置rbx为0,故此时为1)和rbp进行比较,前面rbp我们设置为1,所以两者相等,cmp后转向add  rsp,8继续执行。

因此在ret之前,栈顶指针rsp一共移动了56个字节(一次add,六次pop)。所以我们在栈中布置56个字节就可以了。

 

这两段代码普遍存在于x64二进制程序中,只不过是间接地传递参数。

 

可能用到的其他的gadget

pop_rdi_ret = l64(0x4008a3)

#0x4008a3:

pop rdi;

ret


pop_rsi_ret = l64(0x4008a1)

#0x4008a1:

pop rsi;

pop r15;

ret

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值