pwn | 堆利用笔记

pwn | 堆利用笔记

先搞清数据结构才行,这部分只能多画图多画表格,不然没办法理解。

堆相关数据结构

glibc的堆块结构如下:
image

ctfwiki上给出的数据结构:
image

INTERNAL_SIZE_T是宏定义,其实就是size_t,在32位下是32位,64位下是64位。
下面是我自己画的图:
image

我们称前两个字段称为 chunk header,后面的部分称为 user data。每次 malloc 申请得到的内存指针,其实指向 user data 的起始处。

faskbin只用fd(单链表)
smallbin,sortedbin只用fd,bk(双向循环链表)
只有largebin里面4个都用到,largebin后两个指针指向的是和它size不同的堆块。

当一个 chunk 处于使用状态时,它的下一个 chunk 的 prev_size 域无效,所以下一个 chunk 的该部分也可以被当前 chunk 使用。这就是 chunk 中的空间复用。

一般情况下,物理相邻的两个空闲 chunk 会被合并为一个 chunk 。堆管理器会通过 prev_size 字段以及 size 字段合并两个物理相邻的空闲 chunk 块。

top chunk

程序第一次进行malloc的时候,heap会被分为两块,一块给用户,剩下的那块就是top chunk。
所谓的top chunk就是出于当前堆的物理地址最高的chunk。
这个 chunk 不属于任何一个 bin,它的作用在于当所有的 bin 都无法满足用户请求的大小时,如果其大小不小于指定的大小,就进行分配,并将剩下的部分作为新的 top chunk。否则,就对 heap 进行扩展后再进行分配。在 main arena 中通过 sbrk 扩展 heap,而在 thread arena 中通过 mmap 分配新的 heap。
需要注意的是,top chunk 的 prev_inuse 比特位始终为 1,否则其前面的 chunk 就会被合并到 top chunk 中。
初始情况下,我们可以将 unsorted chunk 作为 top chunk。

last remainder

在用户使用 malloc 请求分配内存时,ptmalloc2 找到的 chunk 可能并不和申请的内存大小一致,这时候就将分割之后的剩余部分称之为 last remainder chunk ,unsort bin 也会存这一块。top chunk 分割剩下的部分不会作为 last remainder.

堆分配函数

  1. malloc
  2. calloc
    calloc就是malloc然后给malloc的空间清0
  3. realloc(行为比较复杂)
    image

堆溢出

image

篡改FD指针,目标是任意地址分配:

  • fastbin attack
  • tcache attack[new in libc2.27]

篡改BK指针

  • unsortedbin attack

未完待续

posted @ 2023-01-03 19:06  Mz1  阅读(107)  评论(0编辑  收藏  举报