第一次执行 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。
- memory corruption
- size 是 smallbin 的情况
- smallbin double linked list corrupted
- 从相对应的 smallbin 中拿最后一个时,要符合 smallbin 是 double linked list
- victim == smallbin 最后一块 chunk
- bck = victim->bk
- bck->fd = victim
- smallbin double linked list corrupted
- unsortbin 中有 chunk
- memory corruption
- 取 unsortbin 的最后一块 chunk 作为 victim
- victim->size 要符合规定
- size 必须大于 2 x SIZE_SZ ,必须小于 system_mem
- memory corruption
- size 是 large bin 的情况
- corrupted unsorted chunks
- 在找到适合的 chunk 切给 user 后,剩下的空间会放到 last remainder,然后加到 unsortbin 中
- 这时会取 unsortbin 的第一个的 fd 是否等于 unsortbin 的位置
- corrupted unsorted chunks
detection in free
- invalid pointer
- 检查 alignment
- chunk address 是否为 8 的倍数
- 检查 chunk address 是否小于 -size
- 检查 alignment
- invalid size
- 检查 chunk size 是否合法
- size 必须为 8 的倍数
- 也就是是否符合 alignment
- size 必须大于 MINSIZE
- 检查 chunk size 是否合法
- size 是 fastbin 的情况
- invalid next size(fast)
- 检查下一块 chunk size 是否合法
- size 必须大于 MINSIZE
- size 必须小于 system_mem
- double free or corruption(fasttop)
- 检查 fastbin 中第一块 chunk 跟正要 free 的chunk 是否不同
- 要是相同就会 abort
- invalid next size(fast)
- 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
- double free or corruption(top)
- 在做 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 执行