Windows安全机制---异常处理保护:Safe机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37809075/article/details/82988124

Windows安全机制

微软关于内存保护机制

  • GS编译技术
  • SEH的安全校验机制
  • Heap Cookie,Safe Unlinking等一系列堆安全机制
  • DEP数据执行保护
  • ASLR加载地址随机
  • SEHOP SEH的覆盖保护

异常处理保护:SafeSEH

原理

SafeSEH需要编译器在编译PE文件时进行特殊支持才能发挥作用。在程序调用异常处理前,对调用的异常处理函数进行校验。同GS机制一样,在启用链接选项后,会将所有的异常处理函数提取出来,编入一张安全SEH表,并放到程序的映像里。在调用异常处理函数时与这个表进行匹配。
在这里插入图片描述
RtlIsValidHandler() 函数的校验流程

一些运行异常处理函数执行的情况:

  1. 若 DEP 关闭,则只要在当前模块的内存范围之外找一个跳板,就能转入 shellcode 执行
  2. 可以在加载模块中找一个没有启用 SafeSEH 的模块,用这个未启用 SafeSEH 模块里的指令作为跳板,转入 shellcode 执行
  3. 可以考虑清空 SafeSEH 表以欺骗 OS,或者将自己的函数地址注入到 SEH 表中。
  4. 如果SEH中的异常函数指针指向堆区,也可以绕过SafeSEH机制
绕过
攻击返回地址

前提:启用了SafeSEH未启用GS,直接覆盖返回地址

利用虚函数绕过

不涉及异常处理的事

从堆中绕过
#include<stdafx.h>
#include<stdlib.h>
#include<string.h>
char shellcode[]="";
void test(char * input)
{
	char str[200];
	strcpy(str,input);
	int zero=0;
	zero=1/zero;
}
void main()
{
	char * buf=(char *)malloc(500);
	__asmint 3
	strcpy(buf,shellcode);
	test(shellcode);
}

shellcode在堆中,只需要用在堆的shellcode的起始地址覆盖异常处理的函地址就可以绕过SafeSEH。

利用未启用SafeSEH模块绕过SafeSEH

原理

  1. 首先编译一个不使用SafeSEH的动态链接库NO_Safe.dll
  2. 而Safe.exe有溢出漏洞
  3. 使用NO_Safe.dll中的pop pop retn指令地址覆盖异常处理函数地址,执行完pop pop retn指令后会执行shellcode
  4. 制造除0的异常,进入异常处理,跳过本来的SafeSEH机制

插件
OllySSEH—查看加载模块的SafeSEH情况

  • /SafeSEH OFF:未启用
  • /SafeSEH ON:启用
  • NO SEH:不支持,即异常被忽略无法利用
  • Error:读取错误

步骤

  1. 在NO_Safe.dll中查找pop eax pop eax retn的指令序列
  2. 计算溢出字符串的起始位置距最近的异常处理函数指针的距离
  3. 因为在0x0012FE90到0x0012FEA0上被覆盖一些东西,需要一个jmp跳转。在这里插入图片描述

问题
1.shellcode中的一部分已经被跳板的地址和 __try{} 语句块需要的值给污染了,虽然这里这两处污染不会影响程序逻辑,但谨慎点总是好的。故而我们这里可以将 shellcode 起始位置处的 \x90\x90 改为一个简单的短跳转,短转移偏移量 = 0x0012FEA0 - 0x0012FE90 - 2 = 0x0E,因为 jmp 跳转基址是按照下一条指令来确定的,要减去两个字节的短转移指令长。
2.选择pop pop retn的原因是,在进入异常函数处理之时,栈的情况是 esp +8 的位置保存了处理该异常的 SEH 节点首地址 0x0012FE90 。
在通过 SEH 进行异常处理的时候,会先把当前 SEH 节点的首地址,也就是 nextSEH 的指针压入栈( 正常情况下,如果第一个节点无法处理该异常,转向下一节点),然后压进去两个现场相关的参数。所以两次 pop 之后,retn 指令赋值给 eip 的内容是当前 SEH 节点的首地址 0x0012FE90 了。

利用加载模块之外的地址绕过

原理
前提:所有加载模块都开启SafeSEH机制的情况
解决:当程序加载到内存中时,还有一些映射文件,SafeSEH是兼顾不到的。当异常处理函数指针指向这些地址时,可以不对其进行有效性验证。目的在这些地址找一些跳转指令。
指令:

pop pop retn
call/jmpdword ptr[esp+0x8]
call/jmpdword ptr[esp+0x14]
call/jmpdword ptr[esp+0x1c]
call/jmpdword ptr[esp+0x2c]
call/jmpdword ptr[esp+0x44]
call/jmpdword ptr[esp+0x50]
call/jmp dword ptr[ebp+0xc]
call/jmp dword ptr[ebp+0x24]
call/jmp dword ptr[ebp+0x30]
call/jmp dword ptr[ebp-0x4]
call/jmp dword ptr[ebp-0xc]
call/jmp dword ptr[ebp-0x18]

插件
OllyFindAddr在整个程序的内存空间搜索指令序列

步骤

  1. 上述的跳板指令都会跳到nextSEH,但是这个跳板指令的地址是0x00290B0B。因为包含0x00,所以在拷贝时会出现00截断。所以这个shellcode要放到前面
  2. 但因为nextSEH距离shellcode的起始位置距离较远,nextSEH的能覆盖的值只有2个字节,所以完不成长跳转
  3. 所以在nextSEH位置处放置一个短跳转,在短跳转到的位置放置一个长跳转到shellcode的位置3.所以在nextSEH位置处放置一个短跳转,在短跳转到的位置放置一个长跳转到shellcode的位置
    在这里插入图片描述
    其中回跳10个字节是8个字节+短跳转指令的2个字节
    长跳转213个字节

教训

  • 调试的时候尽量attach,在调试器里面会不一样
  • 在win7和xp环境中的video studio对于局部变量的定义位置要求不同
利用ActiveX控件绕过SafeSEH

前提
(1)有溢出漏洞的 ActiveX控件
(2)未启用 SafeSEH 的 Flash Player ActiveX 控件
(3)可以触发 ActiveX 控件中溢出漏洞的 POC 页面。
原理
Flash Player ActiveX在9.2.124之前的版本是不支持SafeSEH4,在这个控件中找到合适的跳板地址

猜你喜欢

转载自blog.csdn.net/m0_37809075/article/details/82988124
今日推荐