我刚刚了解了缓冲区溢出攻击背后的逻辑以及 UNIX 2.6 以上内核版本中可用的相关保护机制,以避免缓冲区溢出攻击(地址随机化和堆栈粉碎保护)。
每次我们继续禁用地址随机化(将“0”分配给内核地址随机化)和 Stack Smash Protection(在编译时包括 -fno-stack-protector)以分析缓冲区溢出攻击。
只是想知道,是否有任何绕过保护机制可用而无需执行上述两项事件,只需在它仍然强制执行时通过禁用即可。很高兴听到那里是否有这样的机制,你能帮忙吗?
最佳答案
据我所知,避免缓冲区溢出的最佳方法是使用 100% 完全详尽的单元测试来检查处理任何大小和类型的缓冲区的任何函数。当然,这并不总是现实的。
"exhaustive" means that all possible cases are taken in account, no matter whether your application would ever generate all those specific cases at time you first write your code.
尽管有一些工具可以在该领域为您提供帮助。有些自动化程度很高,会自动生成单元测试。我从未尝试过其中任何一种,因此我不能保证其中任何一种,但如果您时间紧迫,那可能会有所帮助。
另一种比较有效的方法是针对您的代码运行静态分析器。 Code Coverity 是我过去使用的那个,但还有很多其他的。在大多数情况下,静态分析只会捕获您在堆栈上声明静态缓冲区的问题,如下所示:
char buf[256];
...
char a = buf[256]; // <- bug here, although not too bad
buf[256] = a; // <- bug here, could be bad, you're writing to the stack!
现在...在 Unix 下,您有两个缓冲区溢出问题。在大多数情况下,它会使您的系统崩溃。但是,如果黑客可以访问您的代码,他们可能会调用特定的系统函数(明确地说是内核函数)。在这种情况下,如果您的进程使用提升的用户(即最坏的情况:root)运行,则可能存在问题。那时黑客可能已经获得了一些权限,可以在未经您授权的情况下做更多的事情。要消除这种风险,您有两个主要解决方案:
- 使用 chroot 环境;如果您是 Linux 新手,这可能很难设置,但它适用于虚拟所有 Unices
- 使用 virtualbox 环境(或其他虚拟系统,如 qemu);获得这样的环境设置通常很容易,但如果您想自动生成新环境......有一个 API,它可能很乏味。
还有最后一种方法,但速度可能很慢。 CPU有一个MMU。您可以使用 MMU 来保护/取消保护内存,并确保每次读写都发生在分配的缓冲区中(在堆栈的情况下,帧缓冲区用于确保您在正确的窗口内。)可以想象,对于每次写入(可能还有多次读取),您都会收到一个中断,并且处理程序不小。调试有很多缓冲区溢出的软件是一个很好的工具/想法,但通常它不能用于生产。
不幸的是,默认情况下,这些选项都不是 g++ 套件的一部分。
关于c - 绕过地址随机化和堆栈粉碎保护 - 缓冲区溢出攻击的可行性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25822216/