查看程序保护。
分析程序,程序只有一个main函数。
v6距离rbp为0x70,在输入数字的时候可以输34 * 4个字节的数,34*4-0x70=24,意味着可以溢出覆盖rbp,ret_address,以及返回地址下面的8个字节。main函数的old_rbp值实际上是代码段init的地址,返回地址位置是libc中的一个地址。scanf函数%d当输入为 '+'时不会改变原内存中数据,于是可以来泄露代码段首地址。在输入number之后可以在bss段上输入数据,由于溢出的大小不够所以想到用栈迁移的方式来做。用RopGadget工具发现了一个修改esp的gadget。
在返回地址下面,即能溢出的最后8个字节,填上bss段上的地址,那么ret后在执行这段gadget的pop rsp时,栈顶指针就到了bss段上,只要控制bss段上的数据,就可以继续进行rop,从而getshell,exp如下:
from pwn import *
io=remote('xx.xx.xx.xx',xxxxx)
def a(data):
io.recvuntil(': ')
io.sendline(data)
for i in range(26):
a('0'