我应该再麻烦教缓冲区溢出吗?

信息安全 应用安全 攻击 源代码 用户教育 缓冲区溢出
2021-08-20 15:58:34

学生们怀疑关闭不可执行堆栈、关闭金丝雀和关闭 ASLR 是否代表了一个现实的环境。如果 PaX、DEP、W^X 等能够有效阻止缓冲区溢出攻击,那么学习它们还有价值吗?

4个回答

绝对地。 ASLRDEP是纵深防御措施。存在可以绕过它们中的每一个的漏洞(对于一个真实的示例,请查看Peter Vreugdenhil 的 Pwn2Own 漏洞,他用于对抗 IE)。

绕过 Windows 的 ASLR 所需要的只是一个信息泄露漏洞,它会让你知道进程中加载​​的 DLL 的基地址(这是 Vreugdenhil 利用的第一个漏洞)。由此,您可以使用ret-to-libc攻击来调用该 DLL 中的任何函数。

底线:堆栈(和堆)溢出在今天绝对仍然相关。它们比以前更难利用,但它们仍然具有相关性。

除了@Larry 和@SteveS 出色的简洁答案,我想指出一个非常重要的点:

学生们怀疑关闭不可执行堆栈、关闭金丝雀和关闭 ASLR 是否代表了一个现实的环境。

希望这适用于您的学生系统。
然而,不幸的是,在世界其他地方,这仍然很常见。除了不支持这些的平台之外,总是有一些构建不佳的产品需要关闭这些、旧版本的操作系统,甚至只是糟糕的错误配置。
还是现实的,可惜了。

最重要的是,还有 2 条来自教育工作者的评论:
1.必须有人建立这些防御,对吗?
2. 即使假设它们是正确的——但这you only need pointers in C/C++并不意味着 Java 开发人员不应该学习这些东西在计算机内部是如何工作的,对吗?

是的。除了缓冲区溢出导致成功利用的系统之外,对缓冲区溢出的完整解释始终是展示您应该如何考虑安全性的好方法。而是专注于应用程序应该如何运行,看看可以做些什么来使应用程序脱轨。

此外,无论堆栈执行和安装了多少尖叫金丝雀,缓冲区溢出都是一个错误。所有这些安全特性只是改变了错误的后果:你“只是”让应用程序立即崩溃,而不是远程外壳。不关心应用程序崩溃(特别是可以远程触发的崩溃)充其量是非常草率的编程。不在我的手表上!

为了完整性,不可执行的堆栈和金丝雀不会防止缓冲区溢出;他们只是关闭了一些利用缓冲区溢出的简单方法。传统的缓冲区溢出是将返回地址替换为指向恶意代码的指针,该恶意代码作为溢出缓冲区的数据的一部分加载;恶意代码在函数返回时被执行。不可执行的堆栈意味着攻击者将无法将他的代码放在堆栈上(他将不得不安排跳转到一些库代码,例如execve()在标准库中实现)。如果堆栈缓冲区溢出(假设溢出是“简单的”:连续的数据块),金丝雀会阻止使用返回地址。但是溢出也可能覆盖其他一些数据,包括函数指针(特别是在 C++ 的上下文中)。

绝对地。他们知道这些是问题的解决方案是不够的,他们应该知道如何以及为什么它们是问题的解决方案。

此外,并非所有平台都支持这些技术。