查看: 13979|回复: 82
收起左侧

[分享] 端午节蓝屏之谜:金山系列软件同微软KB2839229冲突技术分析

  [复制链接]
爱也无罪
发表于 2013-6-13 15:49:27 | 显示全部楼层 |阅读模式
本帖最后由 爱也无罪 于 2013-6-13 16:28 编辑

蓝屏冲突事件来历
在2013年6月12日,也就是端午节当天,微软发布了6月例行补丁日的Windows/Office相关补丁,国内各大安全厂商也向用户及时推送了这些补丁,而在补丁发布后,各大安全厂商、电脑厂商却接到了大量的用户反馈,说安装了微软KB2839229补丁后,导致系统蓝屏,无法开机。
经过对蓝屏DUMP深入分析,可以明确这是金山系列软件中的驱动程序,在挂钩Windows内核时处理不当引发的蓝屏问题,受影响的软件包括金山毒霸、金山卫士、猎豹浏览器、驱动精灵(被金山收购)和WPS Office,受影响的驱动程序组件是:kiskrnl.sys(金山毒霸)、 KsDef.sys(金山卫士)、knbdrv.sys(猎豹浏览器)、dgsafe.sys(驱动精灵)和WpsSafe.sys(WPS Office)。金山毒霸于12日下午1点紧急更新了新版驱动解决此问题,其他的产品升级状况暂时还不清楚。
蓝屏冲突事件Q&A
这里先给出一些关于此次蓝屏事件的一些Q&A,再进入技术分析的部分:

Q:这次蓝屏的技术原因简单来说是什么?
A:是由于金山系列软件在挂钩 Windows内核时,强行跳过系统代码进行执行,而跳过代码的计算方式是使用硬编码的方式导致的。因此只要操作系统代码发生变更,金山系列软件就会引发系统蓝屏

Q:金山的中国区论坛的官方置顶贴说此次蓝屏是因为“微软打补丁没更新版本号导致的”,这是真的吗?这次补丁蓝屏是因为微软的补丁存在问题吗?
A:这不是真的,微软的补丁都会更新版本号,且此次蓝屏同微软更新补丁是否修改版本号无关,也不是微软补丁的责任。

Q:网上有人说360、电脑管家和瑞星等“国内主流安全软件”都会和这个补丁冲突发生蓝屏,在这些安全软件厂商论坛上也会看到有用户反馈蓝屏,这是真的吗?
A:这不是真的,除了金山外,360等安全软件都未采用这种强行跳过系统代码执行的技术方案,不会同本次补丁冲突蓝屏。其它厂商论坛上的蓝屏反馈贴子,经过沟通了解后,主要也都是同时安装了金山系列软件。

Q:为什么有些金山用户打补丁后并未蓝屏?为什么我现在安装了金山系列软件,然后去打这个补丁没出问题?
A:金山毒霸于12日下午更新了新版驱动,因此更新驱动后再打补丁不会出现问题。另外,此补丁只影响32位系统,如果是64位系统的用户无需安装此补丁,因此也不会遇到蓝屏问题。

Q:QQ电脑管家发布新闻说KB2839229、KB2839727这两款补丁都有问题,会导致蓝屏,这是真的吗?
A:由于金山软件的问题,导致蓝屏的只有KB2839229这一款补丁,KB2839727这款补丁是不存在的,这应该新闻作者对补丁“KB2838727”之误。

KB2838727这个补丁是IE浏览器积累性更新补丁,没有升级内核相关文件,不会导致蓝屏

下面我们来具体分析下KB2839229这个补丁究竟更新了什么?为什么金山系列软件在安装了这个补丁后,会导致系统蓝屏?
KB2839229补丁的来历和分析
KB2839229这个补丁修复了由 Google的著名研究人员j00ru发现的一个微软内核信息泄漏安全漏洞CVE-2013-3136,这个漏洞是Windows系统内核在处理页面异常的处理函数KiTrap0E中,由于针对系统内核服务函数KiFastCallEntry的参数处理部分的特殊处理没有考虑Ring3的请求的情况,而引发的一个信息泄漏或拒绝服务安全漏洞。
J00ru在今年5月法国举办的安全大会NoSuchCon上公布了这一安全漏洞,并发表了一篇很有意思的论文:<<Abusing the Windows Kernel: How to Crash an Operating System With Two Instructions>>(如何只用两条指令让操作系统崩溃),这篇论文也被公开在他的技术博客上,对内核安全感兴趣的同学可以学习一下:http://j00ru.vexillium.org/?p=1767
微软6月的补丁KB2839229就是用来修复这个安全漏洞的,首先,微软在修复后的Windows系统内核:ntoskrnl.exe中,对KiTrap0E函数做了一些修改,使用了一个新的名为KiPreprocessAccessViolation的函数,来统一处理针对特殊的内核页面异常的处理,其中就包括出现漏洞的,针对KiFastCallEntry复制参数部分的特殊处理。同时,这个补丁也修改了部分KiFastCallEntry的代码,原先在 KiFastCallEntry复制参数之前,会有一个判断是否是内核模式的逻辑被优化到KiFastCallEntry函数之外(这是微软内核的一个常见编译优化手段),在新的版本中,由于新增了一个判断,这部分逻辑被移动回了KiFastCallEntry函数内,而正是这么一点点小小的正常改动,就引发了金山系列软件的蓝屏。
我们来看一下补丁前和补丁后的ntoskrnl!KiFastCallEntry函数的对比



对比之下就可以看到,从test byte ptr[ebp+72h],2开始,到jz short _KiSystemServiceCopyArguments的部分就是此次修改的代码,这部分代码(ebp+6c的检查)本应是在补丁前的那个jnb loc_43DAF5会去做检查的(由于优化,跳转到函数之外,由于参数堆栈在内核态区域,要判断是否是内核模式调用,如果不是会被拒绝),但这里由于增加了ebp+72h的处理,因此一起被放回了代码流中。
那么为什么这样一个小小的修改,就引发金山系列软件的驱动程序导致系统蓝屏,无法进入系统呢?下面我们来分析金山驱动的挂钩机制,解释这个问题的原因。
金山驱动的分析
首先简单介绍下KiFastCallEntry这个函数的背景,这是系统中所有的内核服务分发的起点,当用户态的程序要调用一个内核态的服务函数,比如打开文件(通过 ZwCreateFile)或创建窗口(NtUserCreateWindowEx),都会经过这个函数点的分发,因此在这里进行挂钩,可以比较方便地针对系统中的可疑程序的行为进行监控、分析和拦截。自360保险箱最早从2007年开始使用了针对KiFastCallEntry的挂钩技术开始,国内外大量的安全软件都开始通过挂钩这个位置来实现主动防御、自我保护或沙箱等相关的安全功能,包括国内的360,金山,QQ电脑管家,瑞星,国外的赛门铁克, BitDefender等,都采用过类似的技术,当然,各家的实现方式各有不同。
金山毒霸的KisKrnl.sys驱动实现了一个特别的版本(金山系列的此次其他受影响驱动也类似,这里暂以KisKrnl.sys为例进行分析),该驱动在挂钩 KiFastCallEntry时,会抢在系统从用户态堆栈复制参数之前,获得执行机会,然后强行跳过包括系统复制参数、相关检查的逻辑,自己接管并实现这部分系统代码,然后再跳转到后面的执行代码。
这个强行跳过系统代码的特别的逻辑不仅奇怪,也存在着很多安全问题和蓝屏隐患。笔者在2011年1月就曾向报告过一个金山毒霸2011中因为这个逻辑而引发的安全漏洞:CVE-2011-0515,被国外漏洞库Secunia(http://secunia.com/advisories/42937)等和中国国家信息安全漏洞库(http://www.cnnvd.org.cn/vulnerability/show/cv_id/2011010320 CNNVD-201101-320)收录,此漏洞的原因就是因为金山的驱动跳走了这部分代码,使得这部分代码在复制堆栈参数时,不受KiTrap0E的异常保护,从而引发了安全漏洞,导致简单的三条汇编指令,就可以在安装了金山毒霸的系统上,触发系统崩溃。
虽然金山后来修复了这个漏洞,但由于没有修改这个错误的逻辑,仍留下了不小的性能隐患,这里不再赘述,下面就来看看引发这次补丁蓝屏的金山驱动代码的具体分析。
这里分析的 KisKrnl.sys是金山毒霸修复补丁蓝屏问题的上一个版本,数字签名是2013年的5月30日。KisKrnl.sys挂钩KiFastCallEntry的大概原理是,先通过SSDT HOOK挂钩ZwDispalyString这个系统内核服务,然后通过特殊的参数触发这个函数的调用,由于在调用系统服务函数时,函数返回地址就是KiFastCallEntry的函数中部,因此KisKrnl.sys就此获得了KiFastCallEntry这个未导出函数的中部位置的具体地址。
接着KisKrnl.sys会通过一个简易的二进制搜索引擎,从KiFastCallEntry函数中部向上搜索一段被称为KiSystemServiceAccessTeb的位置附近的特征码,在找到特征码后,金山会根据系统的大版本号(这里的大版本号是指微软大的产品版本号,例如Windows XP, Windows7)来决定不同的硬编码距离差值,通过这个距离差值,直接定位到跳过系统代码后的位置,然后将其设为要跳转的地址。
如我们上面分析的,微软此次补丁,就恰好向KiFastCallEntry这部分代码添加了4条指令,这就导致了金山原来以为雷打不动的大版本距离差值发生了变化,从而导致定位到了错误的位置,最后挂钩函数跳转到了错误的代码位置,引发系统蓝屏。由于KiFastCallEntry是非常重要的系统分发函数,因此这部分的代码异常就导致了系统反复蓝屏,无法进入。
下面是对KisKrnl.sys的这部分逻辑的反汇编,可以清楚的看到这部分逻辑:
view source


从代码中我们可以看到, KisKrnl先是判断系统版本号,然后在获得的中部地址向上搜索获得KiSystemServiceAccessTeb附近地址后,通过版本号硬编码的偏移来决定跳转返回的地址。
在新版本的KisKrnl.sys在确定硬编码偏移后,还会再判断下代码是否符合,暂时避免了这个问题,但仍留有继续蓝屏,或者保护失效的隐患。
国内外使用类似技术的主流安全产品,不会采用硬编码偏移的这种方式来确定跳转地址,也不会采用强行跳走系统代码这种不稳定的做法,因此不存在同此补丁的冲突问题。
金山系列软件发生这次的问题,主要还是开发人员技术经验不足,在技术方案选择时没有慎重考虑,在发生问题后没有仔细考虑引发问题的方案的不足导致的。
内核驱动程序的方案稳定性决定着用户系统与资料的稳定与健全,开发人员都应引以为戒,慎重对待和考虑技术方案。

附原文链接:http://blogs.360.cn/blog/kb2839229_kingsoft_bsod/

评分

参与人数 3人气 +3 收起 理由
hwl573452046 + 1 根据版规,加1分以示鼓励
a9878803 + 1 主题帖不能加分
cyk553312 + 1 版区有你更精彩: )

查看全部评分

huicuan
发表于 2013-6-13 15:51:36 | 显示全部楼层
管他呢 ,哎蓝不蓝
cyk553312
发表于 2013-6-13 15:57:34 | 显示全部楼层
好长,好深奥
基本没看懂
vm001
发表于 2013-6-13 16:00:17 | 显示全部楼层
楼主是牛人
lxilikepal
发表于 2013-6-13 16:09:47 | 显示全部楼层
vm001 发表于 2013-6-13 16:00
楼主是牛人

楼主是转的……
应该说写这篇东西的才是牛人
vm001
发表于 2013-6-13 16:11:24 | 显示全部楼层
lxilikepal 发表于 2013-6-13 16:09
楼主是转的……
应该说写这篇东西的才是牛人

哦,那就都是牛人
萧观澜
发表于 2013-6-13 16:11:46 | 显示全部楼层
小白前来学习!
chinaallenchen
发表于 2013-6-13 16:18:31 | 显示全部楼层
貌似是精睿论坛出现的,精睿貌似又是数字出资的........
alfchin13
发表于 2013-6-13 16:19:45 | 显示全部楼层
基本上是看懂了大致原因。。。
原作者的意思是金山原来的方法简单粗暴,解决问题但是留下隐患。这次微软在小版本号更新的时候顺手改了偏移,于是金山中枪
真相帝
发表于 2013-6-13 16:26:17 | 显示全部楼层
chinaallenchen 发表于 2013-6-13 16:18
貌似是精睿论坛出现的,精睿貌似又是数字出资的........


这是 mj 写的,发官方blog 了
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 沪ICP备2020031077号-2 ) GMT+8, 2024-11-25 18:55 , Processed in 0.131544 second(s), 17 queries .

卡饭网所发布的一切软件、样本、工具、文章等仅限用于学习和研究,不得将上述内容用于商业或者其他非法用途,否则产生的一切后果自负,本站信息来自网络,版权争议问题与本站无关,您必须在下载后的24小时之内从您的电脑中彻底删除上述信息,如有问题请通过邮件与我们联系。

快速回复 客服 返回顶部 返回列表