stack smash保护的检测及解决方案

逆向工程 C 缓冲区溢出 海湾合作委员会 堆栈保护器
2021-06-26 14:58:25

该视频https://youtube.com/watch?v=4HxUmbOcN6Y介绍了现代编译器如何使用堆栈 cookie 和函数保护堆栈溢出__stack_chk_fail

  1. 如何识别二进制文件是否具有堆栈粉碎保护?如果我__stack_chk_fail在 IDA 中看到 我能猜到这个二进制文件使用了堆栈 cookie(只有当这个二进制文件动态编译时,我才会看到这个函数)。

但是如果这个函数是静态编译的,我怎么识别呢?每个函数都会以if ... then abort else return或仅以从用户处获取缓冲区的函数结束

  1. 如果二进制使用堆栈粉碎保护并获得缓冲区不安全(例如gets),我该如何克服堆栈 cookie?还是没有办法返回到另一个函数?
2个回答
  1. 您可以确定某个函数是否受__stack_chk_fail. 它是用户自定义代码还是从库静态编译都没有关系。

  2. gets设计上是一个非常有问题的功能。不可能防止缓冲区溢出

例如:

int main()
{
    char buf[2000];
    gets(buf);
}

在这种情况下,main由于buf变量的原因,堆栈保护很可能在函数上

  1. 您可以将checksec用于动态链接的二进制文件。但是对于静态编译的二进制文件它会失败。您可以使用radare2为x86/64尝试这样的事情
  • i386
$ r2 -AAA -qq -c "pdf @main~gs" test
│           0x00000591      658b0d140000.  mov ecx, dword gs:[0x14]
│           0x000005b6      65331d140000.  xor ebx, dword gs:[0x14]
  • amd64
$ r2 -AAA -qq -c "pdf @main~fs" test
│           0x00400b5c      64488b042528.  mov rax, qword fs:[0x28]
│           0x00400b85      644833142528.  xor rdx, qword fs:[0x28]

在 x64 中 cookie 是从函数序言中加载fs:[0x28]和在 x86 中加载的gs:[0x14]你可以参考这里的答案