Heap-DoubleFree之Mulnote
Double_free 利用原理
在free chunk时,程序将会以单向链表的形式存到fastbin
中(也就是fd指针链接下一个bins),当我们连续free一块chunk两次时,他的两个fd指针将会同时指向一个chunk,此时当我们再次使用malloc申请chunk时,根据fastbin中的fd指针的指引,便会获取到上一次free掉的堆块。而由于main_arena检查机制的原因,我们不能连续free掉一块chunk,但是可以是如下形式:
Free A
-> Free B
-> Free A
这样的话fd的指针将还是指向A这块chunk。
之后的话由于在fastbin中的chunk将会在该chunk数据区的0x10空间的位置上存放fd和bk指针,所以我们可以在连续free两次同一块chunk后,再次申请该地址在数据区的开头存放一个伪造的fd指针。此时还在fastbin中的B堆块的fd指针将会因为链表的原因而指向我们伪造的fd指针,最后在连续申请两次同样大小的chunk后,再次申请的地址将是我们伪造的fd指针内的地址,以此达成任意地址写的目的。
但是需要注意一点是:
假如我们要伪造一个chunk,使用任意地址写来将onegadget写到malloc_hook上时,由于malloc对chunk的检查机制如果不加以控制会导致程序异常直接退出,这时则可以通过覆盖掉main_arena-88-0x33
->_IO_wide_data_0
到main_arena-88-0x10
->malloc_hook
之间的空间,使ong_gadget直接落在malloc_hook
上。这样当我们再次使用malloc申请chunk时,便能触发malloc_hook上的one_gadget而不会导致程序异常退出了。
任意地址读
当我们伪造一个fd指针为某个函数的got表地址后,再次malloc申请一个空间就是落在该got表地址上,此时再用程序中应有的打印功能查看接受即可(或者可能要再-0x10才能接收到该地址,因为打印出的内容应该会从chunk中的用户数据区开始读的)、
利用条件
- 堆块被free后,next_chunk的pre_inuse位不会被清空
- 堆块的大小符合free掉后fastbins的大小
疑难解答
在第一次malloc填上fd指针后为什么还要再malloc两次之后再次的malloc才能分配到fd指针上的地址
在第一次malloc之后fastbin的指针指向b_chunk,第二次malloc后fd指向a_chunk,第三次后则是a_chunk中的fd指向的也就是我们伪造的chunk,所以再第四次malloc后我们获得的堆块地址就是我们指定的地址了(具体可以使用gdb一步步查看fastbin中指向的地址)
_IO_wide_data_0 的作用,为什么在该地址的指定位置上填充上one_gadget再次malloc后就能拿到shell
可以将_IO_wide_data_0看作是对chunk的一个检查,而_IO_wide_data_0 则距离malloc_hook一般是0x13的距离,所以在这段地址中随便填入数据覆盖掉,之后跟上one_gadget,最后当我们再次malloc时,便会出发这个mallo_hook
Unsorted_bin利用
当free掉的chunk超过0x80
大小时,将被放在unsortedbin
中,而如果只有一个bin的话,此时的fd和bk指针将指向main_arena+88的位置。也就是说此时如果在申请一个堆块的话,将会被分配至
而利用这个main_arena
的地址,我们可以泄露libc基地址,可以计算出malloc_hook
、_IO_wide_data_0
等地址。
如:
main_arena-88
=main_arena
地址
main_arena-88-0x10
=malloc_hook
地址d
main_arena-88-0x10-0x13
=_IO_wide_data_0
地址x
利用条件
- 要free的chunk必须要大于
0x80
- 用户输入的数据没有
\x00
进行截断
实例: Mul_note
题目分析
checksec后可以看到只有栈保护未开启。也就是说我们无法直接劫持got表
使用IDA打开分析反汇编代码,代码虽然加了混淆,不过在start_routine
过程中还是可以看到他是在free后10秒后财经性的指针清零,也就是出现了doublefree
的漏洞。
而在malloc时申请的大小则又不能超过0x10000
,也就是说我们无法再利用mmap申请大内存来获取libc地址
EXP思路
虽然无法利用mmap申请大内存来获取libc,不过可以使用
unsorted bins
来泄露main_arena
的地址从而泄露libc泄露libc后通过计算得出
malloc_hook
、_IO_wide_data_0
、one_gadget
等地址利用Double free来伪造chunk,劫持malloc_hook,再在malloc_hook上写上one_gadget地址,再次malloc时直接拿到shell
EXP
1 | #coding:utf-8 |
学习参考
https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/fastbin_attack-zh/