1.基本信息收集
查看文件信息
1 | file rop |
查看保护
1 | checksec rop |
IDA反汇编看伪代码
2.漏洞定位及利用思路
ret2syscall
很明显gets()函数存在溢出漏洞,但本题没有找到system(“/bin/sh”)函数,且开启了堆栈不可执行保护,因此ret2text,ret2shellcode都无法使用。
这时我们就可以使用ret2syscall的方法了。
ret2syscall,即控制程序执行系统调用,获取 shell。简单地说,只要我们把对应获取 shell 的系统调用的参数放到对应的寄存器中,那么我们在执行 int 0x80 就可执行对应的系统调用。比如说这里我们利用如下系统调用来获取 shell:
1 | execve("/bin/sh",NULL,NULL) |
其中,该程序是 32 位,所以我们需要使得
- 系统调用号,即 eax 应该为 0xb
- 第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
- 第二个参数,即 ecx 应该为 0
- 第三个参数,即 edx 应该为 0
而我们如何控制这些寄存器的值 呢?这里就需要使用 gadgets。比如说,现在栈顶是 10,那么如果此时执行了 pop eax,那么现在 eax 的值就为 10。但是我们并不能期待有一段连续的代码可以同时控制对应的寄存器,所以我们需要一段一段控制,这也是我们在 gadgets 最后使用 ret 来再次控制程序执行流程的原因。具体寻找 gadgets 的方法,我们可以使用 ropgadgets 这个工具。
寻找gadgets
eax
1 | ROPgadget --binary rop --only "pop|ret" | grep "eax" |
这里我们选择0x080bb196
ebx
1 | ROPgadget --binary rop --only "pop|ret" | grep "ebx" |
这里我们选择0x0806eb90
int 80
1 | ROPgadget --binary rop --only 'int' |
0x08049421
/bin/sh
1 | ROPgadget --binary rop --string '/bin/sh' |
0x080be408
3.利用步骤
1.计算偏移量
1 | gdb-peda$ pattern create 150 |
2.编写exp
1 | from pwn import * |