为什么有些 DLL 不是随机的?是什么让为所有 DLL 部署完整的 ASLR 变得困难?

信息安全 硬化 记忆 aslr
2021-08-26 17:40:05

为所有内容部署 ASLR 的挑战之一是,至少在 Windows 上,某些 DLL(库)未以与 ASLR 兼容的方式编译。(它们没有被编译为与位置无关的代码,因此它们在内存中加载的位置不能随机化。)

这是有问题的,因为如果应用程序仅加载一个非随机化的 DLL,那么它实际上就不是随机化的。为了阻止标准攻击(例如,ROP 攻击),所有代码都必须随机化:即使是单个非随机化的 DLL 也足以让 ROP 攻击成为可能。因此,对于一阶近似,ASLR 仅在其所有DLL 都是随机化的情况下才可用于保护特定应用程序。应用程序通常会加载许多 DLL,并且由于只需要一个非随机 DLL,因此确保所有 DLL 都是随机的尤为重要。

一般来说,业界正朝着增加随机化使用的方向发展,但速度很:我想将它带到任何程序将使用的每个 DLL 都需要时间。例如,最近发现Dropbox DLL 不使用随机化,因此任何使用 Dropbox DLL 的程序都不会受到 ROP 攻击的保护(任何使用 Dropbox DLL 的程序都会失去 ASLR 的好处)。

我的问题:某些 DLL 不随机化的典型原因是什么?通常是某种技术障碍或技术问题导致难以或不可能将 DLL 编译为与位置无关的代码吗?构建 DLL 的开发人员是否缺乏对安全性的认识/关注?是否是旧版 DLL 非常旧且尚未重新编译以利用随机化?默认情况下 Microsoft Visual C++ 是否无法执行正确的操作(默认情况下是否无法将 DLL 编译为与位置无关的代码)?完全是另外一回事吗?

是否有任何技术进步或工具可以帮助为当前不支持随机化的 DLL 更好地部署 ASLR/随机化?

相关资源:SlopFinder是一种用于扫描系统以查找不支持 ASLR 的 DLL 的工具。

1个回答

这里有一些很好的信息显然,由于“向后兼容性问题”,DLL 只能在被标记为 ASLR 时才受制于 ASLR。尽管 DLL 本质上是要重新定位的,但我可以想象一些(糟糕的)编写的软件可能会做一些技巧,这些技巧依赖于 DLL 最终位于相对较小的地址空间范围内(可能的候选者是一些需要区分“指向数据的指针”和“指向代码的指针”的垃圾收集器——我知道在带有 Linux 仿真的 OpenBSD 上启动某些版本的 Chrome 的 Javascript 解释器时会出现此类问题)。

如果 Microsoft 费心实施额外的标志,那么他们遇到至少一个他们无法忽视的此类软件案例是合理的(如果不是可能的话)(向后兼容性在 Windows 世界中非常重要)。

因此,如果静态链接器在上次构建 DLL 时这么说,DLL 将允许 ASLR 发生。这是使用/DYNAMICBASE标志的问题。文件指出:

默认情况下,/DYNAMICBASE 处于打开状态。

Visual Studio 2010 和 2012 的文档包含这句话,但不是 Visual Studio 2008 的文档。因此必须假设大多数使用 Visual Studio 2010+ 的人生成与 ASLR 兼容的 DLL,但大多数使用 Visual Studio 2008 或以前的版本生成不受ASLR 约束的 DLL。

在我上面第一个链接的页面中,其中一条评论说:

在构建 PE 映像后,您仍然可以使用 Microsoft 链接器来执行此操作。使用链接 /edit /dynamicbase (或 editbin /dynamicbase )。

所以你可以“修复”一个 DLL,但这是假设 DLL 不会被 ASLR 破坏,即缺少标志只是由于 DLL 供应商使用的 Visual Studio 的默认配置。