侧边栏壁纸
博主头像
胜星的博客博主等级

行动起来,活在当下

  • 累计撰写 23 篇文章
  • 累计创建 38 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

SafeSEH原理及绕过技术

胜星
2022-05-19 / 0 评论 / 0 点赞 / 135 阅读 / 3081 字

SafeSEH原理及绕过技术

设计SafeSEH保护机制的目的,以为了防止那种攻击者通过覆盖堆栈上的异常处理函数句柄,从而控制程序执行流程的攻击。

1、SafeSEH的保护原理

SafeSEH的基本原理很简单,即在调用异常处理函数之前,对要调用的异常处理函数进行一系列的有效性校验,如果发现异常处理函数不可靠(被覆盖了,被篡改了),立即终止异常处理函数的调用。不过SafeSEH需要编译器和系统双重支持,缺少一个则保护能力基本就丧失了。下面从两个方面来阐述怎样来实现SafeSEH。

2、SafeSEH机制的运行机理:

  1. 首先会检查异常处理链是否在当前程序栈中,如果不在,将停止对异常处理函数的调用。
  2. 检查异常处理函数指针是否指向当前程序栈,如果是,将停止对异常处理函数的调用。

当前两项检查都通过后,程序调用一个全新的函数RtlIsValidHandler(),来对异常处理函数进行有效性验证

20181101094707618

下面看一下RtlIsValidHandler的伪码:

BOOL RtlIsValidHandler(handler)
{
	if (handler is in an image)
	{
		       // 在加载模块的进程空间
		if (image has the IMAGE_DLLCHARACTERISTICS_NO_SEH flag set)
			return FALSE; // 该标志设置,忽略异常处理,直接返回FALSE
		if (image has a SafeSEH table) // 是否含有SEH表
		if (handler found in the table)
			return TRUE; // 异常处理handle在表中,返回TRUE
		else
			return FALSE; // 异常处理handle不在表中,返回FALSE
	if (image is a .NET assembly with the ILonly flag set)
	
		return FALSE; // .NET 返回FALSE
	
	// fall through
	}
    
	if (handler is on a non-executable page)
	{
	         // handle在不可执行页上面
		if (ExecuteDispatchEnable bit set in the process flags)
			return TRUE; // DEP关闭,返回TRUE;否则抛出异常
		else
			return ACCESS_VIOLATION; // enforce DEP even if we have no hardware NX
	}
    
	if (handler is not in an image)
	{
	
	         // 在加载模块内存之外,并且是可执行页
		if (ImageDispatchEnable bit set in the process flags)
			return TRUE; // 允许在加载模块内存空间外执行,返回验证成功
		else
			return FALSE; // don't allow handlers outside of images
	}
	// everything else is allowed
	return TRUE;
}

RtlIsValidHandler()函数对以下3种情况允许异常处理函数执行。
(1) 异常处理函数位于加载模块内存范围外,DEP关闭。
(2) 异常处理函数位于加载模块内存范围内,相应模块未启用SafeSEH(不存在SHE表),同时相应模块不是纯IL。
(3) 异常处理函数位于加载模块内存范围内,相应模块启用SafeSEH,异常处理函数在SHE表中。

3、怎样检测PE文件是否启用SafeSEH

前面介绍过数据目录里面的一个结构(IMAGE_LOAD_CONFIG_DIRECTORY),该结构的成员SEHandlerTable是指向合法SEH处理程序地址列表的指针,成员SEHandlerCount是数目。而IMAGE_LOAD_CONFIG_DIRECTORY这个结构体只有/SAFESEH选项设置了才存在,因此,就可以根据它来判断PE文件是否加了/SAFESEH链接选项。这个结构在PE中的偏移由PE附加头IMAGE_DATA_DIRECTORY 数组的第11项指定。

#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG  10  // Load Configuration Directory

4、绕过方法简介

  • 利用堆地址覆盖SEH结构绕过SafeSEH
    • 上面讲过,在禁用DEP的进程中,异常分发器允许SEH handler位于除栈空间之外的非映像页面。也就是说我们可以把shellcode放置在堆中,然后通过覆盖SEH跳至堆空间以执行shellcode,这样即可绕过SafeSEH保护。
  • 利用没有启用SafeSEH保护的模块绕过SafeSEH
    • 在介绍原理时讲过,在国内,目前大部分的PC都是安装的Windows XP,也就是说对于大部分Windows操作系统,其系统模块都没有受到SafeSEH保护,可以选用未开启SafeSEH保护的模块来利用,另外,现在还有很多VC6编译的软件,这些软件本身和自带的dll文件,都是可能没有SafeSEH保护的。这时就可以使用它里面的指令作为跳板来绕过SafeSEH。
  • 利用加载模块之外的地址绕过SafeSEH
    • 同样是根据SafeSEH的原理可知,对于加载模块之外的地址,SafeSEH同样是不进行有效性检测的(当然假设是DEP是关闭的,或者DEP已经被绕过)。
0

评论区