首页
社区
课程
招聘
[原创] Let's GoSSIP 软件安全暑期学校 Day 1
发表于: 2019-7-21 10:26 3166

[原创] Let's GoSSIP 软件安全暑期学校 Day 1

2019-7-21 10:26
3166

Let's GoSSIP 软件安全暑期学校 2019 第一日

 

早上八点钟来到上海交通大学闵行校区的微电子学院大楼,便可以看到报告厅中已经有许多的同学与工作人员。

 

交大的李卷孺老师上台进行开幕式发言。 今年的GoSSIP汇聚了120余名注册学员,邀请了来自国内,北美与欧洲的知名安全研究人员作为讲师。五天的项目中,主题涵盖了侧信道攻击,安全开发,AI安全,嵌入式安全,网络安全,口令安全,硬件安全,漏洞挖掘等多个热门领域。

 

 

开幕式过后,俄亥俄州立大学的张殷乾教授,作为国际知名的侧信道安全研究人员,为同学们带来了第一个议题,你了解与不了解的侧信道攻击。议题的内容十分丰富,干货十足,在此我们只对其进行简单的概括。

 

 

张教授先对俄亥俄州立大学与自己所在的研究团队做出了介绍。议题的内容分为两个部分。

 

第一部分主要介绍了Micro-architecture中的侧信道攻击的相关概念。
所谓Micro-architecture, 是指对于软件来说不可见的硬件部分。而对其的侧信道攻击,便是指通过micro-architecture 从侧面对其进行信息泄露。

 

 

侧信道攻击可以被应用的场景有很多,比如说两个虚拟机共享同个CPU时,我们便可以使用其中一个对另一个发起侧信道攻击以获取敏感信息。

 

张教授从三个角度介绍了侧信道攻击:

攻击容器:

侧信道的攻击可以针对不同的容器。

 

比如,我们可以利用分支预测单元(Branch Prediction Unit, 也即BPU), 页表,TLB等单元。

攻击方法:

张教授主要介绍了以下两种攻击方法。

 

Prime Probe Attack:
攻击者先将一定个数的cache组填充,之后重新读取刚刚存取的地址,通过读取数据的时间便能够判断被evict的cache line 数量。

 

Flush Reload Attack:
攻击者先确保一个memory block 不在cache当中,之后等待受害者更新cache, 攻击者重新读取对应的memory block,以判断受害者有无调用某些数据。

 

两者如果相比较的话,Prime Probe方法不需要攻击者和受害者共享内存,更为通用。 而Flush Reload方法的使用前提是两者共享物理内存,因为flush 和reload过程都需要攻击者直接对目标内存进行访问,优点是该方法更具有指定性。

攻击维度:

所谓攻击维度是指,攻击者与受害者共享的资源是什么。当两者不共享同一个CPU Core时,侧信道攻击将会比较难以实现。


 

在第二部分中,张教授介绍了几种具体的侧信道攻击。

Spectre attack:

BPU会激进地对分支指令(JMP,CALL等)做出预测,并提前执行分支。如果在解析目标后,发现分支预测错误,提前执行的结果将会被抛弃,并重新执行。

 

简单的例子:

if(x>0) do A; else do B;

 

当x被从内存中读取之前,CPU便会基于历史对该分支进行预测,并执行所与猜测分支中的代码。

 

而当x被解析后,CPU会检查该预测的准确性,如准确,性能便因此得到了优化。反之,将会抛弃执行结果,并重新执行。

 

而我们便可以利用这一特性获取受害者内存空间中的敏感信息。我们先污染分支预测器,让其将做出我们所期望的预测。 之后,根据预测结果执行,比如。利用OOB的Index值读取敏感数据。接着通过侧信道攻击推测敏感数据。

Meltdown attack:

Meltdown attack,则是依赖于乱序执行。现代的CPU不仅会乱序地执行指令,在micro-architecture层面也会贪婪地并行执行操作。因此数据能在CPU发现错误前抵达。

 

一下是一段简单的meltdown 代码

//%rcx=kernel地址
//%rbx=convert-channel buffer地址
movzx (%rcx).%rax
shl $12,%rax
movq(%rbx,%rax,1),%rbx

 

此外,张教授还详细的介绍了针对Intel SGX的L1Terminal Fault, 以及比较前沿的RIDL漏洞。


 

午饭后,便开始了下午的议题。议题为百度X-Lab的孙茗珅博士带来的 Rust的奇幻之旅。

 

 

该议题围绕内存方面的问题,对Rust这个语言进行了介绍。

 

Rust是一门内存安全的系统编程语言,其中比较核心的概念为aliasing与mutation不能够同时存在,也即,只能同时读,不能同时写同一个数据。

 

以下为一些Rust保证内存安全的机制:

 

ownership:
一个变量拥有一块内存。

 

borrowing:
通常借出之后,借出者不能mutate这个变量。
如果使用mutable borrow的方法借出,原主人在归还前将不能进行mutate。保证aliasing与mutation不同时存在。

 

Lifetime:
每个指针持续范围都是受限的。

 

Rust的编译器将确保每一个资源都有独一无二的owner。被认为无法保证内存安全的代码将无法通过编译。

 

此后,孙博士介绍了受到广泛使用的TrustZone。TrustZone为移动电话和镶嵌式设备提供了受信任的执行环境。但是内存安全的问题打破了TrustZone对安全的保证。e.g. CVE-2015-6639。

 

由此作为动机,孙博士参与开发了Rust OP-TEE TrustZone SDK。该开源项目为TrustZone 提供了一套内存安全,且使用方便的SDK。
4ccK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6E0k6i4y4S2L8r3!0U0K9#2)9J5k6r3I4A6L8Y4g2^5i4K6u0r3M7Y4g2K6N6q4)9J5k6r3!0H3N6r3g2W2i4K6u0V1N6s2u0#2M7%4c8*7L8$3&6W2i4K6u0V1M7$3c8C8

 

最后,提到了Rust也可能是不安全的。我们可以使用unsafe关键字在Rust编程当中使用内存不安全的代码。我们可能会觉得,使用unsafe rust需要显式的使用关键字,因此并不构成安全问题,但事实不是这样。

 

用以下代码举个例子:

in library:
unsafe fn dangerous(){
  //something unsafe
}

fn safe(){
  unsafe(dangerous(); )
}
developer:
fn main(){
  safe();
}

 

我们可以看到,main函数中隐式的调用了unsafe代码。

 

在现在许多的Rust项目中,都存在由此带来的安全问题。


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

最后于 2019-7-21 22:48 被杭州猛男编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 4839
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
这个不错的
2019-7-22 09:36
0
游客
登录 | 注册 方可回帖
返回