我一直在阅读关于ASLR的内容,我有几个问题。我的编程经验很少,但我对它背后的理论很感兴趣。
我理解它随机化了DLL,堆栈和堆在虚拟地址空间中的位置,以便恶意代码不知道它们的位置,但实际程序在需要时如何知道它们的位置?
如果合法进程可以找到它们,那么什么阻止恶意代码做同样的事情呢?
最后,是ASLR试图阻止在其正在攻击的进程的用户空间中运行的恶意代码吗?
由于
答案 0 :(得分:2)
作为背景,ASLR旨在使code injection attacks复杂化,攻击者试图利用您的溢出错误欺骗您的应用程序来运行攻击者的代码。例如,在成功的stack buffer overflow attack中,攻击者将其代码推送到堆栈并修改调用帧的返回指针以指向堆栈代码。
大多数代码注入攻击都要求攻击者知道进程内存布局某些部分的绝对地址。对于堆栈缓冲区溢出攻击,它们需要知道易受攻击的函数调用的堆栈帧的地址,以便它们可以设置函数返回指针指向堆栈。对于其他攻击,这可能是堆变量,异常表等的地址......
一个更重要的背景事实:与编程语言不同,机器代码中包含绝对地址。虽然您的程序可能会调用函数foo()
,但机器代码将调用地址0x12345678
。
但实际程序在需要时如何知道它们的位置?
这是由dynamic linker和其他操作系统功能建立的,这些功能负责将磁盘上的可执行文件转换为内存中的进程。这涉及使用对foo
的引用替换对0x12345678
的引用。
如果合法进程可以找到它们,那么什么阻止恶意代码做同样的事情呢?
合法进程知道地址的位置,因为动态链接器创建进程,使实际地址硬连接到进程中。所以这个过程本身并没有定位它们。到进程开始时,地址全部计算并插入到代码中。攻击者无法利用此功能,因为动态链接器不会修改其代码。
考虑攻击者拥有他们试图攻击的同一可执行文件副本的情况。他们可以在他们的机器上运行可执行文件,检查它,并找到所有相关的地址。如果没有ASLR,当您运行可执行文件时,这些地址很可能在您的计算机上保持相同。 ASLR将这些地址随机化,这意味着攻击者无法(轻松)找到地址。
最后,是ASLR试图阻止在其正在攻击的进程的用户空间中运行的恶意代码吗?
除非存在内核注入漏洞(可能非常糟糕并且导致OS vendpr发布补丁),是的,它正在用户空间中运行。更具体地说,它可能位于堆栈或堆上,因为这是存储用户输入的位置。使用data execution prevention也有助于防止成功的注入攻击。