堆溢出攻击是如何执行的?
在堆栈溢出攻击中,攻击者会用自己选择的地址替换函数返回地址。
那么,在堆溢出攻击中又是如何做到这一点的呢?此外,是否可能从堆上运行代码?
堆溢出攻击是如何执行的?
在堆栈溢出攻击中,攻击者会用自己选择的地址替换函数返回地址。
那么,在堆溢出攻击中又是如何做到这一点的呢?此外,是否可能从堆上运行代码?
请注意,这因平台而异,我的示例过于简化。基本上归结为堆管理器具有可能被覆盖的链表,您可以使用链表指针来覆盖进程内存的随机部分。
想象一下,我有一个天真的堆实现,其控制块如下:
struct HeapBlockHeader
{
HeapBlockHeader* next;
HeapBlockHeader* prev;
int size;
// Actual heap buffer follows this structure.
};
当堆被释放时,这个控制块通过修改next/prev指针返回到一个已释放块的列表中。如果我溢出了堆缓冲区,我可以用我控制的数据覆盖下一个控制块中的指针。假设我覆盖这些链接以将它们指向指向代码的指针(可能只是在我溢出的缓冲区中)和堆栈上函数的返回地址。当堆管理器尝试将块链接回到已释放列表时,它实际上会用我控制的代码指针覆盖堆栈上的返回地址。
这篇文章对堆溢出攻击进行了很好的概述:http://www.h-online.com/security/features/A-Heap-of-Risk-747161.html
这篇文章描述了一些硬化的策略,用于Vista的堆管理器,以防止这种类型的攻击:http://www.blackhat.com/presentations/bh-usa-06/BH-US-06-Marinescu.pdf
编辑:有可能从堆运行代码,是的这是可能的。现在许多平台默认将堆内存设置为不可执行,这提高了获取任意代码运行的难度。然而,你仍然可以进行“跳转到libc”样式的攻击——覆盖返回地址到一个已知的函数,该函数将是可执行的。