首页
社区
课程
招聘
[原创]ExploitMe第四题,关于safeSEH和/GS技术
发表于: 2011-5-31 20:56 17554

[原创]ExploitMe第四题,关于safeSEH和/GS技术

2011-5-31 20:56
17554
ExploitMe大赛:http://bbs.pediy.com/showthread.php?t=133692

通过ExploitMe第四题为引,详细分析了/GS和safeSEH在汇编代码中的具体实现过程,并在最后给出几种绕过的办法。

Pre1,之前的一些分析:
    程序会根据输入的block size来确定每一分割块所占用的字节数,进而将读取的文件数据分割成固定大小的分割块,而其在读取文件内容后,会在读取的内容末尾添加终止符NULL,然后将读取的总字节数除以block size,得到的就是分割块块数。
    我们可以搜索常见的溢出函数,比如strcpy,strcat之类的函数分析程序对它的调用过程,从而发现可能存在的栈溢出。通过IDA搜索,很容易就发现了这样的一个可能的溢出点:


Pre2,实时的调试:
    我们随意在1.txt中添加一些字符串,使用Immdbg来调试运行,随意输入一个非零的block size来使程序执行到strcpy的调用处。

    由于程序由/GS编译开关生成,很难用覆盖返回地址的方法。故而采用覆盖SEH的方法,必须在GS_cookie检测之前产生异常来调用SEH hanler。本人想到的是除零异常或者是把字符串长度超过0x194,拷贝越过栈底,产生访问异常。

下面对调用strcpy的函数体进行,探究微软/gs和safeSEH在汇编级别的实现细节。

1,/GS技术的实际操作办法
/GS编译选项会在函数的开头和结尾添加代码来阻止对典型的栈溢出漏洞(字符串缓冲区)的利用。 当应用程序启动时,程序的cookie(4字节(dword),无符号整型)被计算出来(伪随机数)并保存在 加载模块的.data节中,在函数的开头这个cookie被拷贝到栈中,位于EBP和返回地址的正前方(位于返回地址和局部变量的中间)。
[buffer][cookie][savedEBP][savedEIP]

其中Scope table 的结构是
    struct _EH4_SCOPETABLE {
        DWORD GSCookieOffset;
        DWORD GSCookieXOROffset;
        DWORD EHCookieOffset;
        DWORD EHCookieXOROffset;
        _EH4_SCOPETABLE_RECORD ScopeRecord[1];
    };

    struct _EH4_SCOPETABLE_RECORD {
        DWORD EnclosingLevel;
        long (*FilterFunc)();
            union {
            void (*HandlerAddress)();
            void (*FinallyFunc)();
        };
    };
我们可以在内存窗口查看:

可以猜测,004010aa 正好是__except(EXCEPTION_EXECUTE_HANDLER)的指令地址,
而004010b0 正好是__except 开始的{}内的地址。

在函数的结尾处,程序会把这个cookie和保存在.data节中的cookie进行比较。
如果不相等,就说明进程栈被破坏,进程必须被终止。

在cookie检测函数里面,其实就是一个简单的判断:


2,safeSEH技术的实际操作办法

在调试exploit.exe时,异常发生时,我们按shift+F7就能进入异常刚发生的系统代码处,KiUserExceptionDispatcher()函数的开始处。(类此的软件异常是通过直接或者间接调用内核服务NtRaiseException而产生的。而用户态中可以通过RaiseException API,或者Try-catch等高级语言来调用这个内核服务,而通过RaiseException来登记软件异常的过程可以简单表述如下:RaiseException在初始化一个EXCEPTION_RECORD结构体之后,开始调用NTDLL中的 RtlRaiseException; RtlRaiseException在初始化CONTEXT结构体之后,开始调用内核中NtRaiseException, NtRaiseException再调用另外一个内核函数KiRaiseException。接下来KiRaiseException会调用 KiDispatchException开始异常的分发)

这个时候其实系统已经帮你做了很多工作了;比如EXCEPTION_POINTERS就在栈顶,如下图:

这里我们给上KiUserExceptionDispatcher函数的伪代码:

KiUserExceptionDispatcher( PEXCEPTION_RECORD pExcptRec, CONTEXT * pContext )  
{  
    DWORD retValue;   
    // 注意:如果异常被处理,那么 RtlDispatchException 函数就不会返回  
    if ( RtlDispatchException( pExceptRec, pContext ) )  
        retValue = NtContinue( pContext, 0 );  
    else  
        retValue = NtRaiseException( pExceptRec, pContext, 0 );   
    EXCEPTION_RECORD excptRec2;  
    excptRec2.ExceptionCode = retValue;  
    excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;  
    excptRec2.ExceptionRecord = pExcptRec;  
    excptRec2.NumberParameters = 0;   
    RtlRaiseException( &excptRec2 );  

}  

我们safeSEH检测的工作就在RtlDispatchException中完成。

当异常发生时,异常分发器创建自己的栈帧。它会把SEH Handler成员压入新创的栈帧中(作为函数起始的一部分)在SEH结构中有一个域是Establisher Frame 。这个域指向异常注册记录 (next  SEH )的地址并被压入栈中,当一个例程被调用的时候被压入的这个值都是位于ESP+8的地方。

我们经常用pop pop ret 串的地址覆盖SE Handler来达到跳转栈上的目的:
-第一个pop将弹出栈顶的4 bytes
-接下来的pop继续从栈中弹出4bytes
-最后的ret将把此时ESP所指栈顶中的值(next SEH的地址)放到EIP中。

3,绕过方法

绕过/GS的方法基本上都通过覆盖SEH来实现,在cookie未检测之前实现溢出。而覆盖SEH有两种,一种是2中所述;直接用pop|pop|retn指令地址来覆盖SEH Handler,从而跳到栈上执行。另外一种就是硬编码shellcode的开始地址,植入SEH Handler,在异常处理函数执行时,直接执行shellcode。

    a,可以用pvefindaddr插件跑,来获取加载模块之外的地址

    b,可以采用shellcode地址硬编码,当然不能用栈地址里面的shellcode。搜索我们发现ctype.nls里面有1.txt文件内容的复制品,我们硬编码地址设成这个模块里的shellcode的起始地址,就能绕过safeSEH。缺点就是通用性极差。

    c,在这里强调一点,插件搜索出来的结果可能是不全的,也可能存在其他的地址上有pop|pop|retn满足条件。比如本例可以发现:

在高地址处,不受safeSEH的限制。

4,小结

     /GS和safeSEH都有较成熟的绕过机制,甚至有插件来进行傻瓜式的搜索。但是我们仍然需要详细了解微软设置这两个机制的详细实现过程,需要我们耐心的调试分析。最后,插件不是万能的。方法知道的越多才会越灵活。懂得原理才是王道!

[课程]Android-CTF解题方法汇总!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (23)
雪    币: 207
活跃值: (26)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
讲解的很详细~不过这精华有点水吧
2011-5-31 22:04
0
雪    币: 393
活跃值: (150)
能力值: (RANK:110 )
在线值:
发帖
回帖
粉丝
3
楼上教训的是。吾本是坊间一菜鸟,偶有一文,贻笑大方。但是遍观看雪,似乎从汇编分析/GS和safeSEH实现过程的帖子亦是寥寥。
2011-6-1 08:09
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
顶礼膜拜wingdbg大牛,①精华呢
2011-6-1 08:38
0
雪    币: 51
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我觉得水是有点的。但是论坛应该鼓励新人嘛。
2011-6-1 09:20
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
水你妹,,你们都不分享,大牛分享出来,你们就知道水,有本事你也水啊。什么叫不水?是不是发个0day你也觉得水啊。在kanxue这类文章很少有人发了,很赞楼主的共享精神。
专批那些装x人士。
2011-6-1 09:28
0
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
分析的很细致详尽,支持!
至于有些红眼病人,不必在意。
2011-6-1 09:38
0
雪    币: 1098
活跃值: (193)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
8
楼主的图做得很不错,请问用什么软件做的?
2011-6-1 10:55
0
雪    币: 393
活跃值: (150)
能力值: (RANK:110 )
在线值:
发帖
回帖
粉丝
9
snagit截图工具
2011-6-1 11:08
0
雪    币: 437
活跃值: (110)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
顶礼膜拜
2011-6-1 12:21
0
雪    币: 1137
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
11
写的很好,学习:)
2011-6-1 13:11
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
top
12
学习学习了,很少人分析SEH和GS实现
2011-6-1 14:10
0
雪    币: 3171
活跃值: (76)
能力值: (RANK:250 )
在线值:
发帖
回帖
粉丝
13
顶楼主,虽然技术简单 但是用心调试了,肯定有人会从中得到很多启示。
另外问下:咋叫不水啊?1楼那位您可否放个不水的主题我们学习膜拜下。
我觉得“精华”鼓励的不仅仅是高超的技术,更是鼓励一种认真、共享的精神吧。
2011-6-1 22:11
0
雪    币: 207
活跃值: (26)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
看来引来一片骂声啊!我没有否定LZ研究,专研的精神~~我也没高超的技术,连菜鸟都不算。
2011-6-1 22:29
0
雪    币: 123
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
其实这篇精不水,不过现在看雪很多水的精了...
2011-6-1 23:51
0
雪    币: 433
活跃值: (1875)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
16
水不水并不重要,重要是那个求知的过程,自己动手调试过的东东比任何空头理论要来得实在。
2011-6-2 00:13
0
雪    币: 393
活跃值: (150)
能力值: (RANK:110 )
在线值:
发帖
回帖
粉丝
17
多谢泉哥和snowdbg等大哥的鼓励。我只是突然想学习一下微软/gs和safeSEH的实现细节,正好exploitme第四题与此相关,就做的时候顺便把它分析了。觉得讲的还算详细通俗,就拿出来分享了。没想到引来这么大风波。人与人想法不同,如果有人觉得不爽我表示道歉。
总之,这只是我自己的知识归纳。觉其有用者取之,识其无用者弃之,仅此而已。
2011-6-2 08:16
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
18
学习学习!
2011-6-2 08:24
0
雪    币: 7008
活跃值: (1040)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
支持分享精神,虽然技术不是特别好,但是精神很好!支持!
2011-6-2 22:02
0
雪    币: 23
活跃值: (31)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
懂得原理才是王道
2011-6-4 09:26
0
雪    币: 129
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
谢谢分享  学习了
2011-6-4 11:39
0
雪    币: 53
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
谢谢分享,
2011-6-18 15:22
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
图文并茂,分析不错,顶起
2011-6-20 09:08
0
雪    币: 42
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
重要的是这个过程。。。感谢楼主分享!
2011-6-21 16:35
0
游客
登录 | 注册 方可回帖
返回
//