c - 使用金丝雀值的堆栈损坏检测
问题描述
我正在阅读一本描述能够检测堆栈何时损坏的防御的教科书。书上说:
最近版本的 gcc 将一种称为堆栈保护器的机制合并到生成的代码中以检测缓冲区溢出。这个想法是在任何本地缓冲区和堆栈状态的其余部分之间的堆栈帧中存储一个特殊的金丝雀值,如下图所示:
这个金丝雀值,也称为保护值,是在每次程序运行时随机生成的,因此攻击者没有简单的方法来确定它是什么。在恢复寄存器状态并从函数返回之前,程序会检查金丝雀是否已被此函数的某些操作或它调用的操作更改。如果是这样,程序将因错误而中止。
我明白了,但我仍然认为这个设计存在缺陷。是的,攻击者可能无法确定 canary 的值是什么,但攻击者知道 canary 的大小(8 字节),因此攻击者可以操纵指针绕过栈中金丝雀所在的这 8 字节区域,然后覆盖返回地址,所以金丝雀实际上什么都不保护,我的理解是否正确?
解决方案
如果攻击者有任意写入,那么是的,金丝雀是无用的。事实上,任意写入可以使金丝雀失效的方法有很多,包括覆盖__stack_chk_fail
(覆盖金丝雀时调用的函数)的 GOT 条目,或者只是不覆盖金丝雀。然而,任意写入并不总是可获得的。它通常仅在存在格式字符串漏洞时发生。当只有缓冲区溢出时,要写入金丝雀之后的地址,您必须写入该地址之前的地址,其中包括金丝雀。这意味着用缓冲区溢出覆盖返回地址的唯一合理方法是猜测金丝雀或通过另一个漏洞泄漏它。
推荐阅读
- css - 仅使用 CSS 的 Google Chrome 下载文件
- ace-editor - Ace 编辑器多个光标
- c++ - 编写一个将 LLVM IR 文件作为命令行参数的程序
- vuejs2 - 在 Vue2 中以另一种方法检索 e.target.files
- java - 使用 Xero 的 Java SDK 支持多个私有应用的身份验证?
- android - 我想用 FCM 在 android studio 中创建音频呼叫应用程序是否可以
- android - 未定义对“cnss_get_platform_cap”的引用
- nginx - 只有当主进程以超级用户权限运行时,“user”指令才有意义
- node.js - 在mongodb中保存小数点后4位
- javascript - 我想知道如何修复触摸友好的滑块