zoukankan      html  css  js  c++  java
  • Heap exploitation 笔记

    第一次执行 malloc

    • size >= 128k:使用 mmap 函数, kernel 中 sys_mmap
    • size < 128k:使用 brk 函数, kernel 中 sys_brk
    • 无论一开始 malloc 多少空间 < 128k , kernel 都会给 132kb 的 heap
      segment(rw) ,这个部分称为 main arena
    • 第一次 malloc 时就会将 heap 切成两块 chunk ,第一块 chunk 就是要分配出去的 chunk ,剩下的空间视为 top chunk ,之后要是分配空间不足时将会由 top chunk 切出去

    第二次执行 malloc

    • 只要分配出去的总内存大小不超过 128KB ,则不会再执行 system call 跟系统要空间,超过大小才会用 brk 来跟 kernel 要内存空间
    • 即使将所有 main arena 所分配出去的内存体 free 完,也不会立即还给 kernel
    • 这时的内存空间将由 glibc 管理

    main arena header

    • malloc_state
    • 存有 bins 、 fast bin 、 top chunk 等信息
    • 位于 libc 的 bss 段中

    Heap overflow

    • 在 heap 段中发生的 buffer overflow
    • 通常无法直接控制 eip ,但可以利用覆盖下一个 chunk heaker ,并利用 unlink 时的行为来间接连成任意位置写入,进而控制 eip
    • using unlink:通过 overflow 覆盖掉 freed chunk 中的 fd 及 bk 指针,再利用 unlink 中 FD->bk = BK 及 BK->fd = FD 来更改任意内存体位置

    detection in malloc

    • size 是 fastbin 的情况
      • memory corruption
        • 从 fastbin 取出的第一块 chunk 的 size 不属于该 fastbin 中的
        • 主要检查方式是根据 malloc 的 bytes 大小取得 index 后,到对应的 fastbin 找,取出第一块后检查该 chunk 的 size 是否属于该 fastbin
        • 但实际比较的时候是先以 fastbin 中第一块 size 取得 fastbin 的 index,再去比 index 跟刚刚算的 index 是否相同,不过这取 index 的方式是用 unsigned int。
    • size 是 smallbin 的情况
      • smallbin double linked list corrupted
        • 从相对应的 smallbin 中拿最后一个时,要符合 smallbin 是 double linked list
        • victim == smallbin 最后一块 chunk
        • bck = victim->bk
        • bck->fd = victim
    • unsortbin 中有 chunk
      • memory corruption
        • 取 unsortbin 的最后一块 chunk 作为 victim
        • victim->size 要符合规定
        • size 必须大于 2 x SIZE_SZ ,必须小于 system_mem
    • size 是 large bin 的情况
      • corrupted unsorted chunks
        • 在找到适合的 chunk 切给 user 后,剩下的空间会放到 last remainder,然后加到 unsortbin 中
        • 这时会取 unsortbin 的第一个的 fd 是否等于 unsortbin 的位置

    detection in free

    • invalid pointer
      • 检查 alignment
        • chunk address 是否为 8 的倍数
      • 检查 chunk address 是否小于 -size
    • invalid size
      • 检查 chunk size 是否合法
        • size 必须为 8 的倍数
        • 也就是是否符合 alignment
      • size 必须大于 MINSIZE
    • size 是 fastbin 的情况
      • invalid next size(fast)
        • 检查下一块 chunk size 是否合法
        • size 必须大于 MINSIZE
        • size 必须小于 system_mem
      • double free or corruption(fasttop)
        • 检查 fastbin 中第一块 chunk 跟正要 free 的chunk 是否不同
        • 要是相同就会 abort
    • size 是 smallbin & largebin 的情况(非 mmap)
      • double free or corruption(top)
        • 检查正要 free 的 chunk 跟 top chunk 的位置是否不同
        • 要是相同就会 abort
      • double free or corruption(out)
        • 计算出来下一块 chunk 的位置是否超出 heap 的边界
        • 超出 heap 边界就会 abort
      • double free or corruption(!prev)
        • 根据下一块 chunk 的 inuse bit 来检查正要 free 的 chunk 是否已被 free 过
      • invalid next size(normal)
        • size 必须大于 2 x SIZE_SZ
        • size 必须小于 system_mem
      • corrupted unsorted chunks
        • 在 unlink 后要放到 unsortbin 时,会先从 unsortbin 取第一块 chunk 出来 ,然后检查该 chunk 的 bk 是否等于 unsortbin
    • 在做 unlink 时
    • courrupted double linked list
      • 检查 circular doubly linked list 的完整性,指出去在指回来必须指向值及,否则就会表示 corrupted double-linked list 中断
      • P->bk->fd == p
      • P->fd->bk == p

    using unlink(modern)

    • bypass the detection
      • 必须伪造 chunk 结构
      • 必须找到指向伪造 chunk 的 pointer 及该 pointer 的 address
      • 因此能直接改的地方有限,通常要间接去读取或写入任意位置
      • 通常 r 会是个 data pointer
      • 可以利用他再去改变其他存在 &r 附近的 pointer 然后在利用这些 pointer 去造成而任意位置读取及写入,如果存在 function pointer 更可直接控制 eip 。

    Using malloc maleficarum

    • stack overflow
      • 当 stack overflow 不够覆盖到 ret 时
      • 利用 stack overflow 覆盖要 free 的 ptr 并伪造 chunk
      • 须针对 prev_size 及 size 做处理,通过检查
    • using fastbin
      • 当下次 malloc 时,就会取得伪造的 chunk
    • The House of Spirit
      • 可以做information leak
      • 也可加大 stack voerflow 的距离
      • 要先算算在 stack 中去下一块 chunk 的 size 是否为 8 的倍数, size 的取决是很重要的
    • The House of Force
      • heap overflow 覆盖 top chunk 的 size ,变成一个很大的值
      • 下次 malloc 是,malloc 一个很大的数字(nb),然后 arena header 中的 top chunk 的位置会改变
        • new top chunk = old top + nb + 8
        • nb 可以是负的,因为传进去会被自动转换成很大的数字,只要让 fake szie - nb > 0 就会让 glibc 以为 top 还有空间可以给
      • 这样下次 malloc 的位置将会是 new top chunk 的位置。

    Using fastbin

    • 类似 House of Spirit
    • 如果可以改到 fastbin 的 free chunk 可以将 fd 改成 fake chunk 的位置,
      只要符合 size 是属于改 fastbin 就好,因为下次 malloc 只会检查这项
    • 下下次 malloc(size-0x10)时,就会取得该 fake chunk 的位置
    • fake chunk 可以是任意内存体位置

    Some useful global variable

    • __free_hook 、 __malloc_hook 、 __realloc_hook
      • free 、 malloc 、 realloc 前会先检查是否上面三个全局变量有值,若有则当 func ptr 执行
    • __malloc_initialize_hook
      • ptmalloc_init 时(第一次执行 malloc 会用),会检查该变量是否有值,若有则当 func ptr 执行
    • __after_morecore_hook
      • 在跟用 brk 跟系统要 heap 空间时,会检查该变量是否有值,若有则当 func ptr 执行

    内容来源

    Heap exploitation

  • 相关阅读:
    Kafka 生产者 自定义分区策略
    同步互斥
    poj 1562 Oil Deposits(dfs)
    poj 2386 Lake Counting(dfs)
    poj 1915 KnightMoves(bfs)
    poj 1664 放苹果(dfs)
    poj 1543 Perfect Cubes (暴搜)
    poj 1166 The Clocks (暴搜)
    poj 3126 Prime Path(bfs)
    处理机调度
  • 原文地址:https://www.cnblogs.com/luoleqi/p/12348316.html
Copyright © 2011-2022 走看看