Page 275 - 《软件学报》2020年第11期
P. 275

3590                                Journal of Software  软件学报 Vol.31, No.11, November 2020

                 循预先定义好的 CFG,以确保程序控制流不被劫持或非法篡改.具体做法是,在分支指令前插入检测代码来判断
                 目标地址的合法性.CFI 技术分为细粒度和粗粒度两种类型.
                             [5]
                    Abadi 等人 提出了最早的细粒度 CFI 技术,该技术预先计算出所有间接分支指令可能的目标地址,并为之
                 赋予唯一的 ID;在每条间接跳转指令执行前插入检测代码,判断 ID 是否合法,一旦发现违反 CFG 的间接分支就
                                       [6]
                 会被识别为攻击.Abadi 等人 利用 CFI 思想保证控制流的正确性,并结合内存访问控制、影子栈等,在运行时对
                 传统的应用程序提供保护与监控.虽然细粒度的 CFI 技术针对所有分支进行检测,能够提升系统的安全性,但其
                 性能开销超过 15%,难以得到实际部署.
                    粗粒度的 CFI 技术将一组相同或相近类型的目标归到一起进行检测,可在一定程度上降低性能开销.Zhang
                    [7]
                 等人 提出了 CCFIR 方法,该方法对间接 call 指令和 ret 指令的目标进行区分,阻止未经验证的 ret 指令跳转到
                                       [8]
                 敏感函数的行为.Zhang 等人 提出了 binCFI,该方法将间接分支指令的操作数分为代码指针、异常处理程序入
                 口和返回地址等类型,通过精细的静态分析,得到不同类型间接分支指令的合法目标集合,并基于此进行攻击检
                                 [9]
                 测.Mashtizadeh 等人 提出了 CCFI 方法对代码指针进行更细致的划分,该方法将代码指针细分为函数指针
                 类、返回指针类、异常处理函数指针类、虚表指针类,通过对代码指针进行加密来增强 CFI 方法.以上方法都
                 是只实施了控制流不敏感策略,然而上下文信息的缺少会降低方法的有效性.因此,Veen 等人                              [10] 提出了上下文
                 敏感的 CFI 技术,该方法能够监控通往敏感函数(可用于实施控制流劫持攻击)的执行路径,通过使用二进制插桩
                 技术,在被监控路径上强制执行上下文敏感的不变量.
                    以上这些粗粒度 CFI 技术都需要修改源码或者通过反汇编重写二进制代码(通常需要依赖调试信息以保
                 证其正确性),这给这些技术的使用带来了额外的限制.本文提出的 MIBChecker 方法直接利用硬件获取运行时
                 信息进行检测,不依赖于源码及调试信息,可以直接作用于传统二进制程序.
                    此外,一些研究通过利用现有硬件机制来降低 CFI 技术的性能开销.Pappas 等人提出了 kBouncer 方法                        [11] ,
                 该方法利用 LBR 捕获最近的 16 次分支信息,在系统调用处对捕获的 16 次分支进行安全性检测.Cheng 等人提
                 出了 ROPecker 方法  [12] ,该方法也是利用 LBR 捕获程序控制流信息的方式进行 ROP 攻击检测.该方法在运行时
                 检测过去和未来的执行流中是否存在长 gadgets-chain 来进行攻击检测,还通过滑动窗口的机制来进一步提高
                 准确性和高效性.但是,这两种方法都是一次性针对整个 LBR 进行检测,会面临历史刷新问题,容易遭受历史刷
                 新攻击  [13] .Xia 等人提出了 CFIMon [14] ,该方法采用 BTS(branch trace store)机制来捕获程序运行过程中分支指令
                 的信息.虽然 BTS 能够将程序整个执行过程中的所有分支指令的历史信息都记录下来,但相比于 LBR,使用 BTS
                 会引入更大的性能开销.此外,以上 3 种方法均是针对长 gadgets-chain 的 ROP 攻击进行检测,对于由短 gadgets-
                 chain 进行的规避攻击检测效果不佳.
                    本文提出的 MIBChecker 方法针对每个预测失败的间接分支立即从 LBR 获取当前分支信息进行检测,能够
                 从根源上避免 LBR 历史刷新攻击问题.进一步的,本方法提出了系统调用参数检测方法,能够有效地检测出通过
                 短 gadgets-chain 进行的规避攻击.
                    除了利用现有硬件技术以外,一些研究还通过设计自身硬件来进行 CFI 检测,此类方法通常通过硬件影子
                 栈以及扩展新的指令集来实现 CFI 检测策略              [15] ,或者通过修改分支指令的硬件逻辑来限制跳转目标,如限制函
                 数间的跳转    [16] 、限定跳转目标为基本代码块的开始           [17] 等.此类方法能够降低性能开销,但都需要新的硬件来支
                 持,短期内难以推广,实用性较差.
                    除了 CFI 方法,另一个 ROP 攻击防御方面的研究热点是随机化技术                   [18−22] ,该类技术通过将函数、内存页、
                 基础块或指令排布等随机化,让攻击者难以准确预测所需 gadget 的位置,进而无法进行 ROP 攻击.该类方法主要
                 提供概率性保护,能够增大攻击的难度,本文的方法可以和这类方法一起作用,用于阻止攻击者对应用程序进行
                 ROP 攻击.

                 2    MIBChecker——基于硬件分支信息的 ROP 攻击检测方法

                    本文提出了 MIBChecker 方法,该方法的基本原理如图 1 所示.
   270   271   272   273   274   275   276   277   278   279   280