|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 A1Pass 于 2018-3-15 09:28 编辑
这次的“Intel处理器漏洞”影响之广泛可以说是前无古人了。当然,将其称之为“Intel处理器漏洞”也确实有些冤枉Intel了,毕竟其他处理器也都不同程度的受到了影响,只不过Intel是被影响最严重的厂商,但是事件发生后Intel股价单日下跌8%已经证明一切。
其实我一直以来都想找个机会能给各位关注知乎“黑客说”专栏的同学讲些系统底层的知识,这次Intel的漏洞算是个不错的契机。由于“黑客说”的slogen是“安全圈老鸟为小白开放的一块自留地”,因此我希望能用最简洁的语言向相对零基础的朋友描述清楚计算机底层世界中的一些冷知识。
目录
引子——来自虚拟世界底层的灾难
微码——中央处理器的另一番景色
氮气——中央处理器加速技术解密
熔毁——摧毁虚拟世界的权限长城
锡安——屡次被黑客攻破的圣盔谷
结尾——对于底层黑客技术的迷思
引子——来自虚拟世界底层的灾难
元旦刚过,第一篇详细描述此Intel漏洞的可查报道由 John Leyden 与 Chris Williams 于2018-01-02发布在英国老牌技术媒体The Register上,约12小时后Google公司的Project Zero安全团队在2018-01-03发布了名为《1995年后的几乎所有CPU都将受到“熔毁”与“幽灵”漏洞的影响》,将此事件推向高潮。
从漏洞分析的蜘丝马迹来看,此漏洞至少早在2017-12-09以前就已经在业内的部分圈子内开始被有序研究了,那么这究竟是一个什么漏洞呢?与CPU又有什么关系呢?具体能造成什么后果呢?我们研究它有什么收益呢?下面我就一一回答这些问题。
首先,概括的说这就是一个由于CPU指令加速功能的设计缺陷,导致的微结构内部通过侧信道向外部泄漏数据的一个Bug(不要怕,这种专业解释看不懂很正常)。而我们这篇文章的主要目的之一就是以浅显易懂的语言让各位零基础读者理解这究竟是什么意思。既然提到了CPU指令加速,那么很显然就是与CPU相关了,而目前修复这个漏洞的方法自然也是对CPU的指令加速这一机制做了某些限制,打完补丁后会直接导致CPU速度降低30%~35%(嗯,你没看错,你的i7瞬间就变i5了,不过没事,别人的i5也会变成i3的),虽然Intel声明说根据用户的不同应用场景,在大多数情况下影响并没有这么夸张。但是道理咱们都懂的,虽然原本最快能跑200km/h的性能车打完补丁后就变成了最快只能跑130km/h的面包车,但是在处处堵车的大背景下我们确实是也很少跑到130km/h,不过问题是我多花的那些钱找谁要去呢?
其次,这个漏洞能造成的后果就目前来看还是相对比较有限的,因为其对关键内存区域只有读权限没有写权限,所以能够引起最大的问题就是关键数据(例如各位都能够理解的用户名、密码)被泄漏。如果合理的映射到的实际攻击场景中,效果就是受害者浏览一个能够触发此漏洞的网页,然后其浏览器中自动保存的那些用户名、密码就被瞬间窃取了。当然,深究下去的话,黑客们如果利用此技术补白其在攻击过程中缺少的关键信息,那么由此导致的后果就不可估量了。目前直接导致的最大问题就是各种云、各种IDC将面临关键数据泄漏灾难,而漏洞补上后又会导致整体性能下降30%,同样也算是另外一种灾难了。
最后,就是研究这个漏洞究竟有什么收益。其实,这个漏洞中引伸出来的很多知识点都是信息安全领域中比较核心的内容,也有些知识是深入学习软件逆向所需要掌握的。如果你对信息安全感兴趣,那么这篇科普文你一定要从头到尾一字不落的读下来,读完之后,你眼中的计算机将会是另一番景象。
微码——中央处理器的另一番景色
有些基础的同学可能知道程序的最底层就是由“机器码”构成的,这些“机器码”是由程序员们通过使用例如C、CPP等计算机语言编写的源代码经过编译器编译生成的。这些二进制的“机器码”被以某种方式让CPU读取到后执行,就形成了应用程序各种各样的行为(例如QQ能聊天、Office能办公、陌陌能把妹等)。
但现实情况并非这么简单……
首先,所谓的“机器码”这个叫法本身并不专业(虽然各大技术论坛的很多文章都这么写),其正确的叫法应该是操作码(OPCode)或勉强算是正确的二进制代码,因为操作码是构成计算机指令集体系的一部分(请参考本段后面的“释义:何为指令集”),所以这并不能被理解为最原子化(不可再分割)的操作。其实,一条操作码(例如一个加1操作的操作码是十六进制的0x40,或二进制的1000000,翻译为汇编就是INC EAX)在被CPU读取执行时,并非就直接执行了,而是将这条操作码在CPU内可能会被分解为几十条至数百条不等的微指令/微码(MicroCode)再进行运算操作,最后在交由CPU物理层的逻辑电路去执行。
其次,我们平时所能接触到的一般被称之为计算机体系结构(Architecture),而CPU中使用的则是微体系结构(Microarchitecture)。这就导致实质上大多数的IT工作者(包括普通程序员乃至汇编语言程序员甚至大部分软件安全研究员)所接触的最底层其实就是计算机体系结构这一层(例如我们现在广泛使用的冯·诺依曼结构,也叫做存储程序方式结构),在这个结构中,CPU被看作是一个不可被再分割的单元,被看作是一个黑盒子,因为在大多数IT工作者的实际工作过程中,最多也只能涉及到操作码(二进制代码)这一级,所以哪怕是在例如信息安全等相对比较专业的领域,有关微体系结构中的微指令这个概念也是鲜有人知的。
最后,关于微体系结构本身,这其实是一个CPU最为核心的部分,对于大多数IT工作者而言,CPU微结构并不暴露给他们,哪怕是最底层的软件安全研究员也只能是通过操作码来访问CPU,因此就目前层面而言我们能使用CPU的最小操作粒度就是指令了。但我们上面也简单的说过,操作码在被CPU读取后还可能会被解析成为若干条更小的执行单元,并由这些单元最终驱动CPU的单个硬件逻辑电路去完成具体计算操作,而这些更小的执行单元就被称之为微操作(MicroOP/μOP)或者微指令/微码(MicroCode)。在实际应用场景中,微指令是可以完成一些非常复杂的操作的,而通过修改CPU的微指令在很多时候甚至可以帮助厂商协助用户修补已经发售CPU的Bug(可惜这次漏洞由于过于复杂,不能通过修改微指令修复此漏洞)。
释义:何为指令集
指令集是指CPU提供给外界的功能接口,举例来说,空调的指令集就包含“开关机”、“调高温度”与“调低温度”等,而空调提供给我们的指令集接口,就是空调遥控器。
而CPU的指令集是由汇编语法、OPCode等构成,汇编语言是OPCode的一种文字化映射,可以将看似毫无含义且晦涩难读的二进制代码一一对应为用英文单词组成的汇编语言,以方便人们使用。
这类似于空调遥控器将人类完全无法看见的红外信号影射为遥控器上的一个个按钮,这样人们只需要操作按钮就可以由遥控器转化为红外信号指挥空调操作。
因此,我们可以将操作码(OPCode)类比为空调用于通信的红外信号。
氮气——中央处理器加速技术解密
氮气,作为超级跑车在赛道上扭转乾坤的利器,可以将引擎的最后一点潜能完全压榨出来,以此获得爆裂般的加速。而CPU作为对速度有更高要求的计算机核心部件,对于速度的追求自然是用户以及工程师们的终极梦想,因此各个实验室的工程师们也必将为此绞尽脑汁……
本段我们就以Intel CPU的发展为例为各位同学简要阐述一下CPU中的“氮气”加速技术是怎么一点点被开发出来的。
原始级,蛮荒状态-1987年
Intel在1978-06-08创造了8086处理器,这时处理器的执行流程非常简单,就是从内存中读取操作码后将操作码译码解析成微指令,并由微指令驱动逻辑电路去完成具体计算操作,然后再读取下一条指令。
以上操作可被概括为取指令、译码和执行这三步,而且每次都要等到这三个步骤都完成后才能执行下一条指令。
上古级,指令缓存-1982年
由于CPU的执行速度远高于内存的读取速度,因此Intel发现整个CPU的性能瓶颈出现在内存读取这一环节上。而又因为绝大多数指令编译的操作码仅几个字节大小,所以Intel在1982年发布了一款新CPU 80186,并且增加了指令缓存机制。
80186拥有一个6字节的指令缓存器,在每次剩余空间大于等于3字节时,80186就会自动提前将下一条指令从内存中读取进来,进而大大降低了操作码的读取延迟。
古代级,数据缓存-1985年
由于指令缓存机制在80186上取得了巨大成功,因此Intel在1985年发布的80386上面将指令缓存提高到了最大8KB,相较80186增加了1300余倍,并增加了数据缓存机制。
除此之外,Intel为了进一步降低因内存读取而造成的高延时,还为80386增加了最高64KB的数据缓存,使得80386有能力预先将一部分数据从内存读取到CPU的数据缓存区域,从而极大的降低因为CPU需要频繁访问内存而造成的延迟,例如:
int nArray[100] = {1,2,3,4,5,6,7,8,9,10, ... };
for (int i=0; i<100; i++)
printf("%02d ", nArray); // 重复访问100次数组nArray
以上这段代码编译运行后,我们会发现访问数组的速度特别快,其主要原因就是数据缓存起到的作用。应用程序以为它是在访问物理内存中的一块栈空间的内容,而实际上它是在访问CPU的数据缓存。
近代级,多流水线-1989年
由于内存的延迟已经被Intel在80386上尽可能的优化,因此Intel的工程师们这一次将优化的目光锁定在指令执行的流程上,他们首先将指令的执行细分为五个步骤,分别为:
Step1:取指令,将操作码从指令缓存中取出;
Step2:译码,将操作吗翻译为具体的微指令;
Step3:转址,将内存地址和偏移进行转换;
Step4:执行,指令在该阶段真正执行运算(由微指令控制硬件逻辑电路去完成);
Step5:退出,将执行结果写回到寄存器或者内存。
一个指令必须要经过这5步才能执行完成,而CPU执行这5步所需要占用的CPU时间就被称之为这条指令执行所需的时钟周期,需要时钟周期越短的指令,其在一秒钟内可以执行的次数就越多,效率就越高。
而Intel工程师之所以将一条指令的执行分为以上5个步骤,就是因为在绝大多数情况下以上五步可以被并行执行。也就是说第一条指令在Step4处执行时,第二条指令可以在Step3执行,而第三条指令则可能在Step2中被执行,这样每一步都像是一条流水线上的工人,而分为5步就可以被看作一个指令被5个工人分别处理,因此理论上来讲,在同一时间内,这条拥有5个工人的五级流水线可以同时并行执行5条指令,而需要占用的CPU时间相对于以前执行一条指令来说并未因此有太大的增加,具体如下图所示。
Intel在1989年第一次将五级流水线技术应用到了80486处理器中,使得新处理器在频率仅为上代一倍多的情况下获得了数倍于上代CPU的理论执行速度。
现代级,超流水线-1993年
既然流水线这么强悍,那么为什么不多搞一些呢?其实Intel的工程师们也是这么想的,因此Intel在1993年推出的首代奔腾(因为586这个代号被占用,所以启用了新名字Pentium)处理器时,第一次将超标量流水线结构应用到自己的产品中。
新款奔腾处理器的超标量流水线由两条五级流水线构成,但是限于一些底层逻辑限制,第二条流水线能够执行的指令类别有所受限,并且在遇到类似于JMP、CALL等转移指令时会使得第二条流水线失效,但是即便如此,启用超流水线结构的CPU也比其他同等工况下快了近1倍。
次代级,乱序执行-1995年
通过流水线的优化让Intel的工程师们尝到了甜头,但是因为程序代码的前后顺序逻辑等问题,在增加过多的流水线对于指令的执行速度不会再有明显的提高,因此Intel的工程师们将优化目标锚定在流水线本身逻辑的修改及加强上。
通过了解多级流水线可知,如果执行指令时各环节工况基本一致,那么越靠后处理的操作码所需的绝对执行时间就越长。那么能否将译码时间长但执行时间短,和一条译码时间短但执行时间长的指令合并为前后两条进行执行呢,因为这样就可以极大的利用好流水线中的每一级,如下图所示。
Intel在1995年推出的奔腾Pro处理器中首次应用了可以极大改进流水线工作效率的乱序执行(Out-of-Order, OOO)技术,并且为了缓解因JMP、JNZ等转移指令对超标量流水线的影响而推出了指令预测(猜测执行/分支预测)技术,这两种技术的出现使得Intel的流水线已经被优化到了极致。除此之外,奔腾Pro更是将原先的五级流水线升级到了12级,这使得奔腾Pro处理器中的每条流水线理论上可同时执行12条指令。
经过如此优化的流水线已经明显不符合当时的主流情况,进而导致奔腾Pro上的流水线在大多数情况下实际是在等待新指令的传入,而正是由于Intel这次跨时代的流水线优化,使其早在23年前便为今天的漏洞埋下了祸根,并且使其养成了挤牙膏的坏习惯,看来车开的太快果然容易出问题。
后现代级,超线程-2002年
由于上次乱序执行与指令预测的双剑合璧,使得CPU处理指令的速度飙涨,进而导致指令被执行的速度比处理器能够提供指令的速度更快,因此CPU的超标量流水线部件在大部分时间处于空闲状态。为了让整套流水线部件能够完全发挥其应有的作用,Intel在2002年为奔腾4处理器加入了第二套前端部件(例如寄存器、译码器等),这样对于操作系统来说,它就能看到两个处理器了。这样来自两套前端部件的所有的指令被一个共享的流水线部件执行,进而充分的发挥了其本来作用,而这种技术就被称之为超线程。
熔毁——摧毁虚拟世界的权限长城
计算机权限的核心基础就是将内存赋予了不同的权限属性,例如运行于用户层(RING3,3层)的代码是不能访问内核层(RING0,0层)的,如果不是这样,那么任意一个用户层程序都可以通过修改内核层的数据间接控制操作系统,进而随意控制整个权限控制系统。由此可见,内存的边界如果不存在了,其后果是多么可怕。
而通过我们上一节“次代级,乱序执行-1995年”这部分的分享可知,Intel在1995年开挂一样为他的CPU增加了两个新功能,分别为乱序执行与指令预测,而正是由于这两项开挂般的流水线优化功能导致了这个开挂般的漏洞。
首先,Intel为了使得乱序执行能够发挥全部效能,因此为了避免性能损失,在其将内存数据读入到数据缓存时并没有做任何权限检查。这点其实是没有问题的,因为数据所在的内存属于计算机体系结构,而读入的数据缓存则属于微体系结构,只要CPU在返回处理结果之前(例如将处理结果写入外部可访问的寄存器或内存)没忘记做权限检查即可。而实际Intel的CPU也是这么做的,其CPU内部的缓存无法被CPU之外的任何外部代码读取(包括内核态代码与用户态代码),并且在将外部数据读入到缓存中时也不做任何权限检查,而是在将处理结果写回到外部内存或寄存器之前才会做权限检查(但这时某些数据已经被读入到缓存中了)。
除此之外,Intel的指令预测功能的逻辑也非常简单,它判断的就是上一次执行这个条件跳转时是跳向了哪里,那么这次它就认为仍然会跳向那里。不要看它逻辑简单,但是却非常实用,因为CPU执行的绝大多数操作都是循环,而循环的特点是每次执行的代码其实都是一样的,仅仅是处理的数据每次有些许差别,所以Intel的这个指令预测的命中率据说可以达到80% 。
其次,既然Intel做数据缓存时没做权限检查,而且指令预测功能又这么简单,那么我们可以不可搞点事情呢?让我们一起来想想以下场景……
我们通过循环执行某写代码而使得CPU的指令预测认为我们下次仍然要执行某指令,而实际在某一次之后其内部的执行细节已经发生改变,原本不会出错的倒数第二条指令执行后将会出错,原本正常读取数据的倒数第一条指令在最后一次则试图读取的是内核内存。
这样,根据CPU的流水线以及数据缓存机制,CPU在执行倒数第二条即将出现错误的指令之前就已经将其后面的倒数第一条要读取内核内存的指令准备妥帖了,也就是说,最后一条指令想要读取的内核内存数据此时已经被CPU预先加载到其缓存中,并且没有做权限检查。
而由于CPU在执行倒数第二条指令时就会出错,因此根本就不会再试图执行倒数第一条指令,但是这时CPU的数据缓存中却保存着未经权限检查而在内核内存中读取出来的数据。但是由于CPU的数据缓存是外部不可读取的,因此事情如果仅仅到这一步的话是没有任何问题的。
最后,因为CPU所有加载到缓存中的数据都可以在用户层通过一个内存地址访问,因此黑客们这时可以遍历一下所有可能对应的内存块,利用内存访问与缓存访问的速度差异可以判断哪个内存块是在缓存中的,而非法读取的内核数据是有意与内存块对应的,因此原本在用户模式下不能访问的内核数据就被推算出来,这就构成了一次侧信道攻击(Side Channel Attack, SCA)。
此次处理器漏洞主要是由以下三个漏洞组合而成的:
CVE-2017-5754(别名熔毁“Meltdown”):恶意的数据缓存载入漏洞
CVE-2017-5753 (别名幽灵一号“Spectre Variant 1”):绕过边界检查漏洞
CVE-2017-5715(别名幽灵二号“Spectre Variant 2”):分支目标注入漏洞
锡安——屡次被黑客攻破的圣盔谷
锡安,作为《黑客帝国》中人类的最后一个核心基地,圣盔谷,作为《魔戒》中东土世界中最为坚固的堡垒,被分别用以指代Intel CPU本身以及其坚固的防御系统实在是再恰当不过了。
然而越是重要价值越大,引起的后果就越严重,下面我就为各位读者罗列一下CPU的Bug史:
1994年:奔腾处理器被爆FDIV Bug,导致的直接结果就是带小数的除法会被算错;
2000年:奔腾3的“矿渣”Bug,Intel为了与AMD抗衡通过默认加电压超频的方式进行,带来了巨大的稳定性问题,最后Intel回收了这部分CPU,并将其做成了钥匙扣;
2004年:奔腾4的90nm工艺漏电Bug,使得CPU巨热无比只能降频使用,Intel从此不再谈奔腾4架构是为了10GHz做准备的豪言壮语;
2007年:AMD翼龙处理器的TLB Bug,会使得物理内存与虚拟内存的映射表丢失,进而导致死机;
2011年:AMD推土机结构重构了x86架构设计,采用的长管线设计使得其能耗飙升,造成了高频低能的奇观;
2015年:Intel Broadwell架构因SpeedStep引发的BDM101/BDM86错误,导致在开启SpeedStep的电脑上运行密集运算程序是会导致系统蓝屏死机;
2018年:涉及多家处理器的熔毁漏洞与幽灵漏洞;
2021年:当年5月,让我们静静等待下个漏洞的到来,看看我预测的准不准。
结尾——对于底层黑客技术的迷思
随着信息时代的逐渐深入,人类社会对于电子化设备的依赖越发严重,每过一年都会有更多的宝贵的信息存储在电子设备中,因此电子设备中所蕴含的价值也在以几何倍数增加,人类社会势必会将越来越多的资源倾斜到保护信息安全的工作中去。
由于电子化产品天生易于复制传播的特点,随着人类社会整体防御水平逐步提高,原本很多并没有很高防御水平的节点会随着设备及系统的更新被动的获得最先进的防御。这会直接导致信息安全领域的后来者学习门槛逐渐提高,进而筛选出更加优秀的人进入行业内部,反过来在推动整个行业的发展。
此次处理器漏洞就是一个很好的例证,虽然这次攻击的实施以及攻击原理本身都不复杂,但这是一次深入到处理结构内部的攻击,发现这个漏洞的人势必对于芯片设计以及微体系结构有比较深入了解,同时又具备深厚的信息安全素养。随着人类社会信息安全产业的逐步发展,这种底层跨界组合的人才将会持续给我们带来更多惊喜。
因此,这次处理器漏洞带给我最大的启发就是——跨界发展,跨界攻击将成为趋势。
附录1-参考资料:
[1] 安天针对处理器A级漏洞Meltdown(熔毁)和Spectre(幽灵)分析报告
[2] Kernel-memory-leaking Intel processor design flaw forces Linux, Windows redesign
[3] Google: Almost All CPUs Since 1995 Vulnerable To "Meltdown" And "Spectre" Flaws
[4] Meltdown and Spectre
[5] Multiple CPUs - 'Spectre' Information Disclosure (PoC)
[6] CVE - CVE-2017-5754
[7] CVE - CVE-2017-5753
[8] CVE - CVE-2017-5715
附录2-关于十五派:
十五派(15PB)是一个依托于卓越的研发团队和丰富的集训管理经验,为个人、公司、高校提供定制化信息安全技术教育解决方案的专业团队,十五派(15PB)隶属于北京蓝森科技有限公司旗下,是国内第一个信息安全教育品牌。 |
评分
-
查看全部评分
|