堆栈防护和堆栈粉碎保护 - 金丝雀、内存

2023-12-22

我有一些关于 Stack Guard 和 SSP 保护的问题。第一个问题是关于 Stack Guard 及其三种类型的金丝雀(如果我没猜错的话)——终止符、随机和随机异或。

  1. 我想知道如何在 x86 Linux 系统上禁用 Stack Guard?我在某处读到,使用 gcc 编译时可以使用此命令-disable-stackguard-randomization,与此启用命令相同-enable-stackguard-randomization,两者都不起作用。如果需要的话,我的gcc版本是4.8.2。

  2. 关于堆栈防护的下一个问题,当我能够启用/禁用它时,我该如何设置,我想使用哪种类型的金丝雀?据我读到,默认情况下使用终结者金丝雀,对于随机我必须使用-enable-stackguard-randomization,但是随机异或怎么样? (或者使用 null 0x00000000)

  3. 现在关于 SSP(ProPolice),我知道,对于随机金丝雀,我必须使用它进行编译fstack-protector-all,但是终止符怎么样,默认情况下它和 Stack Guard 中的一样吗?

  4. 最后一个,我在哪里可以找到内存中的随机金丝雀?例如,我有这样的场景 - 编译的C程序,就像gcc -g example.c -o example -fstack-protector-all,随机金丝雀也是如此。假设,每次执行后我都能获得金丝雀的地址。所以我期望Canary = 0x1ae3f900.

    从不同的论文中,我得到了一些信息,金丝雀位于 .bss 段中。所以我使用 readelf 获取 .bss 段的地址:readelf -a ./example | grep bss。是080456c9。在 gdb 中,我设置了一些断点,以获取 canary 的地址,但是当我检查 .bss 地址时x/20x 0x080456c9,我看到的只是 0x00000000 地址,但是 金丝雀无处可去。另外,我查了一下__stack_chk_fail如果它不存在,但结果相同,我在那里看不到它。我从 PLT/GOT 获取 stack_chk_fail 的地址。


堆栈粉碎保护 (SSP) 是对 StackGuard 的改进。 SSP 首次在 gcc 4.1 中实现。

我想知道如何在 x86 Linux 系统上禁用 Stack Guard?

Use -fno-stack-protector禁用用户态 SSP。

The --disable-stackguard-randomization and --enable-stackguard-randomization是 glibc 源代码的构建选项。

当我能够启用/禁用它时,我该如何设置,哪种类型 我想用金丝雀吗?

据我所知,这在 gcc 中是不可配置的。从 glibc 2.10 开始,堆栈金丝雀是在一个名为的函数中生成的_dl_setup_stack_chk_guard。这是一部分its code https://github.com/lattera/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/sysdeps/generic/dl-osinfo.h#L24:

  if (dl_random == NULL)
    {
      ret.bytes[sizeof (ret) - 1] = 255;
      ret.bytes[sizeof (ret) - 2] = '\n';
    }
  else
    {
      memcpy (ret.bytes, dl_random, sizeof (ret));
      ret.num &= ~(uintptr_t) 0xff;
    }

dl_random保存辅助向量条目的地址AT_RANDOM,它是内核在创建进程时初始化的 16 字节随机值。如果您在未初始化的内核或模拟器上运行AT_RANDOM, 支票dl_random == NULL将为 true,并且使用的金丝雀是终止符值,其中第一个和第二个最高有效字节初始化为 255 并且\n, 分别。所有其他字节均为零。通常AT_RANDOM由内核初始化,因此至少 7 个有效字节AT_RANDOM被复制。金丝雀的最后一个字节设置为零。

因此,如果您想使用特定方法生成金丝雀,您可以更改此代码并构建您自己的 glibc。

作为替代方法,@PeterCordes 在评论中建议将您的金丝雀值写入内存位置%%fs:0x28(见下面的代码)在顶部main函数并在返回之前恢复运行时生成的金丝雀main.

现在关于SSP(ProPolice),我知道,对于随机金丝雀我必须编译 与“fstack-protector-all”,但是终止符怎么样,它与 默认情况下在 Stack Guard 中?

所有变体-fstack-protector选项使用 SSP。这些不会影响金丝雀的生成方式。

最后一个,如果你们有人能告诉我,在哪里可以找到随机的 记忆中的金丝雀。

金丝雀是在进程启动初期动态生成的;你不能使用readelf得到金丝雀。根据this https://www.elttam.com.au/blog/playing-with-canaries/文章中,您可以使用以下代码在编译 i386 时获取金丝雀:

int read_canary()
{
  int val = 0;
  __asm__("movl %%gs:0x14, %0;"
          : "=r"(val)
          :
          :);
  return val;
}

对于 x86_64:

long read_canary()
{
  long val = 0;
  __asm__("movq %%fs:0x28, %0;"
          : "=r"(val)
          :
          :);
  return val;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

堆栈防护和堆栈粉碎保护 - 金丝雀、内存 的相关文章

随机推荐