堆入门5.2—Unsortedbin Attack

概念

利用 Unsortedbin 的机制向目的地址写入一个较大的数值(一个指针)。

利用的前提是控制 Unsortedbin Chunk 的 bk 指针,这就意味着需要向 free chunk 写入内容,由于有局限性,通常配合其它漏洞使用。

引用CTFwiki:
unsorted chunk 基本来源 ¶

  • 当一个较大的 chunk 被分割成两半后,如果剩下的部分大于 MINSIZE,就会被放到 unsorted bin 中。
  • 释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻时,该 chunk 会被首先放到 unsorted bin 中。关于 top chunk 的解释,请参考下面的介绍。
  • 当进行 malloc_consolidate 时,可能会把合并后的 chunk 放到 unsorted bin 中,如果不是和 top chunk 近邻的话。

main_arena

  • main_arena 是一个 struct malloc_state 类型的全局变量,是 ptmalloc 管理主分配区的唯一实例。

  • 把正确的 fd 指针 leak 出来,就可以获得一个与 main_arena 有固定偏移的地址

  • 说到全局变量,立马可以想到他会被分配在 .data 或者 .bss 等段上,那么如果我们有进程所使用的 libc 的 .so 文件的话,我们就可以获得 main_arena 与 libc 基地址的偏移,实现对 ASLR 的绕过。

理解

举个例子:

libc版本:libc-2.23.so

#include <stdio.h>
#include <stdlib.h>
int main(){
        char *chunk1;
        char *chunk2;
        char *chunk3;
        char *chunk4;

        chunk1=malloc(0x100);
        chunk2=malloc(0x10);#防止合并
        chunk3=malloc(0x90);
        chunk4=malloc(0x10);#防止 free 后与 topchunk 合并

        sleep(1);#仅用于方便下断点
        free(chunk1);
        free(chunk3);
        sleep(1);
        malloc(0x100);#将 chunk1 申请回来
        sleep(1);
}

第一个 sleep(1) 处:
file

第二个 sleep(1) 处:
file
可以看到:
unsorted_chunk1_fd -> main_arena
unsorted_chunk1_bk -> unsorted_chunk3 #chunk1 在 chunk3 前面 free
unsorted_chunk3_fd -> unsorted_chunk1 #chunk1 在 chunk3 前面 free
unsorted_chunk3_bk -> main_arena

图个方便,这里就把 chunk3 的 fd 作为目标地址,假设此时上述情况如下
file
将 unsorted_chunk1_bk 改为 target-0x8 ,再申请回 chunk1 ,然后就利用 unsortedbin 机制在 target 位置就成功写入一个main_arena 的地址。有就如上面所示 chunk3_fd 被改写为了 main_arena 的地址。

file
意思就是通过修改 Unsorted chunk_bk 来改变 Unsortedbin链的结构,把目标地址当作了新结点加入了 unsortedbin链中管理,也就写入了对应这个新结点对应地址的内容。

与fastbin attack配合使用

总所周知,Fastbin Attack 在构造 fake chunk 时需要 size 绕过检测(通常用0x7f),而 Unsortedbin Attack 可以像目标地址写一个地址,当 Fastbin Attack 实在构造合格 size 时,就可以利用 Unsortedbin Attack 向 fake chunk 写入一个含有 0x7f 的地址,只是要计算好偏移地址。

梳理步骤

fast_chunk=malloc(0x70)       #申请fast_Chunk
free(fast_chunk)              #构造fastbin链
fast_chunk_fd -> target       #写入目标地址
unsorted_chunk=malloc(0x100)  #申请unsorted_chunk
free(unsorted_chunk)          #构造unsortedbin链
unsorted_chunk_fd -> target   #修改unsorted_chunk的fd指向目标地址
malloc(0x100)                 #将之前的unsorted_chunk申请出来
malloc(0x70)                  #将fast_chunk申请回来
malloc(0x70)                  #申请到目标地址的fake chunk

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据