2019独角兽企业重金招聘Python工程师标准>>>

蓝屏冲突事件来历

在2013年6月12日,也就是端午节当天,微软发布了6月例行补丁日的Windows/Office相关补丁,国内各大安全厂商也向用户及时推送 了这些补丁,而在补丁发布后,各大安全厂商、电脑厂商却接到了大量的用户反馈,说安装了微软KB2839229补丁后,导致系统蓝屏,无法开机。

经过对蓝屏DUMP深入分析,可以明确这是金山系列软件中的驱动程序,在挂钩Windows内核时处理不当引发的蓝屏问题,受影响的软件包括金山毒 霸、金山卫士、猎豹浏览器、驱动精灵(被金山收购)和WPS Office,受影响的驱动程序组件是:kisknl.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函数的对比

补丁前nt!KiFastCallEntry部分代码(win7 SP1 x86)

01 mov     cl, [eax+edx]
02 mov     edx, [edi+eax*4]
03 sub     esp, ecx
04 shr     ecx, 2
05 mov     edi, esp
06 cmp     esi, ds:_MmUserProbeAddress
07 jnb     loc_43DAF5
08 rep movsd
09 test    byte ptr [ebp+6Ch], 1
10 jz     shortloc_43D8E5

补丁后nt!KiFastCallEntry部分代码(win7 SP1 x86)

01 mov     cl, [eax+edx]
02 mov     edx, [edi+eax*4]
03 sub     esp, ecx
04 shr     ecx, 2
05 mov     edi, esp
06 test    byte ptr [ebp+72h], 2
07 jnz    shortloc_435807   
08 test    byte ptr [ebp+6Ch], 1
09 jz     short_KiSystemServiceCopyArguments@0
10 cmp     esi, ds:_MmUserProbeAddress
11 jnb     loc_435A41
12 rep movsd
13 test    byte ptr [ebp+6Ch], 1
14 jz     shortloc_435831

对比之下就可以看到,从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等,都采用过类似的技术,当然,各家的实现方式各有不同。

金山毒霸的KisKnl.sys驱动实现了一个特别的版本(金山系列的此次其他受影响驱动也类似,这里暂以KisKnl.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的异常保护,从而引发了安全漏洞,导致简单的三条汇编指令,就可以在安装了金山毒霸的系统上,触发系统崩溃。

虽然金山后来修复了这个漏洞,但由于没有修改这个错误的逻辑,仍留下了不小的性能隐患,这里不再赘述,下面就来看看引发这次补丁蓝屏的金山驱动代码的具体分析。

这里分析的 KisKnl.sys是金山毒霸修复补丁蓝屏问题的上一个版本,数字签名是2013年的5月30日。KisKnl.sys挂钩 KiFastCallEntry的大概原理是,先通过SSDT HOOK挂钩ZwDispalyString这个系统内核服务,然后通过特殊的参数触发这个函数的调用,由于在调用系统服务函数时,函数返回地址就是 KiFastCallEntry的函数中部,因此KisKnl.sys就此获得了KiFastCallEntry这个未导出函数的中部位置的具体地址。

接着KisKnl.sys会通过一个简易的二进制搜索引擎,从KiFastCallEntry函数中部向上搜索一段被称为 KiSystemServiceAccessTeb的位置附近的特征码,在找到特征码后,金山会根据系统的大版本号(这里的大版本号是指微软大的产品版本 号,例如Windows XP, Windows7)来决定不同的硬编码距离差值,通过这个距离差值,直接定位到跳过系统代码后的位置,然后将其设为要跳转的地址。

如我们上面分析的,微软此次补丁,就恰好向KiFastCallEntry这部分代码添加了4条指令,这就导致了金山原来以为雷打不动的大版本距离 差值发生了变化,从而导致定位到了错误的位置,最后挂钩函数跳转到了错误的代码位置,引发系统蓝屏。由于KiFastCallEntry是非常重要的系统 分发函数,因此这部分的代码异常就导致了系统反复蓝屏,无法进入。

下面是对KisKnl.sys的这部分逻辑的反汇编,可以清楚的看到这部分逻辑:

01 .text:000310D7                 mov     eax, os_version
02 .text:000310DC                 push    esi
03 .text:000310DD                 mov     esi, callebx_return
04 .text:000310E3                 add     esi, 0FFFFFF38h
05 .text:000310E9                 test    eax, eax
06 .text:000310EB                 jle     loc_313C7
07 .text:000310F1                 cmp     eax, 3
08 .text:000310F4                 jle     loc_312F2
09 .text:000310FA                 cmp     eax, 4
10 .text:000310FD                 jz      loc_31251
11 .text:00031103                 cmp     eax, 5
12 .text:00031106                 jz      loc_311B3
13 .text:0003110C                 cmp     eax, 6
14 .text:0003110F                 jnz     loc_313C7
15 .text:00031115                 lea     eax, [ebp+code_offset]
16 .text:00031118                 push    eax
17 .text:00031119                 push    27h
18 .text:0003111B                 push    offset KiAccessSystemTebCodeSpec
19 .text:00031120                 push    0C8h
20 .text:00031125                 push    esi
21 .text:00031126                 call    code_search
22 .text:0003112B                 test    eax, eax
23 .text:0003112D                 jz      loc_3126B
24 .text:00031133                 mov     eax, [ebp+code_offset]
25 .text:00031136                 lea     ecx, [eax+esi+25h]
26 .text:0003113A                 lea     eax, [ecx+48h]
27 .text:0003113D                 mov     jump_cross_return_address, eax

从代码中我们可以看到, KisKnl先是判断系统版本号,然后在获得的中部地址向上搜索获得KiSystemServiceAccessTeb附近地址后,通过版本号硬编码的偏移来决定跳转返回的地址。

在新版本的KisKnl.sys在确定硬编码偏移后,还会再判断下代码是否符合,暂时避免了这个问题,但仍留有继续蓝屏,或者保护失效的隐患。

国内外使用类似技术的主流安全产品,不会采用硬编码偏移的这种方式来确定跳转地址,也不会采用强行跳走系统代码这种不稳定的做法,因此不存在同此补丁的冲突问题。

金山系列软件发生这次的问题,主要还是开发人员技术经验不足,在技术方案选择时没有慎重考虑,在发生问题后没有仔细考虑引发问题的方案的不足导致的。

内核驱动程序的方案稳定性决定着用户系统与资料的稳定与健全,开发人员都应引以为戒,慎重对待和考虑技术方案。

转载于:https://my.oschina.net/zhuzihasablog/blog/139114

端午节蓝屏之谜:金山系列软件同微软KB2839229冲突技术分析相关推荐

  1. 计算机蓝屏代码0xc0000020,Win10打开软件提示“损坏的映像 错误0xc0000020”的解决方法...

    现在,使用windows10系统的朋友越来越多了,因此总有一些用户会反馈一些问题.比如,说这次有用户在打开软件时遇到报错的问题"文件名-损坏的映像 错误0xc0000020",这是 ...

  2. linux 环境变量文件_应急响应系列之Linux库文件劫持技术分析,有点硬核哟

    0×01 菜逼阶段 Linux库文件劫持这种案例在今年的9月份遇到过相应的案例,当时的情况是有台服务器不断向个可疑IP发包,尝试建立连接,后续使用杀软杀出木马,重启后该服务器还是不断的发包,使用net ...

  3. 啊啊啊啊啊,终于解决电脑hardlock.sys蓝屏问题啦,顺利下载modelsim软件

    最开始下载软件时,电脑蓝屏,以为是电脑储存空间不足,换了1T固态硬盘之后,问题还是没有解决: 从博客看经验贴,需要进入安全模式后,从别的笔记本电脑上复制hardlock.sys文件到自己电脑上替换,结 ...

  4. 0x000000ea(0x000000ea蓝屏代码是什么意思)

    蓝屏错误代码0X000000EA(0X85AFDDA0,OX89? 0x000000EA错误表示显示驱动程序遇到了问题.这个错误一般是因为显卡或显示器的驱动程序存在BUG或安装不正确引起的. 如果遇到 ...

  5. 揪出“凶手”——实战WinDbg分析电脑蓝屏原因

    http://www.appinn.com/blue-screen-search-code/ 蓝屏代码查询器 – 找出蓝屏的元凶 11 文章标签: windows / 系统 / 蓝屏. 蓝屏代码查询器 ...

  6. oc引导windows蓝屏_人人都会遇到系统蓝屏问题,教大家自已排除蓝屏,学会一辈子受用...

    一.造成电脑蓝屏有那些? 1.在这里我跟大家聊聊,我想只要自已有电脑人都会遇到电脑蓝屏问题,那怎么排除蓝屏问题?首先要找到电脑蓝屏的原因才针对性的处理,引起电脑蓝屏的原因有很多: 2.硬件方面有:电脑 ...

  7. 系统蓝屏的几种姿势,确定不了解下么?

    前言 在 蓝屏(BSOD)转储设置,看本文就够了!这篇文章里比较详细的介绍了蓝屏转储设置.做好设置后,我们就可以在需要的时候使系统蓝屏了.本文介绍几种使系统蓝屏的办法,当然肯定还有其它办法,如果哪位小 ...

  8. php工程导致系统蓝屏,经常蓝屏是什么原因

    经常蓝屏的原因:1.错误安装或更新显卡驱动后导致电脑蓝屏:2.超频过度是导致蓝屏:3.安装的软件存在不兼容:4.电脑内部硬件温度过高:5.内存条接触不良或内存损坏. 错误更新显卡驱动 错误安装或更新显 ...

  9. 蓝屏分析_电脑突发蓝屏现象?教你如何快速修复

    近日,win7系统遭遇大面积蓝屏崩溃现象,360紧急跟进,根据目前部分用户反馈,初步判断蓝屏是由于系统中的某个硬件驱动程序或者木马病毒,导致了Windows7系统的smss.exe进程停止,进而触发蓝 ...

最新文章

  1. ​​​​​​​跳水板
  2. 统计app用户在线时长_优质的APP推广渠道,应该如何筛选?
  3. python sklearn.datasets.fetch_mldata MNIST手写数字数据集无法获取, 报错 Function fetch_mldata is deprecated 的解决办法
  4. java keytool证书工具使用小结
  5. 单片机涡轮流量传感器_关于涡轮流量计传感器的维护保养
  6. LNK2019:无法解析的外部符号
  7. FastJSON、Gson和Jackson性能对比
  8. VC++实现防火墙过滤
  9. rk3288 android5.1 java 层使用 su 获取 root 权限
  10. 2022-03-13 转载 Dockerfile 高阶使用指南及镜像优化
  11. Spring好处—总结
  12. 四叉树 gis java_GIS中四叉树索引及其分类介绍 | 麻辣GIS
  13. freewitch测试信息-cdr
  14. Java Spring Security 安全框架:(四)PasswordEncoder 密码解析器详解
  15. RapidMiner
  16. 运营老鸟眼中,“用户分层”真的超级简单!
  17. 8086CPU I/O系统组织 8253芯片 8255A芯片
  18. OpenGL(五)立体图形
  19. 开心一刻:今天下班后,我尾随一女同事,为她充当护花使者
  20. Linux操纵细碎以太网卡的装配及设置-2

热门文章

  1. Android各种大内存脚本对比(app2sd,a2sd,a2sd+,d2sd,CronMod,Mound2SD)
  2. java 熔断_Hystrix服务熔断
  3. 三电极体系电化学测量模组
  4. Android 开发简单记事本程序(附源码)
  5. 干货,史上杀伤力最大的溢出型漏洞到底是什么?看这一篇就够了| 漏洞连载
  6. (二)回顾硅谷:硅谷历史
  7. 来了解一下最新Amy联/通免流
  8. 打开cad图纸计算机打不开,电脑上CAD软件为何打不开?打开电脑CAD软件方法!
  9. 数据结构与算法学习——基础知识(一)
  10. MATLAB未定义变量example,小虫求助“ 未定义函数或变量 'Beam_InputData547'。