栈溢出的几种保护机制

0x01.Stack Protector(栈保护)

  • 也称 cannary。

说明:当启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary

canary是一种用来防护栈溢出的保护机制。其原理是在一个函数的入口处,先从fs/gs寄存器中取出一个4字节(eax)或者8字节(rax)的值存到栈上,当函数结束时会检查这个栈上的值是否和存进去的值一致。

gcc中的使用:

-fstack-protector 启用保护,不过只为局部变量中含有数组的函数插入保护
-fstack-protector-all 启用保护,为所有函数插入保护
-fstack-protector-strong
-fstack-protector-explicit 只对有明确stack_protect attribute的函数开启保护
-fno-stack-protector 禁用保护.

0x02.NX(DEP)(堆栈不可执行)

说明:NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。

  • 等同于Windows下的DEP。

gcc编译器默认开启了NX选项,如果需要关闭NX选项,可以给gcc编译器添加-z execstack参数。

-z execstack / -z noexecstack (关闭 / 开启)

0x03.PIE(ASLR)(内存地址随机化)

  • Position-Independent-Executable

说明:标准的可执行程序需要固定的地址,并且只有被装载到这个地址才能正确执行,PIE能使程序像共享库一样在主存任何位置装载,这需要将程序编译成位置无关,并链接为ELF共享对象。

一般情况下NX和地址空间分布随机化(ASLR)会同时工作。

引入PIE的原因就是让程序能装载在随机的地址,从而缓解缓冲区溢出攻击。

Linux下开启关闭:

0 - 表示关闭进程地址空间随机化。

1 - 表示将mmap的基址,stack和vdso页面随机化。

2 - 表示在1的基础上增加栈(heap)的随机化。

#!bash
sudo -s 
echo 2 > /proc/sys/kernel/randomize_va_space

gcc: 

-no-pie / -pie (关闭 / 开启) 

0x04.RELRO

说明:设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。RELRO为” Partial RELRO”,说明我们对GOT表具有写权限。

扫描二维码关注公众号,回复: 9460116 查看本文章

开启与关闭:

-z norelro / -z lazy / -z now (关闭 / 部分开启 / 完全开启)
发布了63 篇原创文章 · 获赞 71 · 访问量 5504

猜你喜欢

转载自blog.csdn.net/ATFWUS/article/details/104552315