NX(DEP)、Canary(FS)、 RELRO(ASLR)、PIE编译选项
CANARY(栈保护溢出标志)
这个选项表示栈保护功能有没有开启。
栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖站上的返回地址来让shellcode能够得到执行。当启动栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当但会真正返回的时候会验证cookie信息是否让合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。栈上的cookie信息我们成为Canary。
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 //启用堆栈保护,为所有函数插入保护代码
ASLR地址随机
AddressSpaceLayoutRandomization ASLR地址空间布局随机化,该技术在2005年的Kernel2.6.12版本中引入,会将进程的某些内存空间地址进行随机化来增大入侵者预测目的地址的难度,从而降低进程被成功入侵的风险。
FORTIFY
用于检查是否存在缓冲区溢出的错误,针对的是字符串、内存操作函数、例如memcpy memset strcpy strcats snprintf等等。
PIE(代码段、数据段地址随机化)
-fpie -pie开启PIE 此时强度为1
-fPIE -pie开启PIE,此时为最高强度2
NX(堆栈禁止执行)
基本的原理是将数据所在内存页表示为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。
- -z execstack//禁用NX保护
- -z noexecstack//开启NX保护
RELRO
在Linux系统安全领域数据可以写的存储区就会是攻击的目标,尤其是存储函数指针的区域。所以在安全防护的角度来说尽量减少可写的存储区域对安全会有极大的好处。大概的实现就是由LINKER指定binary的一块经过dynamiclinker处理过relocation之后的区域为只读。
设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。
checksec
一个脚本来检测gcc编译出来的可执行文件,开启了哪些安全选项。
checksec --file=,后面再跟上二进制文件的绝对路径