借助hitcon training的题目对三种堆的利用方法进行了一个系统的学习,刚入坑的堆小白们可以一起学习一下。题目链接:https://github.com/scwuaptx/HITCON-Training
mkdir + name
touch + name
echo 'context' > name
cat name这是一个典型的use after free很适合初次接触的人进行练习
可以发现是一个note,这里有三个功能

可以发现add的功能是添加字条,第一个段是8字节然后用来储存函数指针 第二段是用来储存我们的输入的

这里可以发现del是一个删除操作,但是并没有让指针置0所以存在use after free漏洞

是一个调用函数指针的一个过程
解题思路
chunk1,chunk2其中大小随意不要超过fastbin的范围就可以了free chunk1free chunk2fastbin中的分布是chunk2(8) -> chunk1(8)chunk2(32) -> chunk1(32)chunk3大小为8
这个时候系统先分配chunk1(8)的大小存放puts函数
然后分配chunk2(8)作为我们的context这个时候我们可以在这里写上magic函数执行获取flag
简单的说use after free就是利用free之后指针没有被设置成NULL然后我们可以在此malloc出来使用。
第三个参数为unsigned符号,当-1时及0xffffffff
任意大小读
top chunk的size域malloc分配的大小这里利用house of force进行利用,题目的下方会对house of force进行一个原理讲解

0x10的空间给hello message和goodbye_message函数
这里可以看见这里总共有5个选项其中选项1就是show item,remove就是正常的删除操作,5是正常的退出操作。接下来我们仔细看2,3两个选项

mallocitem值就可以了
修改物品的名字,根据给定的索引,以及大小,向指定索引的物品中读取指定长度名字。这里长度由用户来读入,也存在任意长度堆溢出的漏洞。

这里有一个我们的flag文件可以让我们利用
malloc一个块change the item in the box进行长度的修改使得我们可以覆盖到top chunk的size位置修改top chunk size=-1(因为在其中size是无符号整数-1会被解释为0xffffff)所以size肯定就够我们用了house of force的方法将top chunk的位置放在heap base地址0x10的块,去修改函数指针为我们Magic的地址
整个利用这样就完成
这里利用house of force
top chunk的大小malloc将top chunk放置到我们需要改写的那个地址上,可以是got表的地址可以是分配的堆块地址。故名思义,就是对一个堆块进行了两次free, 但是free了同一个堆块两次,其中在glibc中对此有一个检查

其中是检查main_arean是否指向向了原来的一个chunk,这个就是非常容易绕过的只需要free(p1);free(p2);free(p1)就可以绕过了。

这是我们执行doublefree之后的图,此时malloc出chunk1,更改chunk1的fd,又因为此时chunk1是在fastbin list,也就是结构变成了下图

可以看见现在fastbin list中会多指向一个我们的fakebin(此时就可以进行任意地址写了)
if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
{
errstr = "malloc(): memory corruption (fast)";
errout:
malloc_printerr (check_action, errstr, chunk2mem (victim));
return NULL;
}其中会有一个对fakebin,size大小的检查,如果不满足当前fastbin链中应该有的大小则会显示异常。

堆题一般都是些菜单题,这又是一道菜单题

add函数就是正常的malloc出堆块,然后输入一些数据,这里并没什么漏洞

visit函数就是遍历刚才我们所有建立的东西

一个删除函数,其中对指针进行了置0所以无法使用use after free,但是这里似乎可以利用double free

把所有已经创建了的都进行一个了删除

这是一个get_flag的函数
利用的思路还是比较明显的,利用double free进行一个got表的改写。首先add函数建立2个堆块,然后free(chunk1)->free(chunk2)->free(chunk1)进行一个检查的bypass。然后再执行add函数,进行chunk1堆块的fd指针改写,然后连续free出chunk2,chunk1和我们构造的fake_chunk(这个chunk的地址在got表上),对got表进行一个覆写,将puts函数``got表改写成magic函数的地址。
因为要bypass对fakebin_size的检查,所以在选got表地址的时候需要gdb调试一下,看存储的数的低四位满足要求,这里就选用了0x601ffa,刚好可以满足条件

从这些3个利用方式来看,堆的学习主要是建立在对源码和对堆分配,回收等操作的熟悉的基础上。这里推荐用pwndbg进行调试,还有一些大佬会用gef和peda以及一些插件的方法进行调试,具体看个人的习惯了。