关于C#:缓冲区溢出的编译器艺术 | 珊瑚贝

The Art of Compiler on Buffer Overflow


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

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 编译参数,例如:

1
gcc fnostackprotector z execstack stackoverflow.c o stackoverflow

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

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

  • 您指的是哪个限制,为什么要绕过它?
  • 你想故意破坏堆栈吗?为什么?顺便说一句,您的代码有一个错误。您忘记了 NULL 终止 large_string。 strcpy() 将不限于 255 个字节。
  • 我认为您的意思是询问是否可以绕过 gcc 堆栈保护,如果可以,您应该编辑问题以使其清楚。
  • @NikosChantziaras 有了这个错误,它就更好了!
  • @JonathanLeffler 限制是我只能覆盖 eip 寄存器,并且在编译代码时必须设置 -fno-stack-protector 和 execstack 参数。如果不设置上面的两个参数,即使存在”strcpy(buffer,str)”问题,我也无法利用缓冲区溢出技巧
  • 您可以绕过它,但最有效的方法是查看生成的代码以了解它应该如何完成。
  • @JustForTest 这不是限制它是一个功能
  • @mux 完全正确!这就是我想要的。实际上,我的作业是我们需要在 C 代码中找到缓冲区溢出的古老性并加以利用(通过它运行 shellcode)。问题是,即使我在 strcpy() 函数中发现了问题,我也无法利用它,因为代码是使用 gcc 堆栈保护编译的。
  • 然后在没有保护的情况下编译它。问题出在哪里?
  • @mux 感谢您进行编辑以使问题更清楚;-)
  • @AlexeyFrunze 你能告诉我一个关于如何绕过我遇到的这个问题的 GCC 堆栈粉碎保护的解决方案吗?
  • 研究编译器的汇编输出以了解保护的工作原理。使用 -S 选项。
  • @NikosChantziaras问题是没有保护我无法编译它,我需??要绕过堆栈保护
  • @AlexeyFrunze 代码中的那个错误可能会使 strcpy 在返回之前崩溃,并且它还可能用意外的值(不是 \\’A\\’s)填充堆栈,你不认为它应该被修复吗?
  • @mux 是的,我应该添加一个笑脸。
  • 该示例代码中有一个错误,这只会使您的事情变得更加复杂,我对帖子进行了一些更改,我认为它们没有被提交。
  • @mux 你能再次发送提交吗?
  • @mux 为什么我们应该使用 strncpy() 而不是 strcpy()?
  • @JustForTest 因为您必须以空值终止或指定要从字符串复制的字节数,否则, strcpy 将继续复制字节,直到达到空字节或崩溃,并且永远不会返回,请参见上面的评论。


编译时应禁用堆栈保护:

1
gcc  fnostackprotector z execstack stackoverflow.c o stackoverflow

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

1
sudo sh c ‘echo 0 > /proc/sys/kernel/randomize_va_space’

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

编辑:

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

有没有办法绕过 SSP (StackSmashing Protection)/Propolice?

  • 有没有一种方法可以直接粉碎堆栈而无需任何参数设置?
  • 您的作业要求利用缓冲区溢出,我认为可以安全地假设禁用堆栈保护是可以接受的,否则问题实际上要复杂得多。
  • 是的,我想是这样。很好奇是否有办法绕过如此强大的堆栈保护。另一方面,即使代码中存在堆栈溢出漏洞,也可以说它对代码是安全的,因为堆栈中的代码在堆栈保护编译后无法运行。(此类问题的最坏情况是程序终止,黑客无法通过它运行shellcode)
  • 只是一个小的更正:您的 echo 命令将不起作用。它应该类似于 sudo sh -c ‘echo 0 > /proc/sys/kernel/randomize_va_space’。
  • @工作谢谢!我总是忘记这一点:)
  • @mux 为什么我不能简单地将 “0” 回显到 randomize_va_space 文件?
  • @JustForTest 您需要以 root 身份执行此操作并以 root 身份执行整个命令。
  • @mux 嗨,mux。你能给我你的电子邮件地址,我想更多地谈谈我的缓冲区溢出作业吗?


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

  • 你能为这种堆栈金丝雀举一个简单可行的例子吗
  • @JustForTest:恐怕不会。在您的示例中绕过堆栈金丝雀的唯一方法是用相同的值覆盖它。由于没有内存泄漏漏洞,唯一的方法就是暴力破解它,这可能是不可行的……


来源:https://www.codenong.com/13024977/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_8915.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?