漏洞利用检测的杀器:控制流完整性检测 (CFI)

控制流完整性检测的核心思想是限制程序运行中的控制转移,使之始终处于原有的控制流图所限定的范围内。

漏洞利用检测的杀器:控制流完整性检测 (CFI)

1 控制流劫持攻击是什么?

控制流劫持攻击简单的来说就是二进制漏洞的利用,它是一种常见的针对计算机软件的攻击,给计算机系统安全带来了巨大的危害。控制流劫持攻击通过构造特定攻击载体,利用缓冲区溢出等软件漏洞,非法篡改进程中的控制数据,从而改变进程的控制流程并执行特定恶意代码,达到攻击目的。

一旦攻击者能够通过它来获取目标机器的控制权,甚至进行提权操作,对目标机器进行全面控制。当攻击者掌握了被攻击程序的内存错误漏洞后,一般会考虑发起控制流劫持攻击。

早期的攻击通常采用代码注入的方式,通过上载一段代码,将控制转向这段代码执行。为了阻止这类攻击,后来的计算机系统中都基本上都部署了 DEP(Data Execution Prevention) 机制, 通过限定内存页不能同时具备写权限和执行权限,来阻止攻击者所上载的代码的执行。

自 1988 年 Morries 利用缓冲区溢出漏洞编写蠕虫病毒瘫痪了大量网络计算机以来,控制流劫持攻击就层出不穷。为了防止这种攻击方式的发生,现在的计算机系统中都基本上都部署 了 DEP(Data Execution Prevention) 机制, 通过限定内存页不能同时具备写权限和执行权限,来阻止攻击者所上载的代码的执行。为了突破 DEP 的防御,攻击者又探索出了代码重用攻击方式,也就是利用被攻击程序中的代码片段,进行拼接以形成攻击逻辑,包括 Return-to-libc、ROP(Return Oriented Programming)、 JOP(Jump Oriented Programming)等。

为了抵御控制流劫持攻击,加州大学和微软公司于 2005 年提出了控制流完整性(Control Flow Integrity, 以下简称为CFI)的防御机制。

漏洞利用检测的杀器:控制流完整性检测 (CFI)

2 控制流完整性检测

控制流完整性检测的核心思想是限制程序运行中的控制转移,使之始终处于原有的控制流图所限定的范围内。

具体做法是通过分析程序的 控制流图,获取间接转移指令(包括间接跳转、间接调用和函数返回指令)目标的白名单,并在运行过程中,核对间接转移指令的目标是否在白名单中。

漏洞利用检测的杀器:控制流完整性检测 (CFI)

控制流劫持攻击往往会违背原有的控制流图,控制流完整性检测 使得这种攻击行为难以实现,从而保障软件系统的安全。

控制流完整性检测的概念自提出以来,被业界广泛关注和研究,已经出现几十种不同的控制流完整性检测方法,各有各的优势。这些控制流完整性检测方法的研究重点,主要是在程序进行运行时检查的过程中能保证较低的运行时开销,同时又能保证极高的安全性,保证程序不会受控制流劫持攻击。

控制流完整性检测分为粗粒度和细粒度两种方式,细粒度控制流完整性检测 严格控制每一个间接转移指令的转移目标,这种精细的检查,在现有的系统环境中,通常会引入很大的开销。

粗粒度控制流完整性检测则是将一组类似或相近类型的目标归到一起进行检查,以降低开销,但这种方法会导致安全性的下降。

3 如何进行控制流完整性检测

现在业内主要用的方法是插桩。这边举一个简单的小栗子来说明完整性检测的方式。

以下图展示了该示例代码的控制流图为栗,其中每个节点表示一个基本块,且已被标号。

漏洞利用检测的杀器:控制流完整性检测 (CFI)

基本块 9 对应源码第 18 行语句,其终止指令是间接分支指令,目标基本块为基本块 10(即调用函数 funcA)或基本块 11(即调用函数 funcB)。函数 funcC被运行时,可能存在多条有效的执行路径。例如当参数 input 为 3 时,则有效的执行路径(路径 A)为:

1 → 2 → 4 → 6 → 7 → 1 → 2 → 4 → 6 → 8 → 1 → 2 → 3 → 9 → 10

执行路径 A 的控制流信息能够在线下分析阶段就能获得。在运行时阶段,当到达间接分支时,利用先前已执行的路径信息可以确定当前间接分支的目标地址。例如,当程序按照执行路径 A 执行达到基本块 9 时,则其合法的后续基本块必定为基本块 10。基本块 11 及其它基本块都是不合法的后续基本块。

如果采用上下文敏感的控制流完整性检测,当不考虑用户输入数据的时候,可以确定对于具体的一条路径,间接分支的目标可以唯一确定。在实际情况中,程序中可能包含许多未初始化的变量,但间接分支变量不会由未初始化的变量直接或间接计算得到。否则将导致目标地址的不确定,最终甚至有可能导致段错误。此外,来自用户或系统的外来数据也不可能参与计算间接分支指令的目标地址。

因为由于 ASLR 的实施,用户与外部系统不可能知道目标指令地址的真实地址。因此,在讨论间接分支的目标地址时,未初始化数据和外部输入数据可暂时忽略。

控制流完整性检测在运行时检测程序的控制转移是否在控制流图中,以识别是否遭遇了攻击。具体作法是在控制流转移指令前插入检验代码,来判断目标地 址的合法性。这种做法能够对控制流劫持攻击起到防御作用,但是也存在一些问题。严格意义上的 CFI,需要做到对每条间接控制转移都做检查,并确保每条转移指令只能转移到它自身的目标集合。如果要达到更好的防御效果,则要做到上下文敏感的检查。然而,这种检查机制虽然能够最大程度地提升系统的安全性,但其开销过大,难以得到实际部署。

4 总结

本文科普了控制流劫持以及控制流完整性检测的基本概念和知识。从 2005 年控制流完整性检测 技术被提出,控制流完整性检测 技术已经历经了 10 多年的发展。近两年涌现出的大量 控制流完整性检测 相关的研究工作,极大推进了控制流完整性检测技术的发展。但是,CFI技术未来仍有很大的发展空间,需要实现一种高可靠、低开销的控制流完整性检测技术。

声明:本文来自山石网科安全技术研究院,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。

版权归原作者所有,如若转载,请注明出处:https://www.ciocso.com/article/356.html

发表评论

登录后才能评论
跳至工具栏