目录
- 一、系统安全现状
- 二、攻防演化
- 三、代码注入攻防
- 1、通过内核漏洞
- 2、系统控制能力大
- 3、多见于早期Linux
- 4、内核代码注入防护
- 5、通过内核页表来实现
- 6、通过隔离环境保护内核页表
- 四、内核代码重用攻击
- 五、内核数据攻击
- 1、控制数据被保护后,攻击者提出非控制数据攻击
- 2、非控制数据防护
- 六、内核攻防演化
- 1、攻击演化
- 2、防护演化
- 3、防护方案的滞后性
- 4、最近几年的攻击方式总结
- 七、容器介绍
- 1、什么是容器
- 2、 操作系统级虚拟化
- 3、具有效率高、启动快、配置灵活等特点
- 3、由namespaces负责隔离
- 4、由control groups进行限制
- 5、容器资源隔离
- 6、容器资源隔离安全性分析
- 八、内存计数问题
- 1、内核依赖memcg对内存进行计数
- 2、memcg未经系统性安全分析,存在安全隐患
- 3、我们的工作
- 4、发现了policy design中导致的计数缺失的问题
- 5、设计基于编译器的自动化分析工具
- 6、内核安全性在对抗中大幅提升,但对数据攻击防护依然不足
- 7、容器场景给内核带来了新的机遇,也带来了新的安全挑战
一、系统安全现状
首先我们来看一下系统安全,特别是系统安全的现状,这是Linux2008~2019年的内核代码的数量,然后到2019年已经超过2300万行,现在我们的最新统计数据是将近2800万行代码。
另一方面如果我们只看Linux内核,我们觉得它的代码量挺高的,但是我们如果把它放到整个安卓的生态里面来看,其实它只是在很小的一部分,在Linux内核之上,还有Hal hardware abstraction there
这一层,上面还有Android的run time
层,再往上面有安装的framework
,还有applications
。
二、攻防演化
代码量跟bug的数量或者说跟漏洞的数量它是成正比的,代码量越多,它的bug漏洞数目也会越大,所以这是Linux内核的一些现状。在最近一些年,它里面的bug数量每年都超过125,这都是Linux内核里边可以被利用的bug数量,代码量巨大就会导致新的漏洞,所以软件漏洞无法避免,这些软件漏洞往往会被攻击者利用,这就会产生新型的攻击。
另一方面,新型的攻击又催生了新型的防护,所以对操作系统内核的攻防是在不断的对抗中演化升级的,它的攻防不是静态的,不是一下子就能全部防住的,它是在不断对抗中演化升级,所以没有绝对安全的系统,也没有绝对强的攻击手段,他们都是相对在演化,所以我们有一张这样的图,如果来看我们攻防演化,我们按照这个手段对它进行分类的话,首先是代码注入攻击,然后防护代码注入攻击, 研究人员提出了带数据不可执行,然后对进行防护。
攻击者发现他的攻击手段被防护了之后,进而提出了代码重用攻击,然后安全研究人员又提出了新型的防护,叫控制类完整性进行部分防护。在这之后攻击者又提出了数据攻击,而现在我们又提出了这个数据有完整性一些保护。
三、代码注入攻防
1、通过内核漏洞
- 篡改已有代码
text section
- 注入新的代码
- 或者跳到用户代码,比如
jump-to-user
2、系统控制能力大
- 可执行新代码
- 危害大
3、多见于早期Linux
- 比如
Kernel Text RWX (Android 2013)
4、内核代码注入防护
- 保护已有代码
W^X
- 硬件支持,杜绝注入
- 数据不可执行(
2001 XN ARM; NX AMD
) - 特权不可执行(
2011 SMEP Intel; PXN ARM
)
5、通过内核页表来实现
- 在内核页表设置相应的保护位,实现保护
- 多数Android设备, 包含Google Pixel
- 防御性弱,内核页表被改掉即失效
- 对内核页表没有保护
- 攻击者可篡改页表,去掉保护
- 进而篡改代码
6、通过隔离环境保护内核页表
- 通过隔离环境,避免内核漏洞影响
- 实现了纵深防御
defense-in-depth
四、内核代码重用攻击
无法注入新代码,重用已有代码,通过篡改控制流,拼接已有函数片段,实现攻击函数,也被称为控制流劫持攻击。
五、内核数据攻击
1、控制数据被保护后,攻击者提出非控制数据攻击
- 返回地址和函数指针以外的数据
- Data-oriented programming
- 影响关键的安全特性
- 仅利用非控制数据攻击做到内核提权
2、非控制数据防护
非控制数据攻击的一个例子就是s一Linux绕过,在Linux内核的代码44.4版本里发现一个全局变量,如果是0,就会永远是真,所以就永远绕过,攻击者一般拿到这个之后,获得了内存的读写权限,首先把变量写成0,Linux的所有检查都会绕过,但是现在对于非控制数据还没有很好的有效防护,所以现在主流的操作系统也都没有部署对数据攻击的有效防护。
六、内核攻防演化
1、攻击演化
它的攻击复杂性在指数增进,同时它的隐蔽性也在增加,代码注入工具很容易被检测,因为它改了代码或者增加了代码,代码重用攻击只改了written Reiss
的方向,所以它已经比较难检测,而数据攻击就更难检测,这么多数据,你根本不知道哪些被篡改。
虽然这个攻击的难度在增加,但对于我们比较有利的是它的控制能力却在减少,代码注入攻击能力最强,代码注入攻击可以拼接代码片段,也可以做到图例完整。
数据攻击就只能通过筛选数据,并且你的攻击范围只能是数据控制的一些代码,所以它的控制能力在减弱,但是它依然能够入侵操作系统内核,依然能够做到权限提升,所以数据攻击危害性还是很大。
2、防护演化
防护方面的演化,每一个攻击出来,首先都会提出一些防护的方案和解决思路,并且一般都是通过一些学术论文发表,大家提出的防护方案,后续这些学术的原型软件的方案通过沉淀,通过不断的优化,硬件厂商会把它做到硬件化,比如说后面会有一些AMD
或者intel
,会把它真正的实现到硬件里面来提供支持。
硬件首先能提高安全性,其次能减少性能开销,所以一般硬件被防护机制支持后,这种安全机制一般会大规模的商用,这就是防护的研发趋势,从软件到硬件,从学术界的原型到产业界的实用方案。
3、防护方案的滞后性
对于代码注入攻击,最早是在1988年出现的, 到2001年才有硬件的防护方案,所以滞后13年,代码重用攻击滞后17年,而数据攻击到现在还没有很好的防护方案,所以它的滞后性肯定会更多。
4、最近几年的攻击方式总结
下面对攻击方法进行一个总结,这是最近几年的一些总结,蓝色的是代码重用攻击,红色的是数据攻击。这里面我们可以看到代码注入攻击已经很少了,一些比较有名的论文,都是基于代码重用攻击或者数据攻击的。
这里面每一个有图标的都是一个真实的攻击案例。
我们总结一下防御的方法,防御的方法就是内存的安全问题,主要可以归为两类,一个是越界的独,一个是越界的写。
越界的读,如果它读了不该读到的数据,就会造成一个Information
。越界的写,如果他写代码的话,它就是代码输入攻击,如果他写控制数据,它就是代码重用攻击,也要控制这个攻击,如果他写非控制数据的话,叫面向数据,这是传统的系统内核攻防的演化,现在这个容器应用更加广泛了,容操系统在容器的场景下,面临一些特殊的安全挑战。
七、容器介绍
1、什么是容器
容器是操作系统级虚拟化,它是由同一个内核虚拟出来多个用户空间的实例,每个用户空间的实例,不需要维护单纯的内核,用户空间的实例,也叫容器实例,它不用单独维护内核,所以它效率高,启动快,并且配置比较灵活,会被广泛应用于代码。
2、 操作系统级虚拟化
由同一内核虚拟出多个用户空间实例,无需维护单独内核
3、具有效率高、启动快、配置灵活等特点
3、由namespaces负责隔离
首先是提供了namespace
,它负责隔离,namespace
相当于镜像。如果我们说一种资源,它被namespace
的,就说这个资源在容器看到的跟 Linux内核外边看到的是不一样的,相当于给容器一个单独的镜像,现在内核支持了8种namespace
,这叫资源的限制,叫control group
,它可以限制CPU,可以限制内存,可以限制一些设备资源,它可以限制你用了多少CPU,用了多少内存,对IO的访问速度是多少。
4、由control groups进行限制
- 当前内核支持13种cgroups
- 主要用于限制CPU、内存和设备资源
5、容器资源隔离
(1)本质是基于进程的资源隔离
- +namespaces and cgroups
(2)进程能access哪些内核资源
- Kernel text
- Global data
- Heap
- Stack
- Kernel provides 300+ syscalls
6、容器资源隔离安全性分析
- 当前容器注重限制物理资源,忽略抽象资源,如内核变量
- 我们发现这些抽象资源同样可以被DoS攻击
- 例如打开大量文件,耗尽
nr_files
- 所有新打开文件操作均会失败,导致无法运行新程序
这些内核数据同样决定操作系统功能的可用性,容易导致DoS攻击,内核data dependency
复杂,难以彻底解决DoS问题,高安全性要求场景建议使用虚拟机隔离。
八、内存计数问题
1、内核依赖memcg对内存进行计数
2、memcg未经系统性安全分析,存在安全隐患
3、我们的工作
- 形式化定义了内存计数的步骤
- 分析了
policy design
的问题 - 设计自动化工具分析
implementation
问题
4、发现了policy design中导致的计数缺失的问题
攻击者可以轻易突破memcg内存限制
5、设计基于编译器的自动化分析工具
对policy implementation
进行系统性分析
6、内核安全性在对抗中大幅提升,但对数据攻击防护依然不足
- 代码注入攻击
- 代码重用攻击
- 数据攻击
7、容器场景给内核带来了新的机遇,也带来了新的安全挑战
- 抽象资源攻击
- 内存计数问题
上一篇:【Java 多线程 7】通过socket、多线程、动态代理、反射 实现RPC远程方法调用
下一篇:Java学习路线总结,搬砖工逆袭Java架构师