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

时间:2015-01-18 20:47:47

标签: gcc random linux-kernel protection

我有一些关于Stack Guard和SSP保护的问题。第一个问题是关于Stack Guard及其三种类型的金丝雀,如果我是正确的 - 终结者,随机和随机XOR。

1)我想知道,如何在x86 Linux系统上禁用Stack Guard?在我读到的某个地方,使用此命令可以实现,使用gcc' -disable-stackguard-randomization '进行编译时,它与此命令相同对于启用' -enable-stackguard-randomization ',两者都不起作用。如果需要,我的gcc版本是4.8.2。

2)关于Stack guard的下一个问题,当我能够启用/禁用它时,我该如何设置,我想使用哪种类型的金丝雀?我读到的,默认情况下使用终结器金丝雀,随机我必须用' -enable-stackguard-randomization '编译,但随机XOR怎么样? (或使用null 0x00000000)

3)关于SSP(ProPolice),我知道,对于随机的金丝雀,我必须使用' fstack-protector-all ' ,但终结者怎么样,默认情况下与Stack Guard相同?

4)最后一个,如果有人,可以告诉我,我可以在内存中找到随机金丝雀。例如,我有这个场景 - 编译的C程序,如' gcc -g example.c -o example -fstack-protector-all ',所以使用随机的canaries。让我们说,我可以在每次执行后获得金丝雀的地址。所以期待,我有: Canary = 0x1ae3f900 。从不同的论文中,我得到一些信息,该金丝雀位于.bss段。所以我使用readelf获取.bss段的地址:' readelf -a ./example | grep bss '。它是080456c9。在gdb中我设置了一些断点,以获取金丝雀的地址,但是当我检查.bss地址x / 20x 0x080456c9时,我看到的只是0x00000000地址,但是 金丝雀无处可去。另外,我检查了 __ stack_chk_fail ,如果没有,但结果相同,我无法在那里看到它。我从PLT / GOT获得了stack_chk_fail的地址。

提前感谢您的回答和时间。

1 个答案:

答案 0 :(得分:2)

Stack Smashing Protection(SSP)是对StackGuard的改进。 SSP最初是在gcc 4.1中实现的。

  

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

使用-fno-stack-protector禁用用户界面SSP。

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

  

何时可以启用/禁用它,如何设置,哪种类型的   我想用金丝雀吗?

据我所知,这在gcc中是不可配置的。从glibc 2.10开始,堆栈Canary是在名为_dl_setup_stack_chk_guard的函数中生成的。这是its code的一部分:

  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,并且使用的canary是终止符值,其第一个和第二个最高有效字节被初始化为255和\n。所有其他字节均为零。通常AT_RANDOM由内核初始化,因此AT_RANDOM的至少7个有效字节被复制。金丝雀的最后一个字节设置为零。

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

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

  

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

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

  

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

金丝雀是在流程启动的早期动态生成的;您不能使用readelf来获得金丝雀。根据{{​​3}}的文章,在为i386进行编译时,可以使用以下代码来获取canary:

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;
}