• comm tips:
    • environ指向的地址-30*size 为 main函数的返回地址的栈地址
    • 申请分配large chunk时,会进行 malloc_consolidate,清空fastbins表,进行合并
  • scanf, printf 当输入、输出过长时,会调用malloc、free
  • addr(main_arena)-0x10 = addr(__malloc_hook)
  • malloc、calloc、realloc区别
    •  calloc 在分配后会自动进行清空
    • 当realloc(ptr,size)的size不等于ptr的size时
      • 如果申请size>原来size
        • 如果chunk与top chunk相邻,直接扩展这个chunk到新size大小
        • 如果chunk与top chunk不相邻,相当于free(ptr),malloc(new_size)
      • 如果申请size<原来size
        • 如果相差不足以容得下一个最小chunk(64位下32个字节,32位下16个字节),则保持不变
        • 如果相差可以容得下一个最小chunk,则切割原chunk为两部分,free掉后一部分
    • 当realloc(ptr,size)的size等于0时,相当于free(ptr)
    • 当realloc(ptr,size)的size等于ptr的size,不进行任何操作
  • unlink利用
    • 条件:
      • 存在堆溢出,可以伪造堆块和控制下一个堆块的头部
      • 存在全局指针ptr指向堆块
    • 方法:
      • 伪造堆块
        • fd=ptr-size*3
        • bk=ptr-size*2
      • unlink成功之后
        • ptr=ptr-size*3
        • 编辑ptr指向的内容,修改ptr指向got表,再编辑ptr即可overwrite got表
    • chunk0                malloc返回的ptr           chunk1        malloc返回的ptr
      |                     |                        |             |
      +-----------+---------+----+----+----+----+----+------+------+----+----+------+
      |           |         |fake|fake|fake|fake| D  | fake | fake |    |    |      |
      |           |         |prev|size| FD | BK | A  | prev | size&|    |    |      |
      | prev_size |size&Flag|size|    |    |    | T  | size | flag |    |    |      |
      |           |         |    |    |    |    | A  |      |      |    |    |      |
      |           |         |    |    |    |    |    |      |      |    |    |      |
      +-----------+---------+----+----+----+----+----+------+------+----+----+------+
                            |--------new_size--------|
                            list
  • fastbin attack
    • house of spirit
      • 伪造chunk,free之后再次申请chunk进行攻击
    • double free
      • 重复释放同一个chunk,实现类似类型混淆的效果
    • Arbitrary Alloc

      • 利用: malloc_hook地址-0x28+5 作为伪造的fd指针(地址错位)
        • pwndbg> p &__malloc_hook
          $2 = (void *(**)(size_t, const void *)) 0x7ff5dd109b10 <__malloc_hook>
          pwndbg> dqs 0x7ff5dd109b10-0x28+5
          00:0000│ 0x7ff5dd109aed (_IO_wide_data_0+301) ◂— 0xf5dd108260000000
          01:0008│ 0x7ff5dd109af5 (_IO_wide_data_0+309) ◂— 0x7f
          02:0010│ 0x7ff5dd109afd ◂— 0xf5dcdcae20000000
          03:0018│ 0x7ff5dd109b05 (__memalign_hook+5) ◂— 0xf5dcdcaa0000007f
          04:0020│ 0x7ff5dd109b0d (__realloc_hook+5) ◂— 0x7f
          05:0028│ 0x7ff5dd109b15 (__malloc_hook+5) ◂— 0x0
          ...
          07:0038│ 0x7ff5dd109b25 (main_arena+5) ◂— 0xc7604a04a0000000
  • unsorted bin attack
    • 条件:
      • 能够控制 Unsorted Bin Chunk 的 bk 指针(bk = target_addr – 0x10)。
    • 效果:
      • 实现修改任意地址值为一个较大的数值(unsorte bin地址),例如 global_max_fast,例如_IO_list_all(house of orange)
  • House of Lore(small bin attack)
    • 条件:
      • 能够修改small bin中的bk指针
    • 方法:
      • 修改small bin中的bk指针指向伪造的chunk,同时令fake chunk的fd指针不等于small bin中的最后一个chunk
    • 效果:
      • 任意地址写
  • House Of Einherjar (small或large bin attack)free时触发
    • 条件:
      • 需要有溢出漏洞可以写物理相邻的高地址的 prev_size 与 PREV_INUSE 部分。
      • 我们需要计算目的 chunk 与 p1 地址之间的差,所以需要泄漏地址。
      • 我们需要在目的 chunk 附近构造相应的 fake chunk,从而绕过 unlink 的检测。
    • 方法:
      • 覆盖相邻到地址的prev_size与PREV_INUSE标志位
    • 效果:
      • 任意地址写
  • House Of Force (top chunk)
    • 条件:
      • 能够以溢出等方式控制到 top chunk 的 size 域
      • 能够自由地控制堆分配尺寸的大小
    • 方法:
      • 修改top chunk size域为-1,然后分配指定大小的堆块(计算偏移)
    • 效果:
      • 能够在任意地址分配堆块,实现任意地址写
  • House Of Orange (top chunk + unsorted bin + FILE attack)
    • 条件:
      • 首先需要目标漏洞是堆上的漏洞
      • 不存在free函数或其他释放堆块的函数
    • 方法:
      • 伪造top chunk的size,满足
        1. 伪造的size必须要对齐到内存页
        2. size要大于MINSIZE(0x10)
        3. size要小于之后申请的chunk size + MINSIZE(0x10)
        4. size的prev inuse位必须为1
    • 效果:
      • control the world

参考:

  • https://ctf-wiki.github.io/ctf-wiki/pwn/heap/