释放后使用漏洞的可利用性

信息安全 应用安全 C 模糊测试
2021-08-22 01:18:28

释放后使用错误是一类特殊的内存安全错误。在实践中,它们被利用的频率如何?当您在程序中发现释放后使用的错误时,它是经常可利用的,很少可利用的,还是会根据我忽略的其他一些因素而变化?

我对 C 程序中的 use-after-free 错误被利用的频率特别感兴趣(特别是 C,而不是 C++)。C 程序中的 use-after-free 漏洞多久可以利用一次?如果我在我正在测试的 C 程序中发现了一个释放后使用的错误,我应该估计它被利用的可能性是多少?90%?50%?10%?在对 bug 进行分类时(例如,fuzzer 崩溃、Valgrind 警告、来自静态分析工具的警告),与其他类型的内存安全 bug 相比,我应该在多大程度上优先修复 use-after-free 的 bug?


我做过的研究。 我一直在做一些研究。看起来 C++ 程序中的 use-after-free 错误通常是可利用的(因为 C++ 对象的内存布局总是包含指向 vtable 的指针,并且覆盖它很容易导致代码注入)。好的,很好。那么C程序呢?

我还可以看到在某些特殊情况下如何利用释放后使用错误。例如,浏览器或其他具有用户可控脚本的程序中的释放后使用错误似乎经常可以利用,因为进行堆喷射很容易,并且可以对存储在内存中的对象的内容进行大量控制。. 而且,是的,我已经看到了一些在某些特殊情况下利用释放后使用错误的复杂方法(例如,将它们用于信息披露,然后让您对 ASLR 进行去随机化,之后......),但这些看起来很漂亮特定于应用程序,就像您可能需要幸运才能使攻击起作用,即使那样,构建漏洞利用也需要大量工作。但我很感兴趣的是知道“典型案例”通常是什么样子,而不是攻击者幸运的特殊情况。

1个回答

Use-after-free 攻击要求攻击者能够在堆上可靠地分配一些内存。

假设我有一个需要 16 个字节的对象,并且恰好在内存中分配给 0xb00000004 (这里完全由数字组成)。我删除了这个对象并将内存返回到堆中。现在我请求另一个 16 字节的堆分配(例如一个字符串),堆在 0xb0000004 上分配它。现在一个引用旧对象的指针反而调用了新对象,甚至没有意识到它。

正如您之前提到的,这在脚本语言中很受欢迎是有原因的。这是因为脚本语言可以可靠地在堆上分配内存。

因此,要知道您是否容易受到攻击,您需要评估攻击者分配内存的难度,以及该攻击者是否可以可靠地分配内存。

在 C 程序中,潜在风险似乎较小,因为任何此类指针或引用都将针对基本数据类型,而不是对象。当程序将其视为数据时,攻击者将如何执行任意代码?在这种情况下,您需要分析您的数据是否可信。

例如,假设您的程序存储了一个字符串“ http://xyz.com/super program.zip”,并且您有下载、提取和执行它的代码。如果攻击者能够以某种方式将该字符串覆盖到http://superbadplace.com/supervirus.zip/ ",那么您的程序可能会无意中安装 shell。