目录
一 GCC 安全编译简介
操作系统提供了许多安全机制来尝试降低或阻止缓冲区溢出攻击带来的安全风险,例如 NX ASLR PIE CANARY FORTIFY RELRO 等手段,存在 NX 的话就不能直接执行栈上的数据,存在 ASLR 的话各个系统调用的地址就是随机化的等等。
GCC 在生成代码时,实际上已经提供了一些针对安全相关的编译选项。

OPT_CFLAGS += -fPIC -fPIE -fstack-protector-all -z now -D_FORTIFY_SOURCE=2 -fvisibility=hidden
操作系统提供了许多安全机制来尝试降低或阻止缓冲区溢出攻击带来的安全风险,例如 ASLR、NX 等等,这里简单介绍一些常见的使用项。
1 ASLR 地址随机
Address Space Layout Randomization, ASLR 地址空间布局随机化,该技术在 2005 年的 Kernel 2.6.12 版本中引入,会将进程的某些内存空间地址进行随机化来增大入侵者预测目的地址的难度,从而降低进程被成功入侵的风险。
当前 Linux、Windows 等主流操作系统都已经采用该项技术。
2 栈溢出保护
当启用栈保护后,函数开始执行的时候会先往栈里插入 Cookie 信息,函数返回时会验证 Cookie 信息是否合法,非法则停止运行。
攻击者在覆盖返回地址的时候往往也会将 Cookie 信息给覆盖掉,导致栈保护检查失败进而阻止 ShellCode 的执行,在 Linux 中将 Cookie 信息称为 Canary 。
GCC 在 4.2 版本中添加了 -fstack-protector 和 -fstack-protector-all 编译参数以支持栈保护功能,4.9 新增了 -fstack-protector-strong 编译参数让保护的范围更广,在编译时可以控制是否开启栈保护以及程度,例如:
-
$ gcc -o test test.c // 默认不开启 Canary 保护 -
$ gcc -fno-stack-protector -o test test.c // 禁用栈保护 -
$ gcc -fstack-protector -o test test.c // 启用堆栈保护,只为局部变量中含有 char 数组的函数插入保护代码 -
$ gcc -fstack-protector-all -o test test.c // 启用堆栈保护,为所有函数插入保护代码
3 FORTIFY
用于检查是否存在缓冲区溢出的错误,针对的是字符串、内存操作函数,例如 memcpy memset strcpy strcats snprintf 等等。
可以通过 _FORTIFY_SOURCE 宏定义检查的级别:
_FORTIFY

本文详细介绍了GCC编译器如何通过ASLR、栈溢出保护、FORTIFY及RELRO等技术增强代码安全性,包括动态库搜索路径管理和文件级加密实践。了解并应用这些技巧,能有效防止缓冲区溢出和恶意动态库攻击。

430

被折叠的 条评论
为什么被折叠?



