BUU babyheap_0ctf_2017
IDA伪代码分析
首先检查一下文件

拖入IDA查看

mmap了一段内存保存数据,跟做题没啥关系

典型的菜单

接收一个输入


Allocate的逻辑就是接收一个类似上图的结构,第一个1是判断是否已分配。这里讲一下calloc和malloc的区别,calloc不同于malloc,它会将分配的内存区域进行清零操作,这一点EXP里要注意,还有就是calloc就是malloc的一个封装,底层还是调用的malloc,这就对后面向__malloc_hook中打入one_gadget铺垫了基础。

接收一个指定大小size的内容,存在堆溢出

free堆块,最后让指针等于0了,这就没有UAF了,可以从double free的思路入手。

打印函数,可以将堆块的内容打印出来
做题思路
可以利用double free,首先申请四个chunk
1 | |

free(1)将chunk1 free掉,然后通过堆溢出,修改chunk0的内容,将chunk1的size大小改成chunk1加chunk2的大小,0x121是由chunk1大小0x80和chunk2大小0x80,加上两个chunk的chunk头大小各0x10共0x20,加上prev_inuse位0x1,总共0x121,然后alloc(0x110)重新将chunk1分配回来,这样chunk1和chunk2就有重叠部分了,又因为calloc清零操作,需要通过堆溢出将chunk2的size大小改回去,然后将chunk2free掉,因为chunk2大小为0x80,free之后会进入unsorted bin,此时free chunk2的fd和bk指针指向main_arean+88的位置,然后通过dump(1)将chunk1打印,因为free chunk2也在chunk1的范围,这样就可以通过free chunk2的fd指针泄露出main_arean+88的地址
1 | |


为什么是main_aren+88,这是固定,我们可以通过调试看看

此时main_arean+88为0x7f8a25985b78,那么main_arean的地址就减去88为0x7f8a25985b20,那我们看看main_arean-0x10是什么东西

发现是__malloc_hook的地址泄露出来了(这好像是固定main_arean-0x10的),这样我们就可以往里面打入one_gadget
1 | |
之后的思路就是通过fastbin_attack,申请两个fastbin大小的chunk,不过首先要将chunk2申请回去,然后将chunk5 free掉,此时chunk5进入fast bin中,通过堆溢出,修改chunk4的内容,将chunk5的size大小改成0x71,反正在fastbin大小范围内就可以,然后将chunk5的fd指针改为__malloc_hook-0x23,为什么是__malloc_hook-0x23,我们等等通过调试看。
1 | |

这里我们可以看到__malloc_hook-0x23有一个0x7f,是不是很熟悉,像不像chunk的结构中的size的大小,那0x7f是在fastbin的大小范围内,所以上面我们要构造fastbin大小范围内的chunk,那这样__malloc_hook-0x23就是一个伪造的fake free chunk,此时free chunk5指向了这个fake free chunk,那我们重新申请回chunk5,再申请一个chunk6,通过修改chunk6的内容,将__malloc_hook的内容改成one_gadget的地址,最后再随便申请一个堆块,这样就会调用malloc,从而触发one_gadget
1 | |
这里提一下libc是在BUU的资源里下载的,这题是Ubuntu16 64位的

EXP
最后贴一下EXP
1 | |