栈溢出的保护机制和利用方法

保护机制

Canary(栈保护)

栈溢出保护是一种缓冲区溢出攻击的缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址让shellcode能够执行。当开启栈保护后,函数开始执行时会先往栈里插入cookie信息,cookie常在ebp的上方,当函数返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候也会将cookie信息覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在linux中将cookie信息称为canary。
canary 简单高效, 就是插入一个值, 在 stack overflow 发生的高危区域的尾部, 当函数返回之时检测 canary 的值是否经过了改变, 以此来判断 stack/buffer overflow 是否发生。
gcc中使用Canary

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

NX/DEP(堆栈不可执行)

如果发生缓冲区溢出,返回地址被覆盖,就会导致控制流被劫持,漏洞就会被利用。
NX/DEP(数据执行保护)就是让栈上的地址不可被执行,将数据和代码区分开,让数据不可当作代码执行,,当程序溢出成功转入shellcode时,程序也会停下来不被执行。
gcc编译器默认开启了NX选项,如果需要关闭NX选项,可以给gcc编译器添加-z execstack参数
gcc -z execstack -o test test.c

PIE/ASLR(地址随机化)

ASLR表示地址空间层随机化。这种技术使共享库,堆栈和堆被占用的内存的地址随机化。这防止攻击者预测在哪里采取EIP,因为攻击者不知道他的恶意有效载荷的地址。攻击者难以找到shellcode地址,就算覆盖了返回地址,也不知道覆盖到了什么地方。ASLR在装载过程中对模块随机的装载,无法找到模块的位置和栈的位置,找不到返回地址。
PIE:位置独立的可执行区域(position-independent executables)。这样使得在利用缓冲溢出和移动操作系统中存在的其他内存崩溃缺陷时采用面向返回的编程(return-oriented programming)方法变得难得多。
liunx下关闭PIE
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space

RELRO

设置符号重定向表格,为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。

利用方法

栈溢出利用技术基础ROP
利用signal机制的的ROP技术:SROP
在没有binary的情况下利用得到BROP
劫持栈指针stack pivot,通常将栈指针劫持到其他不是栈的区域
利用动态链接绕过ASLR:ret2dl resolve,fake linkmap
Partial OverWrite:利用ASLR中低12位不会被随机化的特性来绕过ASLR的,也就是覆盖过程中只覆盖低12位从而绕过ASLR
当溢出位数不够时可以通过覆盖ebp和partial overwrite


栈溢出的保护机制和利用方法_第1张图片

你可能感兴趣的:(栈溢出的保护机制和利用方法)