如果您的堆栈和堆不可执行,您的代码如何运行?

Ada*_* Sh 24 c security buffer-overflow

我读了一本关于缓冲区溢出的书,它建议下一步处理:

使堆栈(和堆)不可执行可以为现有程序提供高度保护,防止多种类型的缓冲区溢出攻击.

但我不明白我们怎么做 - 执行会发生在哪里,如果不在堆上或堆栈上?

Jim*_*ter 25

如果我理解你的问题,其他答案都没有解决.答案是执行发生在代码部分,既不是堆栈也不是堆.在典型的分页存储器系统中,来自程序文件(例如,Windows中的.exe)的代码被加载到可执行但只读的页面中.其他可写(和可执行)页面被分配给堆栈和堆的进程.这里的建议是操作系统和硬件应该合作来标记那些可写但不可执行的页面(rgngl的答案解释了如何在Windows中这样做).

即使使用不可执行的堆和堆栈,仍然有可能使用Alexey Frunze的答案中提到的面向返回的编程,但是有一些保护技术甚至阻碍了这些,例如堆栈粉碎保护和地址空间布局随机化 - 请参阅http://en.wikipedia.org/wiki/Return-to-libc_attack#Protection_from_return-to-libc_attacks


Ale*_*nze 10

这就是所谓的"面向返回编程"(AKA ROP)类型的漏洞利用.

攻击者发现如何利用被利用程序的不同部分制作他的邪恶代码.

他在返回指令字节之前找到可用的字节序列(指令),它可以对寄存器或存储器执行有用的操作,例如将值移动到某个位置,添加值,比较值等等.这些是漏洞获取的微子程序建成的.

然后通过利用代码错误,攻击者强迫程序开始执行那些完成所有恶行工作的微子程序链.

所以,现在好的代码变成了邪恶的代码.没有在堆栈或堆中执行任何操作.

值得注意的是,在指令跨越多个字节并且长度可变的CPU上,即使作为指令一部分的立即指令操作数(IOW,数字常量)也可以成为代码,因此找到可用字节序列的机会高于在"更简单"的CPU上.

通常还可以构建可以改变内存保护的恶意代码,并且该漏洞将不再受现有应用程序代码的约束.