天天动画片 > 八卦谈 > 关于CPU漏洞

关于CPU漏洞

八卦谈 佚名 2023-05-03 03:13:51

去年的熔断和幽灵漏洞闹得沸沸扬扬,现代处理器无一幸免,这两个漏洞也光荣的成为了史诗级漏洞。这回就来简单地分析一下熔断和幽灵漏洞。

要了解Spectre(幽灵)和Meltdown(熔断)漏洞之前,首先就需要理解一些现代cpu的知识。

CPU作为一台计算机系统的核心部件,其运算速度在几十年内突飞猛进,从上世纪30年代的大型真空管计算机1 ~ 800KHz,到70年代的10MHz速度,截止到文章发布,即使是一个低功耗的ARM处理器,只要是主流的机型,其时钟频率也有GHz级别,在x86领域,随便超5GHz,液氮8GHz也被硬件爱好者们津津乐道,程序的执行效率也已经非常高,现在的处理器每秒都能执行几十亿条指令,让过去想不到的事情,如模拟物理法则,模拟宇宙爆炸,进行大型规模高精度科学计算,都成为了可能。

天河二号
配置

                                   存储器

CPU作为核心部件,在计算机历史上可谓是突飞猛进发展,而我们知道,一台电脑除了cpu,还需要内存和硬盘(ram和rom(固态硬盘也是rom,eeprom))

当cpu开始工作时,硬盘的数据会经过PCH(所谓的南桥),然后再经过CPU,之后才被加载进内存开始执行。

结构

虽然cpu的执行速度十分的快,但由于半导体企业的综合考量,因此主内存(也就是我们所说的内存条和手机运存)被设计成了动态的(与cpu内部静态的寄存器相对)。

我们称之为DRAM,也就是动态随机存取存储器,原理是采用电容存储,通过间隔一段时间,就重新刷新内存,没有被刷新的电容就会丢失存储的数据。

这种简单高效的dram,一个bit只需要一个晶体管和一个电容即可完成,非常的节省成本,现代的内存很容易就能做到16GB,32GB,128GB的高容量,为容纳Chrome提供了充实的条件。

无论多大的内存在我面前一律占用80%

而cpu内部的寄存器就需要6个甚至更多的晶体管,成本是极其高昂的,并且功耗也比dram来的高,因此寄存器的数量很少,用来暂时保存程序运算。

借此,我们就能得出一个存储器结构,如下。

存储器结构

这个结构看上去似乎没有问题,但由于现代的处理器工作速度十分迅速,而主内存的速度却没有这么快,只有0~60GB/s的速度,并且容量又小,现代的操作系统,大型游戏动辄就是几十GB,而且,在一些有大量执行重复任务的程序里,显然对又慢又小的主内存来回写是浪费处理器的性能,借此,上世纪90年代,随着奔腾cpu的横空出世,介于主内存和处理器之间的缓冲区-缓存诞生了。

缓存,顾名思义,是作为缓冲区的一块内存,它虽然没有cpu的寄存器来的高速,但肯定要比主内存来的快,因此,cpu执行程序,不再是取主内存所存储的代码和数据,而是从缓存里取,如图↓

(Cache即缓存)

缓存基于局部性原理,什么是局部性原理呢?

处理器要执行程序,首先他会从缓存里寻找指令和数据,如果没有,就去内存读取,如果内存也没有,就去硬盘读取,如果硬盘也没有,就去远程服务器存储空间读取(当然,这需要更高级的操作系统的配合),如果都没有找到数据,那就不执行程序

1.处理器内部的寄存器,速度最快,处理器主要的数据处理场所也是寄存器,造价高昂,容量小(每一个通用寄存器只有8字节[四字]的大小)

2.处理器内部的Level 1缓存,通常被访问次数小于寄存器,简称L1缓存,L1缓存又分成两个部分,一个部分存储指令,一个部分存储数据,现在的x86处理器一般都是一个核心搭配32KB的L1缓存,指令和数据各一个。

3.L2缓存,用来做更大的数据缓冲区,容量更大,大小在2MB~8MB左右,被访问次数通常更低,并且速度更慢。

4.L3缓存,用于多个核心共享使用,做更大的数据缓冲区,大小在8MB~80MB都有,处理器厂商一般用产品线划分来决定一个处理器的L3缓存,同时L3缓存的大小也十分影响运行性能。

5.内存,硬盘,这些不用我多说了。

上面都是废话,下面才是重点:

程序想要访问某一部分的内存的时候,cpu首先会看这部分内存在不在缓存里面,如果有,那么就能快速得到数据,如果没有,就需要去内存里面找,速度就会慢一些,而这个时间差,是可以被利用来获取数据的

这就得了解另一个机制,叫内存分页,一些学过计算机的可能知道,计算机里面的基本单位是字节(Byte),千字节就是KiloByte(KB),百万字节就是MegaByte(MB),十亿字节就是GigaByte(GB)。。。。

如上面例子所说,当cpu在缓存里找不到数据时,就会从内存里,先获得数据,再放进缓存(方便程序接着继续用),而cpu为了加快放进缓存的进度,就把内存以4KB,1MB等容量,划分为一个单位,把数据放进缓存的时候,不是一个字节一个字节的放,而是一次放4kb,或者一次放1mb等等。。

以上,是熔断漏洞的几个要素罢了,而核心要素,在于cpu一个提升速度的根本要素:乱序执行!

现代cpu执行程序的代码的时候,其实并不是一条一条顺序执行(这样安全,但是不够快),为了提升速度,都是以三条代码,四条代码为单位,一批一批的丢进cpu,(Cpu会自动处理代码之间的先后关系,所以不会错乱的),不过有些时候,速度太快了,会执行一些涉及系统安全的非法代码,这些代码本身并不能被执行,但是cpu的执行逻辑是:先执行,后判断!

于是,结合以上因素,我们就得到了这段非常厉害的代码:

MOV RAX Byte PTR [Kernel]

注释:把Kernel(中文名内核),也就是系统内核的一个地址,里面的数据,以一个字节(Byte PTR),放到一个叫 RAX的寄存器

这段代码本来不应该被执行(因为涉及系统保护),但是因为cpu的乱序执行,导致这个代码会被执行

SHL RAX 0xC

注释:这是最重要的一行代码,意思是,把RAX这个寄存器的数据,向左移动0xC(12)个比特位,相当于是把这个寄存器的数据乘4096(2的12次方)

4096其实就是一个内存页的大小,从这里看出,攻击者要把数据转化为另一种形式

MOV RBX Qword PTR [RAX+RBX]

注释:RBX是一个可用的寄存器,存放的数据是合法的,不涉及系统隐私。

[RAX+RBX]的意思是什么呢?就是把RAX和RBX相加,把这个相加后的数值,转化为一个地址,并将这个地址里面的数据,以4个字(一个字是2字节,4字就是8字节)为单位,放进一个叫RBX的寄存器

这时候,核心的要点来了,如果RAX+RBX作为一个地址,这个地址不在内存里,那么CPU就会从内存里去找!并且放在缓存里面!!!!!!


上面三行代码,就是攻击的全部。


在执行后,CPU发现自己执行了涉及系统隐私的代码,会自动回滚之前的操作,把RAX RBX的数据都给摧毁掉,然而,这两个寄存器的值,虽然不以数据的形式存在了,但是还以一个内存页的形式存在于缓存里面,cpu不会去回滚缓存

接着是最后一步,挨个访问内存页,因为我们知道,如果一个内存页放在缓存里,那么cpu就可以更快得到数据,耗时会更短,这时候,只需要记录访问每一个内存页所需的时间,那么,所需时间最短的那个内存页的内存地址,就是RAX+RBX的值!!!

访问页所需时间

这时候,假设我们得到第X个内存页耗时间最短,如何还原出最先我们从系统里面获得的数据呢?

很简单,因为这个内存页的地址是RAX寄存器+RBX寄存器的值,那么我们只要知道RBX最开始的数值,和这个内存页的地址,我们就可以还原出RAX寄存器的值,用公式表达就是:

                     地址X - RBX的值 = RAX的值

看到这里,不得不佩服发现这个漏洞的团队,正是他们的发现,让人们第一次知道,CPU也是有漏洞的。

后来又陆陆续续发现了很多CPU漏洞,这些漏洞都是上面所说漏洞的变种,幽灵漏洞原理相似,不过利用的是分支预测(在我上一篇专栏有关于分支预测的内容)。


以上就是全部内容,如果你觉得有帮助,请点赞关注收藏。


本文标题:关于CPU漏洞 - 八卦谈
本文地址:www.ttdhp.com/article/29775.html

天天动画片声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
扫码关注我们