堆的基本结构
堆是系统内存分配出来进行管理的虚拟内存,由内存管理器进行管理。
堆的基本结构如上
mem下依次为指向下一个堆块,指向上一个堆块,指向下一个不同的堆块以及指向上一个不同的堆块
其中small bin 和fast bin只会有上面两种指针
两种表的连接方式不同,而large形式的则会使用上述的四种指针
而不同的链接方式之间最大的差距是效率不同,其中large表可以减少遍历的时间
进攻方式
size篡改
通过对victim也就是对修改区的堆的大小进行篡改,破坏原有的链表结构,以达成目的,当然在链表的修改中,系统会进行合法性检查,其中会对fd和bk的值进行进行比对(空闲时,fd存储下一个空闲的chunk,bk指向上一个空闲的chunk)
所以我们要构造能够满足要求的fd和bk使其能形成一个完整的链表,所以我们让一个指针指向这个堆块,然后让fd=*b-12,bk=*b-8(以32位为例),符合上出的合法性检测,然后我们就可以通过对b-12所指的区域进行写入,覆盖掉原有的区域
在fastbin的单链表的输入时,可以篡改fd使其指向一个地址,但是要注意指向的地址本身要符合chunk堆的要求
而对于bk的篡改,可以写入libc地址,配合libc进行使用
然后刚开始最简单就是fastbin attack
#include<stdio.h>
int main(void)
{
void *chunk1,*chunk2,*chunk3;
chunk1=malloc(0x30);
chunk2=malloc(0x30);
chunk3=malloc(0x30);
//进行释放
free(chunk1);
free(chunk2);
free(chunk3);
//重新获取
malloc(0x30);
return 0;
}
最终chunk1的fd不再指向0,而是指向chunk2,然后通过chunk1的内容改变fd的指向,达到目的