【问题标题】:How to turn off gcc compiler optimization to enable buffer overflow如何关闭 gcc 编译器优化以启用缓冲区溢出
【发布时间】:2011-01-21 08:48:49
【问题描述】:

我正在开发一个homework problem,它需要禁用编译器优化保护才能使其工作。我在 ubuntu linux 上使用 gcc 4.4.1,但不知道哪些标志是正确的。我意识到它依赖于架构 - 我的机器使用 32 位 Intel 处理器运行。

谢谢。

【问题讨论】:

    标签: c gcc buffer-overflow compiler-optimization


    【解决方案1】:

    您无需禁用 ASLR 即可进行缓冲区溢出!虽然启用了 ASLR (kernel_randomize_va_space = 2),但除非编译的可执行文件是 PIE,否则它不会生效。所以除非你用-fPIC -pie标志编译你的文件,否则ASLR不会生效。

    我认为只用-fno-stack-protector 禁用金丝雀就足够了。 如果要检查 ASLR 是否工作(必须设置与位置无关的代码),请使用:

    hardening-check executable_name
    

    【讨论】:

      【解决方案2】:

      呃,到目前为止,所有的答案都是错误的,因为 Rook 的答案是正确的。

      输入:

      echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
      

      接着是:

      gcc -fno-stack-protector -z execstack -o bug bug.c
      

      禁用 ASLR、SSP/Propolice 和 Ubuntu 的 NoneXec(放置在 9.10 中,并且工作起来相当简单,请参阅 mprotect(2) 将页面映射为可执行文件和 jmp 的技术)应该会有所帮助,但是这些“安全功能”绝不是万无一失的。如果没有 `-z execstack' 标志,页面将具有不可执行的堆栈标记。

      【讨论】:

      • 您没有阅读这些人的链接。如果你这样做了,你就会知道他正在尝试执行 g(),这是一个编译到二进制文件中的函数。这是一个函数的地址。当您尝试在堆或堆栈上执行 shellcode 时,NX 位就会发挥作用,他的攻击要简单得多。
      • 我同意其他人都是完全错误的,很明显我们是唯一两个利用缓冲区溢出的人。但是我仍然认为我的答案更正确。
      • 嗯,刚刚看到链接——我认为这只是另一个通用的,你是对的。我道歉。
      • 我知道这是一篇旧帖子,但您不能将 sudo 与 > echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
      【解决方案3】:

      在较新的发行版上(截至 2016 年),PIE 似乎默认启用,因此您需要在编译时明确禁用它。

      这里有一些命令的小结,对于在本地玩一般的缓冲区溢出练习很有帮助:

      禁用金丝雀:

      gcc vuln.c -o vuln_disable_canary -fno-stack-protector
      

      禁用 DEP:

      gcc vuln.c -o vuln_disable_dep -z execstack
      

      禁用 PIE:

      gcc vuln.c -o vuln_disable_pie -no-pie
      

      禁用上面列出的所有保护机制(警告:仅用于本地测试):

      gcc vuln.c -o vuln_disable_all -fno-stack-protector -z execstack -no-pie
      

      对于 32 位机器,您还需要添加 -m32 参数。

      【讨论】:

      • -m3264 位机器 上构建32 位代码 时需要。此外,您可以使用-fno-pie 让编译器生成不会干扰PIE 的asm,以及使用-no-pie 让它不将该机器代码链接到PIE。对于 32 位模式,-fno-pie 将显着简化 asm,去除像 call __x86.get_pc_thunk.bx 这样的废话。对于 64 位模式,大多数情况下只允许 mov-immediate 而不是 RIP-relative LEA 用于静态地址,以及 more efficient indexing of static arrays
      【解决方案4】:

      这是个好问题。为了解决这个问题,您还必须禁用 ASLR,否则 g() 的地址将无法预测。

      禁用 ASLR:

      sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'
      

      禁用金丝雀:

      gcc overflow.c -o overflow -fno-stack-protector
      

      禁用金丝雀和 ASLR 后,它应该是像 Smashing the Stack for Fun and Profit 中描述的直接攻击

      这里是 ubuntu 中使用的安全功能列表:https://wiki.ubuntu.com/Security/Features 您不必担心 NX 位,g() 的地址将始终位于内存的可执行区域中,因为它位于 TEXT 内存中部分。只有当您尝试在堆栈或堆上执行 shellcode 时,NX 位才会发挥作用,这不是此分配所必需的。

      现在去破坏那个EIP

      【讨论】:

      • 谢谢,我会这样做的 :) 哦 - 我如何重新启用保护以解除我的机器损坏?.. 我的猜测是 sudo echo 1 > /proc/sys/kernel /randomize_va_space
      • @sa125 是的,它就是这样重新启用的。事实上,这就是您在系统运行时打开和关闭其他内核模块的方式;)
      • 似乎值得指出的是,在我的系统上,randomize_va_space 默认为 2,而不是 1,因此如果您打算重新启用它,值得事先检查。
      • 实际上 g() 的地址很可能不会被 ASLR 随机化,因为它是主二进制文件的一部分。仅当您使用 -PIE 编译二进制文件时,它才会被随机化。
      • 现代 Linux 发行版 configure GCC to build PIE executables by default、@RobertLarsen(以及未来的读者)。您可以使用gcc overflow.c -fno-stack-protector -fno-pie -no-pie 来制作传统的 ELF 可执行文件,而不是共享对象。 (那么您不必为系统范围内的非堆栈段或此可执行文件禁用 ASLR,BTW 是 GDB 所做的。根本不需要禁用系统范围。)
      【解决方案5】:

      我不会引用整个页面,但完整的优化手册可以在这里找到:http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Optimize-Options.html#Optimize-Options

      从它的声音你至少想要-O0,默认值,并且:

      -fmudflap -fmudflapth -fmudflapir

      对于支持它的前端(C 和 C++),检测所有风险 指针/数组解引用 操作,一些标准库 字符串/堆函数,以及其他一些 相关的结构 范围/有效性测试。模块如此 仪表应该不受 缓冲区溢出,无效堆使用, 和其他一些 C/C++ 类 编程错误。这 仪器依赖于一个单独的 运行时库 (libmudflap),其中 将被链接到一个程序中,如果 -fmudflap 在链接时给出。检测的运行时行为 程序由控制 MUDFLAP_OPTIONS 环境变量。 请参阅环境 MUDFLAP_OPTIONS=-help a.out 供其选择。

      【讨论】:

        【解决方案6】:

        试试-fno-stack-protector 标志。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-05
          • 2017-04-08
          • 1970-01-01
          • 1970-01-01
          • 2012-06-18
          • 1970-01-01
          相关资源
          最近更新 更多