费脑子的rop
前言
我还是太菜了,百度,wiki加学长指导还花了好几个小时才做出来easy_rop。。恶补了一波知识点。等我什么时候可以一个人不依靠其他做出来pwn才算入门呢。。。
Step 0x01
一拿到这个题啊,名字是easy_rop,就是一道简单的rop链(我呸),有了基本思路就直接先checksec一下。
是64位程序就丢到IDA64里,开了NA,其他保护没开。
Step 0x02
第一个read函数读取了0x58个字符到name指向的内存就是bss段内存,然后可以看到bss段分配了非常大的内存空间,我们完全可以在这里建立rop链。
同时看到main函数中的提示是系统调用函数,调用execve函数执行/bin/sh。而execve函数的系统调用号是59,就要让$rax的值变为0x3b即可。同时在搜索pop|ret |rax命令并没有找的的情况下,我们利用rax保存函数的返回值这个知识点,利用read函数的返回值将rax的值变为0x3b即可。
Step 0x03
那接下来我们就要考虑execve函数的几个参数的值,第一个参数是rdi,第二个是rsi第三个是rdx。我们要使execve(‘/bin/sh’,NULL,NULL)即可。
之后我们就在第一次输入时构造rop。因为bss段完全可以放下rop链所以我们直接使用通用rop。
脚本如下
1 | from pwn import* |
Step 0x04
rop好了以后就要考虑如何让程序执行我们写在bss上的rop链。这里要用到花式栈溢出里的劫持栈指针。可以参考CTFwiki里的相关内容。这里我们劫持栈指针rsp直接指向bss这里执行我们的命令。
我们在0x400815处有leave retn命令,就直接拿来用。先把rop链的起始地址压到栈里成为rbp的值,在用leave retn指令将rbp的值给到rsp栈指针,这样程序就会从bss处开始执行我们写入的指令。脚本如下
1 | p.recvuntil('about it?\n') |
Step 0x05
这样完整的脚本就写出来了。
1 | from pwn import* |
之后就可以得到shell获取flag啦啦啦。
全文结束,希望有看到的大佬能指点我的错误。太难了太难了,我啥也不会。