【问题标题】:The Art of Compiler on Buffer Overflow缓冲区溢出的编译器艺术
【发布时间】:2012-10-23 06:52:06
【问题描述】:

现代编译器 GCC 非常强大,它甚至可以在编译阶段防止缓冲区溢出,从而使操作系统无法在堆栈空间上运行代码。

例如:

void function(char *str) 
{
   char buffer[16];

   strncpy(buffer, str, 256);
}

void main() 
{
  char large_string[256];
  int i;

  for( i = 0; i < 256; i++)
    large_string[i] = 'A';

  function(large_string);
}

获得魔法 0x41414141 的唯一方法是设置 GCC 编译参数,例如:

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

(我在 ubuntu 10.04 x86 lucid 32bits box 上测试过)

有什么办法可以绕过 GCC 堆栈粉碎保护?

【问题讨论】:

  • 你指的是哪个限制,为什么要绕过它?
  • 您想故意破坏堆栈吗?为什么?顺便说一句,您的代码有一个错误。你忘了 NULL 终止 large_string。 strcpy() 不仅限于 255 个字节。
  • 我认为您的意思是询问是否可以绕过 gcc 堆栈保护,如果可以,您应该编辑问题以使其清楚。
  • @NikosChantziaras 有了这个 bug 就更好了!
  • 然后在没有保护的情况下编译它。问题出在哪里?

标签: c ubuntu stack-overflow shellcode


【解决方案1】:

编译时应禁用堆栈保护:

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

您可能还想禁用地址空间随机化 (ASLR):

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

现在可以试试缓冲区溢出了,推荐阅读Smashing the Stack for Fun and Profit

编辑:

就像我在评论中所说的那样,可以安全地假设在您的分配中禁用堆栈保护是可以接受的,但是,如果您想绕过堆栈保护,您应该检查 SOF 中的相关问题canaries 喜欢这样的问题:

Is there any way to bypass SSP (StackSmashing Protection)/Propolice?

【讨论】:

  • 有没有什么方法可以不用任何参数设置直接砸栈?
  • 您的作业要求利用缓冲区溢出,我认为可以安全地假设禁用堆栈保护是可以接受的,否则问题实际上要复杂得多。
  • 是的,我想是的。很好奇是否有办法绕过如此强大的堆栈保护。另一方面,即使代码中存在堆栈溢出漏洞,也可以说它对代码是安全的,因为堆栈中的代码在堆栈保护编译后无法运行。(此类问题的最坏情况是程序终止,黑客无法通过它运行shellcode)
  • 只是一个小修正:您的echo 命令将不起作用。它应该类似于sudo sh -c 'echo 0 &gt; /proc/sys/kernel/randomize_va_space'。
  • @Job 谢谢!我总是忘记这一点:)
【解决方案2】:

当然有一些方法可以绕过堆栈粉碎保护(称为堆栈金丝雀),尽管在您的示例中并不容易。有关堆栈金丝雀的一些弱点,请参阅我的回答 here。

【讨论】:

  • 您能否为此类堆栈金丝雀提供一个简单可行的示例
  • @JustForTest:恐怕不会。在您的示例中绕过堆栈金丝雀的唯一方法是用相同的值覆盖它。由于没有内存泄漏漏洞,唯一的方法就是暴力破解它,这可能是不可行的......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 2017-06-26
  • 2013-11-06
  • 2013-04-11
相关资源
最近更新 更多