前言
坑比的我比赛的时候没有做。。第二天有课,赛后看了看,题目其实没啥太多难度,可能也就是细节上需要注意一下吧
题目
题目功能
简单介绍一下题目功能,因为我本机是用的linux,ida在虚拟机里,ida的复制又不是特别方便,所以我就不复制分析的情况了,具体分析自己做一下练习一下也比较好,就把大致的情况说明一下。
首先是主菜单
===== Baby Heap in 2017 =====
1. Allocate
2. Fill
3. Free
4. Dump
5. Exit
Command:
5个选项,alloc:
1. Allocate
2. Fill
3. Free
4. Dump
5. Exit
Command: 1
Size: 5
Allocate Index 0
分配一个空间,大小可以自己指定,实际情况是最大4096字节,并且使用了calloc,所以分配之后的chunk会被先清空
分配之后会给出index,用于其他选项
1. Allocate
2. Fill
3. Free
4. Dump
5. Exit
Command: 2
Index: 0
Size: 5
Content: abcd
fill,给出index和size,可以将content写入分配的空间,注意这里没有检验size大小,所以存在堆溢出
free和dump基本上也类似,就是给出index,会进行free操作或者进行将内容打印出来的操作。
漏洞位置
在fill的地方存在一个堆溢出,可以写任意长度,因为分配使用的calloc,所以在分配的时候会将分配出来的chunk先清空,dump的大小是根据alloc指定的size决定的,跟真正的chunk大小无关。
分析
首先检查保护:
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
ASLR默认开启就行了。
PIE和Full RELRO保证了不能通过更改GOT表劫持控制流,加之使用了堆,多半都是用__malloc_hook
和__free_hook
这样的东西。
所以问题就在于:
- 如何leak出libc地址
- 如何劫持控制流
leak libc 地址
其实这个还是挺好想的,已经是很常用的手法了,那就是利用small bin或者large bin在为空的时候fd和bk指向libc的地址,
然后通过这个地址就可以拿到libc基地址了,那么问题就变成了如何拿到fd和bk的地址。
由于堆溢出的存在,这个问题其实挺好解决的,堆溢出可以更改size,那么就可以造成chunk overlap,之后利用dump将包含的chunk打出来就可以拿到fd和bk了。
给出我的一个流程:
分配0x60,chunk 0
+---------+
| chunk0 |
| 0x60 |
+---------+
分配0x40,chunk 1
+---------+-----------+-----