您的位置:首页 > Web前端

突破SafeSEH机制之一——利用堆绕过SafeSEH

2017-08-05 22:39 232 查看
文章是发在吾爱破解的,这里直接转过来了

我也是个新手,刚学漏洞调试,发现要学的东西太多,想要把漏洞学好,必须精通各类系统底层机制,汇编,PE等等等等太多太多,所以不可能把这些东西都学会了,再去调试漏洞,只能一步步慢慢从简单开始,另外也要学会忽略那些你现在所力不能及的地方,如果实在不懂,就跳过,可能到哪一天你忽然就明白了。所以这里,也是希望同学们想学习的不要被这个东西吓到,静下心来慢慢看,如果有不懂的,我可以倾尽所能告诉大家,我要是不懂,论坛里不是还有各种大神嘛,一起请教他们啊。

另外建议大家学习的时候,一定要亲力亲为,最好有自己的实验环境,搭个虚拟机调试一下,自己做过和看过是不一样的概念。
——————————————————————————————————割——————————————————————————————————

其实要说为了突破SEH机制,不需要深究太多原理,只要把SEH的基本原理,以及SEH链的结构整明白就行了,主要是那个链。(因为windows从没有公开过SEH的具体实现,都是靠大牛们逆向出来的)
SEH:structured Exception
Handling,结构化异常处理。是Windows上,Microsoft对C/C++程序语言做的语法扩展,用于处理异常事件的程序控制结构。
异常事件是打断程序正常执行流程的不在期望之中的硬件、软件事件。
硬件异常是CPU抛出的如“除0”、数值溢出等;软件异常是操作系统与程序通过RaiseException语句抛出的异常。
我们需要对SEH知道以下几点:
1、SEH是位于栈中的
2、栈中多个SEH通过链表指针在栈内串成单向链表,位于链表最顶端的SEH通过TEB(线程环境块)0字节处的指针标示(fs:[0])
3、如果源代码中使用了__try{}  __except{},编译器会向当前函数栈帧安装一个SEH
4、每个SEH包含两个DWORD指针:SEH链表指针和异常处理函数句柄(敲黑板敲黑板!!)———所以我们覆盖的是这个异常处理函数句柄
5、当离事故现场最近的异常处理函数处理不了的时候,顺着这个SEH链表依次尝试其他的异常处理函数,如果都没处理,就交给系统的顶层异常处理函数
SEH链表如下:


 

——————————————————————————————————手工分割线——————————————————————————————————————
SafeSEH
Windows XP sp2以后微软引入了著名的SafeSEH机制,在程序调用异常处理函数之前,会对要调用的异常处理函数进行有效性校验,当发现异常函数不可靠时,将终止异常处理函数的调用。
SafeSEH流程(我估计是这张图让大家蒙X了,是的,这张图是本帖最难的=。=)
其实没必要完全整明白,只需要知道,函数在跳向异常处理函数的时候,会对这个函数进行各种各样的有效性检查就够了。


 
突破思路:
那么有3种情况,系统可以允许异常处理函数执行:
1、异常处理函数位于加载模块内存范围之外,DEP关闭(下下次写这个)
2、异常处理函数位于加载模块内存范围之内,相应模块未启用SafeSEH(SafeSEH表为空),不是纯IL(下一次写这个)
3、异常处理函数位于加载模块内存范围之内,相应模块启用SafeSEH,异常处理函数地址包含在SafeSEH表中(放弃)

可以看到,我们突破SafeSEH的方法分为3种
1、排除DEP干扰,在加载模块内存范围外找一个跳板指令就可以转入shellcode执行
2、利用未启用SafeSEH模块中的指令作为跳板,转入shellcode执行
3、由于SafeSEH表加密,对于新手的我暂时不考虑了。

利用堆绕过SafeSEH
今天先利用一个简单的方法绕过SafeSEH
原理:
如果SEH中的异常处理函数指针指向堆区,即使安全校验发现了SEH不可信,仍然会调用已经被修改过的异常处理函数,因此可以将shellcode布置到堆区就可以执行了。
调试环境:
SP sp3
vs2008
Release版本
(有没有大神看到我的这个问题!!)DEP这个问题我想请教一下大家,书中要求关闭,我看我的vs里面没有关闭,也没有影响实验结果。如下图:


 
调试思路:
这次的比较简单
1、确定shellcode在堆中的地址->在malloc后面下一个int3中断,eax存放的是堆分配的地址,也即shellcode拷贝的首地址
2、确定SEH指针地址(确定覆盖地址),确定shellcode在栈中的首地址,计算shellcode大小
源程序:

[C] 纯文本查看 复制代码

?
第一步:
先将shellcode设置为200字节,调试后在确定还需要多远才能覆盖掉SEH指针
直接双击Release程序,OD开始调试:


 
得到堆地址:0x003929B8
第二步:  
运行到test中的strcpy,可以直接运行到循环结束,我是不想看汇编了,搜索FC68字符,直接定位shellcode在栈中的位置:0x0012FE8C
然后直接F9,查看SEH链情况:


 
SEH地址0x0012FFB0+4
所以能够得出shellcode大小为0x12FFB4-0x12FE8C+4=300

所以填充shellcode后,代码如下:

[C] 纯文本查看 复制代码

?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: