堆的初学笔记2
https://www.jianshu.com/p/3d1db2fb7ed4
堆溢出:通过向堆区域写入超出其分配内存边界的数据,从而覆盖相邻的内存空间。
UAF:释放后引用
当两者同时存在时,攻击者可通过利用堆溢出漏洞来修改或篡改已释放的内存块,进而改变UAF漏洞的利用条件,或影响其后续的使用。
fastbin就是在释放一个小于global_max_size的且不小于最小内存的chunk的时候,用来存放这块堆内存的bin,是单链表结构(问题,global_max_size是什么,bin包含什么)(global那个并没有搜到什么,根据翻译应该是全局最大尺寸
bin:
简单来说,bin就是空闲chunk的容器,用户free后,ptmalloc会统一管理heap和mmap映射区中空闲的chunk,当下一次请求分配的时候ptmalloc会在空闲的chunk中选择一个合适的分配,避免频繁的系统调用。
ptmalloc将大小相似的chunk用双向链表连接起来,就形成了一个bin,ptmalloc共维护了128个这样的bin,并使用数组来存储这些bin

数组中第一个bin是unsorted bin,数组中从第2个到64个bin是small bin,它的chunk size依次递增8bytes,每个small bin中的chunk大小相同。
small bin是一个双向链表。双向链表不是循环链表,是有顺序的。在相同大小chunk的bin中的排序是按照[最近使用]的顺序,排在后面的最容易被选中,刚被释放的放在前面(这是什么意思?先进先出?)
small bin后面是large bin,large bin中的chunk的大小不是固定的,而是有一个范围。其中的顺序是按照大小排序的,越大的放在越下面,如果大小相同则按照[最近使用]的顺序。(我需要理解,什么是下面上面,上面是前面后面)
(bin是什么东西?存放了什么?按照道理来说,堆应该还是在原位置,此处是指向堆的指针?)

当空闲的chunk被连接到bin的时候,ptmalloc会把表示该chunk是否正在使用的标志p设为0(这个标志实际处在下一个chunk中)同时ptmalloc还会检查它前后的chunk是否为空,如果为空,ptmalloc会把这些chunk合并成一个打的chunk如何把合并的chunk放入unsorted bin,但对于较小的chunk,ptmalloc会把它放入fastbins中
fastbins
当用户请求小内存,并且释放后也可能再申请小内存。所以合并释放小内存并不明智。再fastbin中,不大于max_fast(默认值为64B)的chunk被释放后,首先会被放到fastbins中,fastbins中的chunk并不改变它的使用标志p,这样也就无法将他们合并,当需要给用户分配的chunk小于或等于max_fast时,ptmalloc首先会在fastbins中查找相应的空闲块,如果找不到才回去bins里面找
在某个特定的时刻,ptmalloc会遍历整个fastbins将相邻的空闲chunk进行合并,并将合并后的chunk加入unsorted bin再加入其他的bin中。
如果被用户释放的 chunk 或在 fast bins 中合并的 chunk 大于 max_fast,则 ptmalloc 会把这些 chunk 放入 unsorted bin 中。在查找合适的 chunk 的时候,首先在 unsorted bin 中查找合适的空闲 chunk,然后才查找 bins。
如果 unsorted bin 中没有合适的 chunk,则会把 unsorted bin 中的 chunk 加入到 bins 的其他 bin 中,再进行查找
大概是这样)
书接上文
(blog:[Pwn之路] 欢迎来到堆攻击的世界——简单堆溢出原理和例题 - FreeBuf网络安全行业门户)
fastbin attack
头部,主体
头部通常记录内存块的状态(已分配或空闲)、大小、指向下一个或上一个内存块的指针等信息
主体用于存储分配出去的内存块和空闲内存块,通常是由一块或多块的连续虚拟内存组成。每个内存块包括一个头部和一个实际的数据部分。
攻击第一步:修改指针
当释放一个符合大小的内存堆A,A会被分配到fastbin中,再释放一个符合大小的内存堆B,B也会被分配到fastbin,此时B存放的next指针就是A,如果再释放一次A,那么A的next就会指向B,两边就会相互指了,达成修改next的目的(没看懂为了做什么,只达到了互指,具体怎么操作还得继续看)
修改指针有什么用呢?
我们修改指针就可以在下次申请内存的时候申请到我们控制的内存。
因为fastbin的特性,刚释放B后再申请相同大小的就会得到B,然后再申请一次就会得到B指向的A。
所以如果我们申请到B,并且B中存放的next是C,再申请就会得到C,随后可以修改C中的内容(这是什么意思?懂了,next指针是下一次申请得到的内存,因此修改next可以指向某个区域从而修改该区域内容)
了解函数malloc_hook
它是GNU C库(glibc)中的一个特殊函数,它可以被用来重写malloc()、realloc()、free()、等内存管理函数的实现,从而堆程序的内存分配和释放过程进行自定义的控制与监测。
通过设置该函数的指针,可以在调用malloc realloc等函数时,先执行我们自定义的一些操作或者根据一些条件来决定是否执行标准的内存分配/释放操作,比如检测内存泄露、记录内存分配释放信息什么的,主要在malloc realloc free调用前先调用malloc_hook,从而达到检测和自定义函数的目的
那么很明了了,一旦修改了malloc_hook函数指针,那就会在下一次malloc等调用
时先执行到我们需要的地址,从而getshell
实际上,这种思路也会用于got表劫持、UAF漏洞,即修改相关调用函数的地址,从而达到劫持程序流的目的。

伪装堆块,使得heap指针数组被涵盖在堆内,然后通过edit修改堆内容,即修改heap指针?然后调用控制程序流
通过修改fd指针可以确定下一次申请到的堆的地址在什么地方,然后填入较大的size,再借此修改heap指针数组内存放的指针,修改heap0的指针为free函数的got表,然后通过edit,去到那个地方将free的got表修改为system的plt表
由于在调用free时,是会先找free的plt表,然后跳转到free的got表执行一次跳转,此时把free的got表修改了就会跳转system去执行
最后执行free函数,即getshell

浙公网安备 33010602011771号