精选文章:
硬核二进制安全学习FunctionPrologue and Function Epilogue基础函数调用机制
硬核二进制安全学习:Buffer Overflow(栈的缓冲区溢出&&Pwn技巧Return to Text)
知者行之始,行者知之成。
-——王阳明
堆溢出介绍:
堆溢出是指程序向某个堆块中写入的字节数超过了堆块本身可使用的字节数(之所以是可使用而不是用户申请的字节数,是因为堆管理器会对用户所申请的字节数进行调整,这也导致可利用的字节数都不小于用户申请的字节数),因而导致了数据溢出,并覆盖到物理相邻的高地址的下一个堆块。
程序向堆上写入数据。
写入的数据大小没有被良好地控制。
堆溢出是一种特定的缓冲区溢出(还有栈溢出, bss 段溢出等)。但是其与栈溢出所不同的是,堆上并不存在返回地址等可以让攻击者直接控制执行流程的数据,因此我们一般无法直接通过堆溢出来控制 EIP 。一般来说,我们利用堆溢出的策略是
1.覆盖与其物理相邻的下一个 chunk 的内容。
prev_size
size,主要有三个比特位,以及该堆块真正的大小。
NON_MAIN_ARENA
IS_MAPPED
PREV_INUSE
the True chunk size
chunk content,从而改变程序固有的执行流。
2.利用堆中的机制(如 unlink 等 )来实现任意地址写入( Write-Anything-Anywhere)或控制堆块中的内容等效果,从而来控制程序的执行流。
[CTFWiki]
1.堆的申请
在我们常见的操作中,堆是用malloc函数申请使用的。
Void *ptr=malloc(0x10)
系统会调用一些函数在内存中开辟一大片空间作为堆分配使用空间。
2.malloc函数在这一片堆分配使用空间中分配0x10大小的空间,将指向该空间的地址返回给ptr(余下的空间称为topchunk)
使用堆的程序演示案例:
#include <stdio.h>
#include <stdlib.h>
int main()
{
void *ptr=malloc(0x10);
void *ptr1=malloc(0x90);
void *ptr2=malloc(0x800);
return 0;
}

我们在main处打下断点接着run起来。

使用vmmap查看内存,发现系统并未给我们分配空间。使用n命令继续调试,一直到第一次调用malloc函数。

我们看调用完成以后有什么变化,继续使用vmmap地址映射空间。

此时我们观察heap大小会发现他的大小比较大

本文探讨了堆溢出原理,如何通过控制chunk结构和内存分配来影响程序执行流,以及malloc函数的工作流程、chunk数据结构详解、堆的申请与释放机制、分箱式管理(fastbins, smallbins, largebins)和堆溢出利用策略。
2718

被折叠的 条评论
为什么被折叠?



