2017/2018-0ctf-babyheap-writeup

因为最近2019届0ctf-tctf开始了,想去水一水,特别把2018的babyheap和2017的babyheap做了一下汲取一下经验,感觉两题类型相似,大致思路相同,2018比2017的利用条件更加苛刻一些。所以把两个题目放在一起来写,有助于加深对fastbin_attack的理解,和提高知识运用的灵活性。

首先提供两道题目的二进制文件:2017_0ctf_babyheap 2018_0ctf_babyheap

先来看2017的题目:

预览:

可以看到文件为64位,保护全开,给了Libc,标准的堆题。。。看到full relro一般为改hook为one_gadget。放进ida里进一步分析:

主要功能分析及漏洞寻找:

可以看到程序开始时先选了一段随机不可控的地址来储存heap列表的基地址(base_ptr)。紧接着就进入了死循环,打印菜单,输入选项,运行函数。逐个分析功能:

allocate()功能中,我们发现heap的content大小由我们自己决定(小于0x1000),是可控的,且heap结构体中会储存heap内容的大小。此外,我们申请堆块时用的是 calloc() 这意味着堆块的数据开始时要被初始化为0,这一点需要注意

fill()函数就是向我们申请过的chunk里填数据,不过有一个很明显的任意溢出更改漏洞。

free()就是将chunk指针free(),没有uaf漏洞。

print()函数就是打印对应下标的chunk的content,不过打印的内容是根据我们在allocate()时输入的size来决定的。

思考如何利用漏洞:

首先我们的最终目标定为:将malloc_hook改为one_gadget,现阶段,我们只能借助于程序自身的fill()功能来进行写,而fill()功能又需要一个堆指针,所以我们的目标转化为如何使堆指针分配到malloc_hook附近,我们运用fastbin功能与overlapping结合的方法来实现。

leak:

因为我们要确定malloc_hook的地址与one_gadget的地址,所以必须泄露出libc。

  1. 泄露功能,我们可以利用程序的print()功能来实现,先申请4个chunk(chunk2大小为smallchunk),然后通过0来改写1的size,然后通过标准的overlapping方法,先free()再malloc(),然后chunk2现在在1的里面,(这里要注意,因为是calloc,所以再次申请chunk1的时候,chunk2的chunk_header会被清零,需要fill()重新布置一下),然后free chunk2,将其放入unsortedbin中,然后通过chunk1的print()打印出chunk2的fd指针,成功泄露libc。(这一部分不理解的可以看我文末的心得,有我第一次做的时候查的资料,帮助理解。)

change:

之后我们就可以先把chunk2(大小我们申请为0x60)放进fastbin里,然后通过chunk1改其fd指针为&main_arena-0x33,然后在申请两次即可,然后再通过改chunk4的内容来改malloc_hook,再申请则会触发one_gadget。

exp如下:

#coding:utf-8

from pwn import *
context(os='linux',arch='amd64')
#context.log_level='debug'
p=process('./babyheap')
libc=ELF('./libc.so.6')

def allocate(length):
	p.recvuntil('Command: ')
	p.sendline('1')
	p.recvuntil(': ')
	p.sendline(str(length))

def fill(ID,length,payload):
	p.recvuntil('Command: ')
	p.sendline('2')
	p.recvuntil('Index: ')
	p.sendline(str(ID))
	p.recvuntil('Size: ')
	p.sendline(str(length))
	p.recvuntil('Content: ')
	p.send(payload)

def free(ID):
	p.recvuntil('Command: ')
	p.sendline('3')
	p.recvuntil('Index: ')
	p.sendline(str(ID))

def dump(ID):
	p.recvuntil('Command: ')
	p.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值