APP下载

基于返回地址签名的控制流攻击检测方法

2020-12-23余云飞汪鹏君张跃军张会红张海明

关键词:堆栈攻击者指令

余云飞, 汪鹏君,2, 张跃军, 张会红, 张海明

(1. 宁波大学电路与系统研究所,浙江 宁波 315211;2. 温州大学电气与电子工程学院,浙江 温州 325035)

微电子技术、物联网技术和大数据技术的发展,使得嵌入式系统已经成为各个领域中不可或缺的角色,其在日常生活、工业生产、交通运输、移动支付等领域发挥越来越重要的作用,然而它们在通过网络进行数据交换、软件更新、对话的同时,也为攻击者提供了攻击通道。近年来控制流攻击事件不断发生,如 2017 年 5 月,WannaCry 勒索病毒利用 TCP445端口漏洞将系统控制流篡改到恶意代码处,进而实施了控制流攻击,造成至少150 个国家和地区受到攻击,严重影响金融、能源、医疗等行业的正常运行。相比于木马攻击、旁道攻击、反向工程等硬件载体攻击,控制流攻击具有有效性高、可行性强以及与其他攻击模式兼容等特性,因此防御控制流攻击,保障嵌入式系统的安全性已经成为当前各领域的迫切需求。

由于控制流攻击的危害性巨大,许多防御控制流攻击的方法相继被提出。文献[1]提出利用控制流完整性(Control Flow Integrity, CFI)检测异常控制流,通过在每一条分支指令中插入验证码,以检测不合法的控制流变化;文献[2]提出粗粒度CFI 检查,使用较少的验证码检查CFI 的合法性,降低了性能开销;文献[3]提出一种基本块级的细粒度CFI 检查,解决了粗粒度CFI 检查安全性不高的问题;文献[4]在分析增强内容敏感和字段敏感指针的基础上,提出细粒度的CFI 检测方法,保证了操作系统内核的完整性;文献[5]提出了一种新的硬件辅助CFI 框架,该框架使用功能标签方法和有效标签的状态模型实施细粒度CFI 策略,提高了安全性;文献[6]采用影子内存保存机制备份控制流信息,确保控制流转移的合法性;文献[7]利用线性加解密方式验证控制流转移前后的一致性,从而保证控制流的正确性;文献[8-10]利用硬件电路的安全性实施控制流完整性检查,达到防御控制流攻击的目的。上述方法基本上是基于CFI,而CFI 分为粗粒度CFI 和细粒度CFI,粗粒度CFI 是将一组类似或相近类型的目标归到一起进行检查,由于检查粒度不够细,攻击者依然可以利用指令配件绕过防御机制实施攻击,致使安全性降低。而细粒度则是严格控制每一个间接转移指令的跳转目标,虽然缓解了粗粒度的安全性局限,但是由于实施细粒度检查要求严格控制每一个间接指令的转移目标,因而引入了过大的性能开销,而且细粒度CFI 的安全性依赖于所构建的控制流图(Control Flow Graph, CFG)的准确性,但是构建十分精确的CFG 是非常困难的,所以依然会造成安全性问题。

鉴于此,控制流攻击的重要一步就是通过内存漏洞修改堆栈中的返回地址进而实施返回动态库函数攻击(Return_Into_Libc, RIL)、面向返回编程攻击(Return Oriented Programming, ROP)等类型的控制流攻击。通过检测返回地址是否被篡改,以有效检测控制流攻击。由于该方法不需要通过线下分析获取CFG 图,避免了因控制流图不完备的漏报问题,进而提高安全性。基于以上分析,本文通过对控制流攻击原理的研究,提出了一种基于返回地址签名检测控制流攻击的方法。该方法利用MD5 算法[11]的不可逆性,为加密后的压栈返回地址与出栈返回地址分别生成唯一的签名值,通过比较压栈地址签名值与出栈地址签名值,达到检测返回地址有无被修改的目的,保证了控制流跳转目标的合法性。

1 控制流攻击原理

控制流劫持大部分是通过内存漏洞篡改返回地址来达到目的,它是实现RIL、ROP 等类型控制流攻击的重要手段。攻击者通过劫持程序的控制流,使程序的运行逻辑违背程序原本的设计目标,进而控制整个系统行为,产生巨大安全危害。实施控制流攻击的重要一步就是劫持程序控制流,而劫持控制流主要利用两种攻击:堆栈溢出攻击与格式化字符串攻击。

1.1 堆栈溢出攻击

堆栈是一段连续分配的有限内存空间,每当一个函数调用发生时,堆栈将被依次压入参数、返回地址、基址指针等数据。当函数对已分配的内存写入超出其本身的容量时,就会造成数据的溢出,溢出的数据可以覆盖原有数据。攻击者可以利用此溢出篡改堆栈中原有的返回地址,进行控制流劫持,并将其导向恶意代码shellcode 处,实施控制流攻击。如图1所示,攻击者用起始地址A 覆盖堆栈中的返回地址,而起始地址A 指向恶意代码或指令片段,当系统执行地址A 处的代码或指令片段时,控制流攻击即被实施。

图 1 堆栈溢出攻击Fig. 1 Stack overflow attack

1.2 格式化字符串攻击

格式化字符串漏洞产生的根本原因是未过滤用户输入。当输入数据传递给某些执行格式化操作的函数时,攻击者即可利用“%s”和“%x”篡改堆栈的数据,还可通过“%n”来读取和写入任意地址,从而导致任意代码读写。当printf 在输出格式化字符串时,随即维护一个内部指针,遇到“%”时,printf 期望其后跟随格式字符串,因此内部字符串会递增以获取格式控制符的输入值。然而printf 不确定堆栈上是否放置了正确数量的变量使其运行,如果没有正确变量供其操作,而指针继续按正常情况下递增,就会引起越界访问,甚至可以利用“%n”任意对返回地址读取和写入。

2 返回地址签名法检测控制流攻击

通过对控制流攻击原理的研究与分析,并且针对现有防御手段的不足,本文提出了基于返回地址签名法检测控制流攻击,整体框架如图2 所示。在返回地址被压入堆栈后,攻击者通过堆栈溢出或格式化字符串攻击篡改堆栈中的返回地址,进行控制流的劫持。为检测返回地址的合法性,在系统执行程序调用指令call 时,首先利用伪随机数发生器电路产生密钥K 与压栈返回地址进行异或操作,将异或后的返回地址作为MD5 算法的输入值,以此避免签名算法的输入值与返回地址直接关联。利用MD5 算法的不可逆性为异或后的压栈返回地址生成唯一的签名值并存储在压栈签名寄存器中,然后在系统执行程序返回指令ret 时,使用相同方法,为出栈返回地址生成唯一的签名值,最后将压栈地址签名值与出栈地址签名值送入到地址比较器中,根据签名值的比较结果判断返回地址有无受到篡改,进而达到检测控制流攻击的目的。

图 2 检测控制流攻击整体框图Fig. 2 Overall block diagram of detecting control flow attacks

2.1 伪随机数发生器

为避免攻击者使用暴力攻击或查表法破译MD5签名算法而直接获取正确返回地址,利用线性反馈移位寄存器(Linear Feedback Shift Register, LFSR)电路实现伪随机数发生器[12],产生128 位密钥K,经过Design compiler 综合,在TSMC 65 nm 工艺下平均功耗为0.527 mW,产生的随机数可通过NIST 测试。该随机数存储在专门的密钥寄存器中且仅限于调用指令call 与返回指令ret 访问,其他指令禁止访问。此密钥用于返回地址进行异或操作,即使攻击者通过暴力攻击获取正确的MD5 算法输入值,也不能直接得到正确的返回地址。伪随机数发生器如图3 所示,由n 个D 触发器和若干个异或门组成。其中gn为反馈系数,取值为0 或1,取0 时表明不存在该反馈回路,取1 时表明存在该反馈回路,n 个D 触发器最多可以提供2n-1 个状态。

2.2 MD5 签名算法

为确保生成返回地址签名值的随机性和不可逆性,利用MD5 算法的不可逆性为压栈、出栈的加密返回地址生成唯一的随机签名值。MD5 算法是一种典型的消息认证算法,经过一系列运算,它可将任意长度的消息压缩为128 位的摘要。MD5 算法的运算框图如图4 所示,具体运算过程如下:

(1)补位。若初始数据的长度没有达到512 的整数倍,系统将会在消息的低位处用一个1 和若干个0 进行补齐。

(2)初始化缓冲器。MD5 有 4 个 32 位的被称作链接变量的整数参数A、B、 C、D, 对其设置初始数据。

(3)非线性轮运算。MD5 算法规定了4 个非线性操作函数:

其中:&为与;|为或;~为非; ∧ 为异或。利用以上 4 种操作,生成4 个重要的计算函数。4 个中间变量a、b、c、d,赋值:a=A, b=B, c=C, d=D。接着执行 4 轮主循环,每一轮完成16 次运算,每轮用到一个非线性函数,每次操作需要对a、b、c 和 d 中的3 个变量完成一次非线性运算,并更新对应的变量数据。

(4)数据输出。处理完所有512 位的分组后,得到一组新的 A、B、C、D 的值,将这些值按 A、B、C、D 的顺序级联,得到MD5 签名值。

2.3 返回地址签名值计算

根据上述方案,利用MD5 算法为返回地址生成签名值,经分析得到压栈返回地址、出栈返回地址签名值计算公式如下:

图 3 伪随机数发生器Fig. 3 Pseudo-random number generator

图 4 MD5 算法框图Fig. 4 MD5 algorithm block diagram

其中:PRNG_K、push_addr、encry_push_addr、sig_push_addr、pop_addr、encry_pop_addr、sig_pop_addr分别为伪随机数电路产生的密钥、压栈返回地址、加密后的压栈返回地址、压栈地址签名值、出栈返回地址、加密后的出栈返回地址、出栈地址签名值。当执行程序调用指令call 时,密钥K 与压栈返回地址进行异或操作,然后将异或后的返回地址作为MD5 算法的输入值,得到压栈地址的签名值。同理,当执行程序返回指令ret 时,生成出栈签名值。

3 实验例证与分析

为了验证方案的有效性,以oc_8051 处理器为验证平台,通过修改oc_8051 处理器的源代码,在处理器架构中加入返回地址签名模块,实现处理器具有检测控制流攻击功能的目的,并进行波形仿真、签名值随机性测试、正确签名值与错误签名值汉明距离测试以及可用的控制流攻击指令消除率测试等实验。实验环境包括:Intel Xeon(R) Dual-Core CPU 2.0 GHz、6 GB RAM 服务器,涉及的工具软件包括:NClaunch、Matlab、以及 ROPGadget-master5.4。

3.1 检测控制流攻击的处理器硬件架构

图5 为将返回地址签名电路应用于oc_8051 处理器的硬件架构图。oc_8051 处理器工作流程分为5 个阶段:取指、译指、执行、访存、写回。由于返回地址签名电路的引入,当处理器处于译指阶段且译指结果为程序调用指令call 时,将产生call_en 使能信号,触发签名电路生成压栈地址签名值。同理,当译指结果为程序返回指令ret 时,处理器产生ret_en 使能信号,触发签名电路生成出栈地址签名值,最后通过匹配压栈地址签名值与出栈地址签名值达到检测控制流攻击的目的。若二者签名值相匹配,处理器继续执行程序,反之,则立即停止程序。

3.2 处理器检测控制流攻击的工作流程

图6 示出了具有检测控制流攻击功能处理器的工作流程,具体步骤如下:

(1)处理器处于译指阶段且指令译码结果为程序调用指令call 时,触发伪随机数发生器生成密钥K,并将压栈返回地址送入XOR 加密单元进行加密处理;

图 5 检测控制流攻击的处理器硬件架构图Fig. 5 Hardware architecture diagram for detecting control flow attacks

图 6 检测控制流攻击的处理器工作流程图Fig. 6 Flow chart of detecting control flow attacks

(2)将加密后的压栈返回地址作为MD5 签名生成单元的输入值,生成压栈签名值;

(3)指令译码结果为程序返回指令ret 时,将出栈返回地址送入XOR 加密单元进行加密处理;

(4)将加密后的出栈返回地址送入MD5 签名生成单元,生成出栈签名值;

(5)比较压栈返回地址的签名值与出栈返回地址的签名值,若签名值相同,则继续执行,反之立即停止执行。

3.3 仿真波形

通过编写测试激励testbench,使压栈地址与出栈地址不同,并使用NClanch 获得仿真波形,如图7 所示。其中ADDR_PUSH_R、ADDR_POP_R、PRNG_K、XOR_ADDR_PUSH、XOR_ADDR_POP、SIG_PUSH_R、SIG_POP_R、COMPARE_SIG 分别为压栈地址寄存器、出栈地址寄存器、随机数K 寄存器、加密压栈返回地址寄存器、加密出栈返回地址寄存器、压栈返回地址签名值寄存器、出栈返回地址签名值寄存器、签名值比较信号。当出栈地址为0x043b,压栈地址为0x0438 时,从仿真波形图中虚线处可发现,二者生成的签名值不同,签名值比较信号翻转,指示当前返回地址遭到恶意篡改,达到检测控制流攻击的目的。

3.4 返回地址签名值及其相关性

表1 所示为7 组输入不同返回地址得到的签名值,经过对签名值的自相关性和互相关性分析,并使用Matlab 获取签名值的相关性分布图。图8 为同一组输出数据的自相关性分布图,图9 为7 组不同输出数据的互相关性分布图,从图中可知生成的地址签名值具有良好的随机性。

3.5 返回地址签名值的汉明距离

图10 所示为本方案假设表1 中的第一个返回地址为正确的出栈返回地址,其余为错误的出栈返回地址,经过对其汉明距离的分析,得到正确返回地址与错误返回地址的汉明距离。汉明距离是用于表示两个二进制字符串之间的差异的数字。设x 和y 是两个相同长度的二进制序列,x 和y 之间的汉明距离d(x, y)是相应符号不同的位数,计算公式如下:

图 7 仿真波形图Fig. 7 Simulation waveform

表 1 返回地址签名值数据输出Table 1 Return address signature

图 8 数据自相关性Fig. 8 Data autocorrelation

图 9 数据互相关性Fig. 9 Data cross-correlation

图 10 正确与错误地址签名值之间的汉明距离Fig. 10 Hamming distance between correct and wrong signatures

其中,i=0,1,…,n-1。由图 10 可得,128 位正确返回地址签名值与错误返回地址签名值之间的汉明距离均达到50%以上,错误签名值与正确签名值具有较大差异性,攻击者很难通过对错误返回地址签名值的分析得到返回地址的正确签名值。

3.6 控制流指令消除率

攻击者利用处理器在执行call 或ret 指令时,对堆栈中的返回地址进行篡改,进而实施控制流攻击。而由于处理器中引入了返回地址签名电路,返回地址若受到恶意篡改会被立刻检测出,因此攻击者不能利用call 指令或ret 指令进行控制流劫持。使用ROPgadget 获取控制流指令总数目并统计call 指令与ret 指令数目,计算call 指令与ret 指令数目在控制流指令总数目中的占比,即可得到控制流指令消除率。表2 示出了5 个不同测试程序下的控制流指令消除率,5 个测试程序中均含有缓冲区溢出漏洞和格式化字符串攻击漏洞,攻击者可利用漏洞进行控制流劫持。结果显示攻击者可利用的控制流指令平均消除率达到81.27%,有效消除了攻击者可利用的控制流指令。

表 2 控制流指令消除率Table 2 Control flow instructions elimination rate

4 结 论

本文提出了一种基于返回地址签名的控制流攻击检测方法。该检测方法首先利用伪随机数发生器产生密钥K 与返回地址进行异或加密,然后将加密后的返回地址作为MD5 算法的输入,利用MD5 算法的不可逆性分别为加密后的压栈返回地址和出栈返回地址生成唯一的签名值,最后根据出栈签名值和压栈签名值是否匹配进行控制流合法性的检测。通过实验验证了此方案的有效性,结果显示当压栈地址与出栈地址相异时,处理器可立即检测出此时控制流不合法。虽然MD5 算法是已有算法且复杂度不高,然而得到返回地址的签名值依然具有良好的随机性,攻击者可以利用的控制流指令平均消除率达到81.27%,可有效地检测出因返回地址篡改而引起的控制流攻击。

猜你喜欢

堆栈攻击者指令
基于行为监测的嵌入式操作系统堆栈溢出测试*
基于贝叶斯博弈的防御资源调配模型研究
基于 Verilog HDL 的多周期 CPU 设计与实现
《单一形状固定循环指令G90车外圆仿真》教案设计
正面迎接批判
正面迎接批判
基于堆栈自编码降维的武器装备体系效能预测
一种航天器软件进程堆栈使用深度的动态检测方法
中断与跳转操作对指令串的影响
MAC指令推动制冷剂行业发展