WINDOWS和LINUX的内存防护机制

一、windows下的内存保护机制

0x00、二进制漏洞

二进制漏洞是可执行文件(PE、ELF文件等)因编码时考虑不周,造成的软件执行了非预期的功能。二进制漏洞早期主要以栈溢出为主。

我们都知道在C语言中调用一个函数,在编译后执行的是CALL指令,CALL指令会执行两个操作:

(1)、将CALL指令之后下一条指令入栈。
(2)、跳转到函数地址。

函数在开始执行时主要工作为保存该函数会修改的寄存器的值和申请局部变量
空间,而在函数执行结束时主要的工作为:

(1)、将函数返回值入eax
(2)、恢复本函数调用前的寄存器值
(3)、释放局部变量空间
(4)、调用ret指令跳转到函数调用结束后的下一条指令(返回地址)

栈溢出指的是局部变量在使用过程中,由于代码编写考虑不当,造成了其大小超出了其本身的空间,覆盖掉了前栈帧EBP和返回地址等。由于返回地址不对,函数调用结束后跳转到了不可预期的地址,造成了程序崩溃。

早期的栈溢出漏洞利用就是将函数的返回地址覆盖成一个可预期的地址,从而控制程序执行流程触发shellcode。漏洞发生时,能控制的数据(包含shellcode)在局部变量中,局部变量又存在于栈上面,因此要想执行shellcode必须将程序执行流程跳转到栈上。

shellcode存好了,返回地址也可控,如果将返回地址改写为shellcode地址就OK了,可偏偏栈的地址在不同环境中是不固定的。

这时候有聪明的程序员发现了一条妙计,栈地址不固定,但是程序地址是固定的。通过在程序代码中搜索jmp esp指令地址,将返回地址改成jmp esp的地址,就可以实现控制程序执行流程跳转到栈上执行shellcode。

附上一张函数调用过程中的栈空间分布图:
这里写图片描述

0x01、启用GS选项

启用GS选项是在编辑器中可以启用的一项选择。

启用GS选项之后,会在函数执行一开始先往栈上保存一个数据,等函数返回时候检查这个数据,若不一致则为被覆盖,这样就跳转进入相应的处理过程,不再返回,因此shellcode也就无法被执行,这个值被称为“Security cookie”。

感兴趣的同学可以编写一个DEMO启用GS后编译,使用IDA便可以看软件到调用Check_Security_Cookie()检查栈是否被覆盖。

可是他们忽略了异常处理SEH链也在栈上因此可以覆盖SEH链为jmp esp的地址,之后触发异常跳转到esp执行shellcode。

有关SEH链的的技术可以参考这里

0x02、SafeSEH

SafeSEH是在程序编译的时候,就将所有的异常处理函数进行注册。凡是执行过程中触发异常后,都要经过一个检验函数,检查SEH链指向的地址是否在注册的列表中。

可是再检验函数的逻辑中阻止执行的情况只有在SEH链指向模块(exe、dll)地址的情况下,如果SEH链指向的地址不在这些模块中,那就可以执行了。因此在程序中非模块的数据空间找到jmp esp,比方说nls后缀的资源文件等。或者是在支持JS脚本的软件中(浏览器等),通过脚本申请堆空间写入shellcode。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值