太长不看版:
这是来自NGA用户kprismk关于这个漏洞的一个比喻。注意这是比喻省略了大量细节,但基本思路大致是这样:
1.kfc里卖的有薯条、鸡块、汉堡、可乐。
2.李小璐去kfc点了个汉堡,吃完走了。
3.狗仔队a狗仔排在李小璐后面的后面,和点餐小姐姐说:我要点和李小璐一样的。
4.点餐小姐姐说,不好意思您前面还有一位,稍等下,但是后厨听到了,麻溜的做了个汉堡。
5.轮到a狗仔点餐了,点餐小姐姐说。不能这样点哦,侵犯人家隐私了,保安把这个狗仔ccq!
6.b狗仔排在a狗仔后面,给小姐姐说:我薯条、鸡块、汉堡、可乐各点一份,饿死了饿死了,哪个快先把哪个给我!
7.b狗仔先拿到了“汉堡”!
8.b狗仔知道了李小璐今天在kfc买了个汉堡!
电脑运行的时候,所有用到的数据都必须经过内存。这里面既有你至关重要的银行密码,也有你故意和非故意打开的莫名其妙小网站小程序。
怎么让这些外面来的野路子程序碰不到关键信息呢?
今天的电脑设计了层层防线,其中至关重要的一层发生在电脑的计算核心——CPU上。CPU会负责检查程序有没有在不属于自己的地盘上探头探脑,如果发现它碰了别人的数据,就会启动枪毙流程。设计者认为,这样就能竖起一堵高墙,把每个程序隔离在自己的小屋里。
但是他们错了。这堵高墙上有一个十分隐蔽的缝隙,刚刚被公开出来。整个行业为之震动。
这个缝隙虽然隐蔽但是危害极大,研究者已经成功通过它偷出来了浏览器保存的网站密码。幸运的是偷密码的过程十分复杂,坏人这几天应该还来不及用它实际作恶;不幸的是堵上这个缝隙极度困难,而且看起来要付出电脑明显变慢的重大代价。
谁也没想到,2018一开年就迎来了这么大的一个大新闻。
事件经过
2018年开头的这几天里,linux系统核心的例行更新被发现在某些场合有巨大的性能衰退,这一反常现象触发了少量业内人士的关注。linux核心被部署在大量的服务器生产环境中,对性能尤为注重,因此这一补丁的匆忙上线和微软windows、苹果MacOS的暧昧反应加在一起,引发了越来越多的讨论。
著名科技新闻站点theregister在北京时间1月3日早上爆料称[1],linux的这一补丁是为了修复某个巨大的CPU硬件安全漏洞不得已而为之,并直指罪魁祸首是当今世界的CPU头号霸主Intel,这一新闻张贴出来以后开始在IT圈内广泛流传,由于这篇新闻具备相当的技术背景并附上了实测数据,具备比较高的说服力,使得相关的议论和猜测愈演愈烈。
在北京时间1月4日早上,Intel终于按耐不住发表了一篇新闻稿[2],意指这些坊间传闻有夸大其词之嫌,但也没有遮掩安全漏洞确实存在。几个小时之后,谷歌的安全小组ProjectZero正式公布了这两个极具震撼力的新型漏洞,也就是大家现在看到的熔毁(meltdown)和幽灵(spectre)。
熔毁和幽灵的官方logo
这时候大家才知道,原来具体漏洞在2017年6月-7月份左右就已经被多个团队独立发现,相关研究人员在当时就已经知会Intel、AMD、ARM等著名CPU设计(制造)公司和微软、苹果、linuxkernel核心开发组等相关机构和团体,并在所有知情人中间形成了默契的封口令[3],众多参与者本来打算等到一两周之后所有补丁和更新都准备好了再对外公布,没想到并不知情的theregister网站从linux开源社区的邮件列表里发现了蛛丝马迹,提前捅破触发了公关危机,于是1月4号早上Intel也决定提前发布消息,随后谷歌的研究者也打破沉默,上线了那个早已准备好的漏洞介绍网站和相关论文[4],于是一切被公诸于世。我们正在经历什么
毫不夸张地说,截至目前爆出的漏洞实锤和原型演示来看,我们遇上了计算机体系结构发展史上的最大硬件漏洞,并且很可能没有之一。目前已经可以确定的是,“熔毁”直接洞穿了Intel和微软Windows、linux、苹果MacOS共同设下的重重安全防护,使用一段并不算特别复杂的代码,运行在Intel处理器上,就可以做到窃取Firefox浏览器在内存中保存的密码、保存了网络通信信息的HTTP报文头等关键隐私,这不是耸人听闻的推测,而是已经被实现并通过视频展示给全世界的事实,连源代码都已开放下载[5]。而另一个漏洞“幽灵”则更加高深莫测,它同样能悄无声息地穿透操作系统内核的自我保护,从用户运行的空间里读取到操作系统内核空间的数据,并且比“熔毁”更加恐怖的是,它在Intel/AMD/ARM这三大主流公司的CPU上都能起作用,可以说事实上所有的PC/手机/服务器都在受影响范围内,并且难以通过软件补丁修复也无法通过反病毒软件对抗,再考虑到过去这些年中CPU数以亿计的出货量,已售出的芯片也无法通过微码更新来完美解决问题,因此将会名副其实地成为一个笼罩在所有人头顶许多年时间的安全隐患,大概“幽灵”的名字也就是这样得来的。
为什么之前没有发现这个漏洞?
这两个漏洞都具有同一个特点,利用了现代高性能微处理器中的关键特性-推测执行和乱序执行,这两项技术都是推动微处理器性能进步、让大家的电脑、手机能够高速运行越来越复杂应用的核心支柱。
推测执行技术是指,处理器为了提高性能,会去提前猜测接下去需要执行什么动作,然后提前执行,如果发现推测错误,则回滚至正常状态。通常应用的推测执行技术都能达到80%-90%以上的推测准确率。需要指出的是,推测执行技术是一个大类技术的统称,包括分支预测,预读取,推测性内存访问,缓存缺失的重叠/乱序处理(MSHR)等等,幽灵漏洞就利用了分支预测、推测性内存访问和MSHR这三个特性。
乱序执行技术是指,当处理器遇到需要发生停顿的事件时(例如需要装载的数据发生了缓存缺失,需要去高延迟的内存中查找),处理器可以越过这个停顿事件,继续超前执行指令。同样,如果超前执行中发生了错误,也需要回滚至正常状态。熔毁漏洞就利用了乱序执行特性。
乱序执行的微结构框图。熔毁利用了图中executionengine的部分,幽灵利用了图中branchpredictor的部分。
乱序执行技术最早出现在CDC6600和IBM360/91上,时间是上个世纪60年代,乱序执行技术的两位关键贡献者JamesE.Thornton(1994)和RobertTomasulo(1997)也因此拿到了计算机体系结构学术界的最高荣誉Eckert–MauchlyAward,至于推测执行的第一个范本,由于变种技术太多已经无法考证,可考证最早的分支预测设计是JamesE.Smith于1981年公开的,他也对乱序执行做出了卓越贡献,于1999年荣获Eckert–MauchlyAward[6]。
可以看到,这些技术都是经过数十年发展验证的成熟技术,此前爆出过的也只是程序运行错误的功能bug,并没有如此严重的安全漏洞,而且推测执行和乱序执行对性能的提高都是成倍的影响力,例如在模拟器上的验证表明,关闭乱序执行大约会损失一半的性能,关闭推测执行中的分支预测则会将处理器的最大指令吞吐的理论上限打回上世纪90年代的水平,因此这两项技术已经成为当之无愧的高性能微处理器的结构顶梁柱。而根据推测执行和乱序执行的框架设计,其中有一个叫做重排序缓冲(ROB)的部件会负责树立推测状态和正常状态之间的分界线,有了ROB的保护之后,推测执行(分支预测)和乱序执行的状态信息就不会被上层感知,这是写在每一本计算机体系结构教科书里的内容,被一代又一代的工程师沿用。
现在,这个内容被彻底改写了。
漏洞原理
虽然指令可以不按顺序执行,为了确保乱序执行的效果不对机器状态发生影响,在乱序执行过程中发生的异常错误和安全检查违例,都要等到指令最后提交结果、并确认推测状态无误时才发起处理,如果发生错误,指令结果将被丢弃,异常处理进行完毕后回到正常状态。如果在乱序执行过程中就对指令进行异常处理,就会导致代码发生异常的位置和实际执行位置不匹配,打破了乱序执行不得影响程序状态的规则,从而破坏辛苦写代码的码农们所感知到的编程模型。如果指令通过了检查,确认无误,指令的操作结果才会更新到缓存与相关寄存器上,从而可以被软件读取。因此从指令执行到进行最后的提交检查之间存在一个可以利用的时间窗口,按照目前的乱序执行窗口和处理器执行频率计算,大概有十几个纳秒到几十个纳秒的时间,可供继续超前执行大约几十到一百多条指令。这个时间窗口成为了“熔毁”的攻击点。
CPU执行代码并非顺序执行,而是会把排在后面的代码提前执行。
在常规状态下,访问被保护的敏感区域会直接被权限鉴别的过程给拒绝,但是熔毁在这个小的时间窗口中,故意插入指令访问了一些本该被保护的关键区域,这些敏感数据就会被提至处理器核心内部的寄存器里参与运算。直到这一步,ROB仍然在维护超前执行状态-正常状态的分界线,整个系统仍然在保护之下,因为虽然敏感数据被提至处理器内部,但是并未经过安全检查和异常检查的确认,所以它的值只能用来作临时运算,不能用来参与正常运算,不会被更新到架构可见寄存器与缓存上,也就无法被上层软件读取,而等检查进行到它所处位置的时候,CPU就会发现问题,然后及时制止,所以不会发生问题。但是这里出现了整个漏洞利用中最漂亮的一步:时间差分攻击。
既然敏感数据已经被提取至CPU核心内部可以参与临时计算,那么就可以用它作为存储器访问的路标k,把内存中的第k块数据装入缓存。这大概要花费上百个时钟周期也就是大约几十纳秒,这个时间处在乱序执行允许的窗口范围内,如果窗口范围不够大了,还可以用其他手段再把这个窗口拉大一些。但终归到最后,乱序执行的指令要走到提交检查的一步,CPU检查发现这个敏感数据被访问了,就会把对应指令的结果抛掉,k的值被扔掉以后,恶意代码就无法读取到k的值了。而这里遗漏了关键的一点,在乱序执行中被装入缓存的内存第k块数据,并没有被清理。于是后继代码就可以大大方方地把相关内存地址都扫一遍,放在缓存里面的数据的访问延迟与放在内存里面的数据是不同的,如果扫描到第10块内存的时候发现它的响应速度特别快,就可以确定先前被读取上来的k值是10。
另一个幽灵漏洞的原理与此类似,但利用的是推测执行(主要是分支预测)的指令,从执行到进行安全检查之间的时间差,在推测执1行状态下,利用此时触发权限违例不会被立即掐死的特点,执行一些恶意代码把敏感数据装入CPU寄存器参与临时计算,随后用这个敏感数据制作一个内存地址装入缓存,再触发随后的时间差分攻击。
效果与防护
熔毁和幽灵利用乱序执行和推测执行,绕过了权限检查等安全措施,可以访问操作系统内核乃至其他程序的内容。其中熔毁更容易触发利用,因此才有大家已经看到的盗取浏览器密码的实例,而幽灵漏洞需要受攻击目标程序的分支入口点结构满足一定条件才能触发,难度相对较大,因此网上还没有发现基于幽灵漏洞的信息泄露实例出来。需要指出的是,幽灵和熔毁漏洞都只能读取敏感信息,不能修改(因为乱序执行/推测执行状态下的修改在未通过检查时一定会被抛弃),算是不幸中的万幸。
由于攻击的是硬件漏洞,因此目前市面所有主流操作系统,包括windows,linux,MacOS都处在攻击范围内,隔离程度不够高的众多半虚拟化方案,Docker,LXC等,也在受影响范围,因此这个漏洞将极大地影响云计算服务提供商。目前Google,Amazon,国内的阿里,腾讯等大型云服务提供商都已宣布了补丁计划。
从业界厂商的角度看,尽管Intel,AMD,ARM各有说辞[7][8][9],但从专业从业人士的角度看,Intel妥妥地同时受到熔毁和幽灵两个漏洞影响,而AMD和ARM在熔毁漏洞面前也只是暂时安全,熔毁的攻击原理也适用于AMD和ARM,只是因为分支预测器结构不同、流水线长度较短导致可利用的时间窗口不大等等因素,才没有像Intel一样被熔毁攻破。而幽灵则针对分支预测器进行注入攻击,目前所有厂商的分支预测器部分都没有做比较好的安全防护,因此Intel和ARM,AMD都会受到影响,而且分支预测器为了提高性能,天生就设计成部分地址哈希进行模糊匹配的模式,使得相关防御措施很难在不伤害性能的情况下修补漏洞。
针对熔毁漏洞,目前已有的技术手段主要是通过软件层次将内核页表与用户页表尽可能地隔离,这种技术的一个实现方案叫KAISER,其变种已经被各大操作系统采用作为熔毁漏洞的临时补救措施。这种技术方案会提高用户态与内核态的切换开销,快速系统调用的初步测试证明,内核系统调用的速度降低到了原先的42%,而利用现代处理器的PCID特性进行优化后,能够恢复到57%的水平[9]。具体的应用程序下降幅度取决于用户程序与内核交互的频繁程度,linxukernel开发人员的测试结果从10%~20%+不等,PCID能够弥补大约5%-7%的性能。
针对幽灵漏洞,目前没有很好的防御方式,linux的发行版之一suse最近公开的一个安全更新显示[10],AMD和Intel已经向相关OS厂商推送了一个微码更新,这个微码更新会关闭分支预测来暂时封堵幽灵漏洞。由于分支预测对性能影响巨大,即便分支预测只被关闭一部分也很容易造成性能衰退二代左右的幅度,如果整个分支预测器都被关闭,CPU性能将退回2000年以前的水平。对于这个更新是否将被应用,相关从业人士正在持续跟进关注。
共0条 [查看全部] 相关评论