SafeSEH原理及绕过技术浅析
作者:magictong时间:2012年3月16日星期五
摘要:主要介绍SafeSEH的基本原理和SafeSEH的绕过技术,重点在原理介绍。
关键词:SafeSEH;绕过技术;异常处理
目录
前言
SafeSEH的保护原理
(1) 二进制层面
(2) 系统层面
怎么关掉编译器的SafeSEH支持
怎样检测一个PE文件是否启用了SafeSEH
绕过方法简介
参考文献
前言
设计SafeSEH保护机制的目的,以为了防止那种攻击者通过覆盖堆栈上的异常处理函数句柄,从而控制程序执行流程的攻击。
自Windwos XP SP2之后,微软就已经引入了SafeSEH技术。不过由于SafeSEH需要编译器在编译PE文件时进行特殊支持才能发挥作用,而xpsp2下的系统文件基本都是不支持SafeSEH的编译器编译的,因此在xpsp2下,SafeSEH还没有发挥作用(VS2003及更高版本的编译器中已经开始支持)。
从Vista开始,由于系统PE文件基本都是由支持SafeSEH的编译器编译的,因此从Vista开始,SafeSEH开始发挥他强大的作用,对于以前那种简单的通过覆盖异常处理句柄的漏洞利用技术,也就基本失效了。
SafeSEH的保护原理
SafeSEH的基本原理很简单,即在调用异常处理函数之前,对要调用的异常处理函数进行一系列的有效性校验,如果发现异常处理函数不可靠(被覆盖了,被篡改了),立即终止异常处理函数的调用。不过SafeSEH需要编译器和系统双重支持,缺少一个则保护能力基本就丧失了。下面从两个方面来阐述怎样来实现SafeSEH。
(1)二进制层面
首先我们先看看编译器做了些什么事情(通过启用链接选项/SafeSEH即可使编译出来的二进制文件具备SafeSEH功能,微软VS2003及以后的编译器已经默认支持)。在编译器生成二进制IMAGE的时候,把所有合法的SEH函数的地址解析出来,在IMAGE里生成一张合法的SEH函数表,用于异常处理时候进行严格的匹配检查。可以使用VC下面的dumpbin工具查看一个二进制文件的config信息,这样调用dumpbin /loadconfig file_all_path_filename。
输出的可能是下面这样(注:tttt.exe使用vs2005编译):
Dump of file H:\Prj_N\tttt\Release\tttt.exe
www.zzzyk.com
File Type: EXECUTABLE IMAGE
Section contains the following load config:
00000048 size
0 time date stamp
0.00 Version
0 GlobalFlags Clear
0 GlobalFlags Set
0 Critical Section Default Timeout
0 Decommit Free Block Threshold
0 Decommit Total Free Threshold
00000000 Lock Prefix Table
0 Maximum Allocation Size
0 Virtual Memory Threshold
0 Process Heap Flags
0 Process Affinity Mask
0 CSD Version
0000 Reserved
00000000 Edit list
00403018 Security Cookie
00402360 Safe Exception Handler Table
1 Safe Exception Handler Count
Safe Exception Handler Table
Address
--------
004018A1 __except_handler4
Summary
1000 .data
1000 .rdata
1000 .rsrc
1000 .text
注意里面加粗标红的部分,这就是该二进制文件里面的SEH异常处理函数地址表。上面的输出实际上涉及如下的一个结构,是保存在二进制文件里面的一份配置表:
#include <windows.h>
extern DWORD_PTR __security_cookie; /* /GS security cookie */
/*
* The following two names are automatically created by the linker for any
* image that has the safe exception table present.
*/
extern PVOID __safe_se_handler_table[]; /* base of safe handler entry table */
extern BYTE __safe_se_handler_count; /* absolute symbol whose address is
the count of table entries */
typedef struct {
DWORD Size;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD GlobalFlagsClear;
DWORD GlobalFlagsSet;
DWORD CriticalSectionDefaultTimeout;
DWORD DeCommitFreeBlockThreshold;<
补充:综合编程 , 安全编程 ,