<<0 day 安全:软件漏洞分析技术>>
page 215 9.2 百密一疏的 S.E.H 验证
通过第7章对异常机制的学习,我们知道改写 S.E.H 中指向异常处理函数的指针已经成为 windows 平台下漏洞利用的经典手法.
在 windows xp sp2 和 windows 2003 中,为了抵御黑客们对 S.E.H 疯狂的攻击,微软引入了著名的 S.E.H 校验机制.
(1)
当系统向栈桢中安装 S.E.H 的时候,还会在栈以外的地方记录 S.E.H 副本.
(2)当异常发生后,系统首先检查栈桢中的 S.E.H 与栈外的 S.E.H 副本是否一致.
(3)如果两个 S.E.H 不匹配,则认为当前的 S.E.H 已经不可信,不去调用其所指的异常处理函数.
这种安全校验能够有效挫败通过改写 S.E.H 中异常处理函数指针而获得控制权的攻击.现在您应该明白在第7章中我们为什么建议在windows 2000平台上进行实验了吧.
但是这种安全机制存在一个严重的缺陷------如果 S.E.H 的函数指针指向
堆区,即使安全校验发现了 S.E.H 已经不可信,依然会调用其已经被修改过的异常处理函数!
(说明:我使用的系统是 XP SP3 ,以下的所有操作都在 XP SP3下进行)
我的疑问:
(1)我使用OD调试光盘里面的程序 SEH_stack.exe ,在安装完一个 S.E.H 之后就在内存中搜索刚才安装的 S.E.H 中的函数的地址,发现除了指令中和栈中的两个之外,没有其他地方保存有副本.而这两个显然不能称为副本----一个在代码段,不可写,不可能是刚写进去的,一个在栈中,就是 S.E.H 本身.
这样的话,那份副本究竟保存在哪里呢?或者系统不是这样直接保存副本的,而是采取了其他的方式?那究竟又是什么方式呢?现在有没有被人们研究出来?
(2)我使用16进制工具修改了程序----只修改了几个字节,就是把 shell code 的最后4个字节(代表shell code 的地址)由0012fe98 修改为 00406030(位于数据段).发现程序可以进入 shell code 执行.这与书上的说法不一样. 00406030 并不属于堆,却执行了.这说明数据段就可以了,不必要非要在堆区.
欢迎大家讨论.
附件里面有光盘程序和我修改之后的程序,大家可以在自己的电脑上测试一下.
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课