Canary栈保护机制

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/ALPS233/article/details/102736299

实验要求:调研 VC .net 或 GCC 4.*中的 Canary 技术实现, 弄懂原理并设计相应的实验例程进行测试,编制相应 报告。

实验环境
Windows 10, 编译器配置为 TDM-GCC 4.8.1 64-BIT Debug

实验主题
调研 GCC 4.*中的 Canary 技术:

原理
1、 在所有函数调用发生时,向栈帧内压入一个额外的随机 DWORD,这个随机数被称作
“canary”,用 IDA 反汇编时,又被称作“Security Cookie”。
2、 canary 位于 EBP 之前,系统还会在.data 的内存区域中存放一个 canary 的副本。
3、 当栈中发生溢出时,canary 将被首先淹没,之后才是 EBP 和返回地址。
4、 在函数返回之前,系统将执行一个额外的安全验证操作,称作 Security Check。 5、在 Security Check 过程中,系统将比较栈帧中原先存放的 canary 和.data 中副本的值,若两者不同,则说明栈中发生了溢出,系统将进入异常处理流程,函数不会正常返回。
如图所示,(图自 Dynamic Canary Randomization for Improved Software Security 论文)
在这里插入图片描述
GCC 4. 中的堆栈保护实现:*
Stack Guard 是第一个使用 Canaries 探测的堆栈保护实现,它于 1997 年作为 GCC 的一个扩展发布。最初版本的 Stack Guard 使用 0x00000000 作为 canary word。尽管很多人建议把 Stack Guard 纳入 GCC,作为 GCC 的一部分来提供堆栈保护。但实际上,GCC 3.x 没有实现任何的堆栈保护。直到 GCC 4.1 堆栈保护才被加入,并且 GCC4.1 所采用的堆栈保护实现并非 Stack Guard,而是 Stack-smashing Protection(SSP,又称 ProPolice)。 SSP 在 Stack Guard 的基础上进行了改进和提高。它是由 IBM 的工程师 Hiroaki Rtoh 开发并维护的。与 Stack Guard 相比,SSP 保护函数返回地址的同时还保护了栈中的 EBP 等信息。此外,SSP 还有意将局部变量中的数组放在函数栈的高地址,而将其他变量放在低地址。这样就使得通过溢出一个数组来修改其他变量(比如一个函数指针)变得更为困难。

个人思考

  1. 可以看出,canary code 作为 stack 的一个有效的保护机制,可以有效地防止通过缓冲区溢出覆盖函数返回地址,只牺牲程序的一小部分性能的代价。
  2. 通过随机不同函数返回地址前的 canary code 在程序每次运行时 Cookie 的种子都不相同,增强的随机性,增加破解 canary code 的难度。
  3. 局限性: a)根据原理看出 canary code 不能防止函数返回地址前的缓冲区溢出。 b)可利用未保护内存绕过 canary 机制,由于缓冲区不是 8 字节类型且大小不大于 4 个字节可通过缓冲区不大于 4 字节的栈溢出直接绕过,此部分不经过 canary 保护 c) 可能根据不同机器栈地址的增长机制或不同分配影响 canary code 的保护功能。

检验实验:编写缓存区溢出,覆盖函数返回地址的攻击代码:
在这里插入图片描述
打开 gcc canary 栈保护编译选项:-fstack-protector-all 运行结果,成功检测:
关闭 canary 栈保护选项后运行:发现不能成功检测,程序运行数秒后崩溃

猜你喜欢

转载自blog.csdn.net/ALPS233/article/details/102736299