绕过 DEP/ASLR 的“泄漏指针”如何工作

信息安全 开发 外壳代码 aslr 部门
2021-09-01 18:53:49

我想知道是否有人可以给我一些关于“泄漏指针”如何绕过 DEP/ASLR 工作的线索。我在这里读到

可靠绕过 DEP 和 ASLR 的唯一方法是通过指针泄漏。在这种情况下,堆栈上的一个可靠位置的值可能用于定位可用的函数指针或 ROP 小工具。完成此操作后,有时可以创建可靠绕过两种保护机制的有效负载。

这是如何完成的对我来说是一个谜。我有一个缓冲区溢出..所以我可以覆盖直到 EIP 和堆栈内容..我在堆栈中有一个可靠的函数指针或代码指针,我知道它存储在哪里..如果我知道这个位置..怎么办我把这个地址放在EIP里?如果我无法将 EIP 更改为那个可靠的位置,我将无法控制执行流

2个回答

“泄漏指针”,通常称为“悬空指针”,可用于创建攻击链以绕过分层安全系统。

DEP 背后的想法是您使内存区域不可执行,从而无法执行该区域中的 shellcode。单独的 DEP 真的很容易绕过,您可以直接 ret-to-lib,并调用您想要的任何函数, system()是您的最爱。

但是,在 Windows 下,启用ASLR的库会有一个随机的内存空间,因此攻击者不知道system()函数的内存地址,因此无法调用它。ASLR 背后的想法是,如果你不知道跳转到哪里,是否可以控制 EIP 并不重要。

能够读取随机内存区域的位置会破坏对 ASLR 的保护,因为现在您有了可靠的跳转位置。这可以通过多种方法来实现。在针对 IE 的 pwn2own 中使用了缓冲区溢出来简单地覆盖空终止符并读取数组末尾。但实际上最常见的技术是使用悬空指针,尽管有 ASLR,它仍可用于读取/写入甚至执行有效的内存位置。

即使使用 ASLR,也不是每个内存位置都是随机的。事实上,可执行二进制文件具有可预测的布局,因此您可以在ROP 链中针对自身使用可执行文件。然而,有时很难找到有用的 ROP 小工具,尤其是在目标二进制文件非常小的情况下。如果您无法构建有用的 ROP 链,那么内存泄露漏洞(例如悬空指针)是一种很好的攻击方法。需要注意的是,ASLR 只随机化页面的位置(内存地址的前几个字节)。如果您可以使用您的 shellcode 填充此页面中的一个区域,那么可以使用泄露的代码准确地执行您的 shellcode内存地址作为基础,然后希望你的 shellcode 位于这个随机位置的某个偏移量。

使用内存操作漏洞链通常只能在脚本环境中使用,例如 JavaScript。

ASLR 涉及随机化对象在内存中的位置。例如,堆可能会移动到内存中的随机偏移量。

如果您以某种方式设法了解堆中对象的地址,那么您将获得大量有关堆在内存中的位置的信息。这可能足以让您预测堆中其他对象的位置。到那时,ASLR 的随机化就变得毫无用处了。因此,揭示指针值(其地址)的信息泄露漏洞可能被用于破坏 ASLR。

指针的地址怎么会泄露?一种方法是通过格式字符串漏洞。假设你这样做是这样的:

printf(msg);

msg攻击者控制的消息在哪里,攻击者可以在哪里读取标准输出然后攻击者可以指定 message 应该是 string "%d",这将揭示堆栈上一些随机数据的值,这很可能是一个有效的指针。(为什么?因为printf()认为您传递了另一个参数并在堆栈上查找并打印该附加参数的值。它不知道您实际上没有传递另一个参数,它实际上是在搜索不相关的内存。)

还有其他方式可以泄露此类信息,但如果可以,您通常可以绕过 ASLR。一旦您可以绕过 ASLR,您就可以使用标准技术来利用缓冲区溢出漏洞。因此,在您的应用程序中存在这些类型的信息泄露漏洞并不是一件好事。