2012-07-14 101 views

回答

19

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

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

+1

很好的回答。然而,一个小的评论 - (盲)ROP实际上击败了ASLR http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=6956567&url=http%3A%2F%2Fieeexplore.ieee.org%2Fxpls% 2Fabs_all.jsp%3Farnumber%3D6956567 – 2015-03-15 20:23:34

0

您可以跳转到这是个可执行段和运行你的邪恶代码的任何其他地方...

毕竟,所有的任何存储中的数据,内存位,位可以是指令给CPU执行。

+0

这个问题似乎是关于当除了程序代码之外的所有内容都在非可执行内存中的情况。你如何将你的代码加载到可执行的内存呢?跳到它可能很容易。 – 2012-07-14 07:57:11

+0

攻击者可以使用代码例如查找pop eax; jmp eax ... – 0x90 2012-07-14 09:20:33

0

您可以使用您的溢出来覆盖函数的返回地址,该函数可以通过您的代码跳转到某个已知地址。但随后OS作家通过随机地址代码的响应被执行...

+0

首先,如果除了程序代码之外的所有内容都在非可执行内存中,您如何将代码加载到可执行位置?单独地址空间随机化并不能防止基于ROP的攻击。看到我的答案。 – 2012-07-14 07:55:39

1

这种保护由操作系统提供,并且不能在应用程序层完成。

请参见维基百科的文章,这也说明如何启用Windows下:http://en.wikipedia.org/wiki/Data_Execution_Prevention

+1

理论上,你可以自己做,它基本上只是一堆mprotect(2)的调用。 – tbert 2012-07-14 07:47:39

+0

感谢您的信息:) – rgngl 2012-07-14 07:55:03

+0

没问题:)请记住,最重要的事情是确保内存不能同时写入和执行。 – tbert 2012-07-14 07:58:20

9

还有就是被称为“回归 - 面向对象编程”(又名ROP)攻击的类型。

攻击者发现如何使用正在被利用的程序的不同部分编写他的恶意代码。

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

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

所以,现在好的代码变成了邪恶的代码。没有任何东西在堆栈或堆中执行。同样值得注意的是,在指令跨越多个字节且长度可变的CPU上,即使作为指令一部分的立即指令操作数(IOW,数值常数)也可以变成代码,因此找到可用字节序列的机会比“简单”的CPU要高。

构建恶意代码通常也是可能的,这些恶意代码会改变内存保护,并且攻击将不再受现有应用程序代码的限制。

4

非常具体的例子:安排返回地址指向system和堆栈中的下一个槽(或通过寄存器拱形的第一个参数寄存器)作为指向字符串"/bin/sh"的指针。

+0

但是,在这种情况下,您是否还需要访问控制台? – 2012-07-14 08:03:17

+1

不是,我假设进程的stdin是一个你连接的套接字或者终端,但是如果没有,只要把'/ bin/sh“改成'”/ bin/sh 0 <&n“'其中'n'是连接的服务器套接字的文件描述符号。 – 2012-07-14 08:16:22

+1

或者当然,您也可以在没有交互式外壳的情况下将其更改为您想要的任何内容,例如'“echo'toor :: 0:0 :: /:/ bin/sh'>>/etc/passwd”' – 2012-07-14 08:37:21

-1

您的代码在文本段中运行,而不是堆栈或堆(两者均用于数据存储)。因此,该组织是:

<highest addresses> 
stack 
... 
heap 
data section (initialized data & bss - uninitialized data) 
code section (text) 
<lowest addresses> 

代码段是可执行但不可变的。这个维基百科文章有更多的细节:https://en.wikipedia.org/wiki/Data_segment