Exploring Branch Predictors for Constructing Transient Execution Trojans

Exploring Branch Predictors for Constructing Transient Execution Trojans(木马)

1. 摘要:
  • 针对于幽灵攻击,工业界迅速采取了一系列软件和硬件上的缓解措施,其中微码补丁最为流行和受信任(microcode patch)
  • 问题:现有的防护策略仍旧存在被攻击的漏洞
  • 论文工作:
    • 提出了暂态木马(transient trojans),即一种软件模块会在暂态执行模式中隐藏自身的恶意活动。这些木马看起来完全正常,能够通过静态/动态的分析检查,但是在被触发后能够获取隐私数据
    • 论文根据推荐的缓解技术对当今系统中存在的攻击面进行了详细的分析,以构建这些暂态木马
    • 论文对一些最新的x86-64处理器中的转移预测器进行了逆向工程,以发现以前未知的可能的攻击方法。根据这些发现,论文构造了三种类型的暂态木马,并证明了他们的隐身性和使用性
2. 介绍:
  • 暂态执行攻击,包括meltdown和spectre,能够利用处理器中的一些性能优化策略,例如转移预测,迫使受害者程序通过在一些微体系结构中留下可被检测的踪迹来泄露隐私数据。这些攻击能够违反内存安全的最基本原则,包括用户-内核隔离。

  • 已有的抵御暂态执行攻击的策略:

    • 串行化指令
    • 避免危险代码序列
    • 刷新硬件数据结构
    • 限制推测执行(safespec,invisiSpec)
    • 禁止微体系结构的隐蔽信道
    • 硬件制造商Intel&AMD使用一系列的微码更新来应对攻击,但是会产生明显的性能下降
  • 论文工作:提出暂态木马,能够隐藏在暂态执行模式下的恶意功能的软件模块

    • 对处理器中的转移预测器进行逆向工程,发现了一些新的分支冲突触发技术(branch collision triggering technologies)(间接转移预测)。这些技术是的轻便(portable,可移指)的,独立的木马能够包含在敏感的软件中,例如恶意的开源代码中
    • 构建软件模块,将所有攻击组件封装在一个进程中
  • 暂态木马中的在暂态执行模式下的恶意功能并不会在软件代码中引起注意,并且能够通过严格的安全检查,例如:

    • 符号执行

    • 污点分析,taint analysis( Dytan: a generic dynamic taint analysis framework )

    • 模型检查

    • 传统的检查软件后门的策略:

      • Backdoor detection system using artificial neural network and genetic algorithm
      • Towards reducing the attack surface of software backdoors.
      • Firmalice-Automatic Detection of Authentication Bypass Vulnerabilities in Binary Firmware
      • HumIDIFy: a tool for hidden functionality detection in frmware.
      • Static detection of application backdoors
    • 已有的幽灵检测工具:

      • oo7: Low-overhead Defense against Spectre attacks via Program Analysis
      • SPECTECTOR: Principled Detection of Speculative Information Flows.
      • Detecting Spectre vulnerability exploits with static analysis
      • LWN.net: Finding Spectre vulnerabilities with smatch
  • 论文认为,当今几乎所有CPU中普遍存在的暂态执行很自然的适合隐藏恶意代码,因为它提供的执行模式对于现有的二进制和源码分析技术来说是完全不可见的

  • 论文贡献:

    • 论文对BPU进行了逆向工程研究,发现了负责间接转移预测的机制和操纵方式。基于这些发现,论文依赖于不同的BPU异常,构造了三种类型的木马
    • 论文提出了一种基于前期BPU访问的新的分支指令冲突机制。该机制允许攻击者构建木马,并且可以避免被检测到。其次该机制允许创建小型,便携的木马
    • 论文提出了一种分散暂态小工具技术,可以提高隐蔽性和有效性
    • 论文分析了静态转移预测机制,发现它可以导致跳过那些论文用于绕过检测并构建木马的间接分支
    • 论文对当前二进制文件进行了分析。结果表明,在大型二进制文件中,潜在的发生危险冲突的发生了高达数十万。论文认为,这种自然发生的冲突可以用于隐藏恶意木马以及从现有代码中构造木马
    • 论文分析了防卫技术,并提出了从不受控制的暂态执行中消除威胁的方法。
3. Spectre v2:利用BTB进行推测执行攻击,允许攻击者可以选择哪些代码被推测执行,并且攻击者可以强制暂态执行以面向返回编程的方式运行,从而可以执行原始二进制文件中不存在的代码序列。
  • Spectre v2需要使用间接跳转或者call指令来创造一个暂态执行窗口

  • 目前Google提出了一种简单的编译解决方法:将所有的间接跳转指令替换为特殊的指令序列,retpolines

    • 使用一条压栈指令和ret指令来替换间接跳转指令
    • 当CPU执行ret指令时,将会使用RSB对指令进行预测,而不是BTB
    • 问题:已经出现了利用RSB的暂态指令攻击;当RSB下溢时,Intel的处理器会使用BTB对指令进行预测
  • 系统范围内的微码保护,Intel

    • IBRS(indirect branch restricted speculation):限制在特权模式下的推测执行。阻止在特权代码中执行的间接分支被更低级别的代码影响,即当处理器进入IBRS模式后,外界无法对间接分支进行操作
    • IBPB(indirect branch barrier):阻止跨进程的BTB污染。在进程切换时刷新BTB。
    • STIBP(single thread indirect branch predictors):单线程单间接转移预测器,阻止跨超线程的BTB污染。控制转移预测器之间的共享
  • 微码保护的问题:为了减少性能下降,有选择性的使用不同的方案。IBRS只在特权模式使用,内核,内核模块,SGX的enclaves中。IBPB和STIBP只会在将上下文切换到敏感进程后才会选择性的强制使用。

  • 目前保护模型仍旧存在的问题:当BTB的污染来源于同一个地址空间时,IBPB和STIBP将不在能够抵御(1)。IBRS指挥保护在特权态运行的代码不受非特权态代码的影响,因此当污染来源于特权态所示,攻击仍旧可能出现(2)

在这里插入图片描述

4. 威胁模型
  • 假定攻击者是恶意开发人员,能够在被触发条件激活之前提供看似安全的软件
  • 用户可以运行静态/动态分析和信息流控制工具,包括目前已有的spectre小工具检测工具
  • 恶意代码可以以预编译的二进制代码,源代码,共享库或者对开源项目的提交的形式分发
  • 假设攻击者对受害者的机器配置有一定的了解,包括微体系结构,操作系统,共享库版本等信息
5. 转移目标地址预测机制
  • 直接转移指令:跳转的目标地址固定,直接的call,jump指令和条件跳转指令。预测目标地址时直接采用缓存在BTB中的上一次跳转的结果

  • 间接转移指令:跳转目标不固定,取决于程序处理的数据。为了提高准确率,通常需要进一步考虑指令的上下文。目前的BPU会将间接转移指令之前执行的转移指令模式(BHB,转移指令)关联在一起。即将BHB和指令地址哈希在一起,然后利用压缩后的BHB的值作为BTB的索引。(同一条间接转移指令会有多个BTB表项)

  • 为了最大化存储利用率,直接转移指令和间接转移指令会共用一个BTB,只是两种指令的索引方式不同:

    • IP-based:直接转移,使用指令地址的一部分作为索引
    • BHB-based:间接转移,使用hash后的BHB作为索引
    • 在实际预测的时候,两者会同时访问BTB,最后使用一个选择器进行选择
  • offset和index的选择问题:index选择中间的部分应该是为了使得一块区域内的指令都在同一路中,集中,好处?减少区域之间的在替换时的干扰

  • BTB中直接转移指令的IP-based索引模式

    • 在Skylake处理器中,只有转移指令地址的低30位被用于查找BTB

    • BTB的相联度:地址中的低30位中的高位会被用作tag,因此论文选择n条高若干位不同,但是其余位均相同的转移指令序列执行两遍,通过性能计数器来判断BTB在第二遍执行时发生的失效次数,从而判断出BTB中每一组最多能够存储的指令数量,即为路数。结果是包含8路,即8路组相联

    • 哪些地址位被用于作为索引:首先执行8条处于同一组的转移指令,然后执行一条翻转30位地址位中的一位作为指令地址的转移指令。如果翻转的哪一位是index位,那么最开始的8条指令仍旧会存储在BTB中,否则将表明翻转的位是tag位。结果:[13:5]为索引位,[29:14]为tag位域。tag位在一些处理器中会进行8位的折叠处理,即每8位之间进行一次亦或运算

    • offset位域:[4:0]。作用尚不清楚。一般情况下,偏移被视为第二个标签,需要完全匹配才能发生BTB命中
      在这里插入图片描述

  • 间接转移预测的索引模式(switch-case)

    • switch-case的情况中,指令实现时通常是先计算跳转目标地址,然后利用间接跳转指令进行跳转。在这种情况下,switch语句之前的代码执行情况将会很可能影响跳转的目标地址,因此为了预测间接跳转通常会联系上下文。但是对于default语句的情况,很多不同的上下文都跳转到同一个目标地址,此时选择简单的IP-based的方法将会更准确。因此论文假设BPU会并发的采用这两种方式访问BTB

    • 对于一条间接转移指令,论文对其假设有多种上下文,使用A,B,R(1…k)进行表示,每一种上下文的情况下,指令都有一个目标地址,使用a,b,r表示,两者的对应关系如下:A->a, B->b, R(1…k)->r。通过多次执行不同上下文情况下的间接转移指令,观察BTB会发生的失效或者命中事件的情况,将可以判断出BPU采用的BTB索引模式。

    • 结果:模式1中表明,对于R(1…k)->r的情况,除了第一次失效,之后都可以正确预测;A-a的情况,在发生第二次的时候也可以预测,即预测器能够使用两种独立的模式预测同一个指令。

    • 结果:模式2表明,预测器会同时使用任意一种方案检查转移指令是否可以被预测。
      在这里插入图片描述

  • 两种不同的间接转移指令会存在的冲突

    • 当BHB状态和精简之后的指令地址都匹配,并且BPU采用BHB-based的索引方式的时候(之前的工作采用的污染BTB的方式)
    • 当精简后的指令地址相同,BHB不同,但是BPU采用IP-based的索引方式的时候
  • 选择用于污染BTB的转移指令类型

    • 之前的利用BTB的攻击通常采用第一种类型的冲突,通过重复先前转移指令的行为来保证BHB的状态一致,同时执行具有匹配的指令地址的间接分支。不太适合在真实世界中使用,因为要求执行污染的分支(writer branch, WB)和被污染的分支(reader branch, RB)必须位于同一地址空间内.

    • 利用冲突1构建木马的难点:WB和RB需要处于会发生地址冲突的位置,还需要具有完全相同的BHB状态。但是映射函数中,f3和f2都是未知的,或者是部分已知的。同时就算f3和f2都是已知的,为了保证BHB的状态,训练过程就需要高度不规则的代码序列,这就很容易被检测工具检测出来。

    • 利用第二种冲突:需要RB和WB在每次执行时都需要处于一个新的BHB上下文中。解决,在执行WB和RB之前执行一段结果随机的条件分支序列。但是这样仍旧会导致BHB的状态最终开始重复,促使BPU使用的BHB-based寻址模式。并且这样的指令序列也是同样高度不规则。

    • 期望的设计:(1)当RB和WB位于同样的地址空间时,会产生可靠的冲突;(2)代码很容易被掩盖为正常代码

    • 论文的设计:将直接分支作为WB,因为(1)它们始终使用IP-based的索引方式,能够使得BTB的状态更具有确定性;(2)在常规应用中很常见,容易掩盖为普通代码。(每4-7条就有一条直接分支)
      在这里插入图片描述

  • 论文通过测试上述的代码得到的结论:

    • 直接分支可以作为WB指令,间接分支作为RB,两者共同创造冲突,从而构建木马。另外,RB并不需要每次都有一个新的上下文?
    • 在BTB中存储的精简之后的数据仍旧允许在一个进程内制造冲突,并且跳转到恶意的地址。
    • 不同种类的直接转移指令都可以作为WB指令,包括call和条件分支
    • 通过多执行几次WB可以提高成功污染BTB的概率。暗示着BTB中的选择器可能会使用竞标赛策略,会选择准确率更高的预测器
6. Distant collision trojans,远程冲突木马
  • 主要利用BTB的索引模式中仅存储着部分的地址信息。当WB和RB发生冲突后,RB发生错误预测时,处理器将推测执行WB指向的目标地址,从而引发攻击。

    • 示例:BTB中的标签会使用XOR对指令地址的高位进行折叠处理。假设在同一个进程中,在地址0x400077处有一条直接分支,在0x4077处有一条间接分支。当两者均使用IP-based的寻址模式时,两者就会发生冲突
  • 攻击的一般过程:首先使用程序API,激活WB指令,将中毒的BTB表项写入BTB中,之后攻击者触发RB初始化暂态执行的条件,例如发出API调用以访问大型数组将RB的目标地址从缓存中刷新出去。然后再执行RB指令,引发错误预测,处理器暂态执行小工具以访问并泄露隐私数据。

  • 该方法与之前构造冲突的方法不同点:已有的方法通常低权限实体会毒害高特权实体的分支,此方法则是使用在以下两种情况中:

    • 高特权实体对低特权实体进行毒害污染
    • 处于同一个特权级别进行毒害污染
  • 利用系统调用的木马示例

    • 在系统态下对BTB的修改结果在返回用户态时不会被删除/回退
    • 对图中的攻击中,对于攻击的每次迭代,攻击者都通过API调用与木马进行交互。每次调用都将激活木马内部的恶意功能,进而执行导致BTB中毒的系统调用。该函数从系统调用返回后,将执行间接跳转,从而导致小工具的暂态执行,最后导致数据泄露
    • 论文从1000次木马执行中收集数据,攻击准确率94.52%(激活后成功拿到数据的概率),激活率12.79%
  • ASLR和KASLR会使得攻击变得更加困难,但是程序可能在没有ASLR的支持下编译。而KASLR的可变性很小,可以通过将RB放置在所有潜在的冲突地址上进行攻击。
    在这里插入图片描述

7. Early Front-end Branch Collisions (早起前端转移指令冲突)
  • BPU在执行过程中正常情况下需要在知道转移指令的最后一个字节之后才能开始预测,因为很多情况下,最后一个字节会作为预测器的索引使用。

  • 在CISC指令系统中,会增加预译码器来检测取到指令缓存行中的指令边界。论文假设:在激进的前端设计中,可能会在预译码完成之前仅使用基於潜在分支指令地址的部分信息进行预测并开始暂态执行。

    • 如果假设成立,那么将会出现早期的前端分支冲突,即位置较近的分支会由于分支指令边界的不确定性而发生冲突。(低位不匹配的分支指令之间产生冲突)Intel的一些专利中将地址的低若干位成为偏移量,但是指明用途
  • 测试假设:将之前的代码中,WB和RB放置在同一个64B的指令缓存行中,以保证两者的tag和index都是匹配的。

    • WB会跳转到一个会泄露寄存器rax中值的小工具中。RB则会跳转到正常的代码。但是在执行RB之前,代码会将秘密值放入rax中。

    • 在执行之前,rax中会被加载为非隐私数据。如果RB会被WB毒害,那么执行之后秘密值将能够通过小工具泄露出去

    • 通过改变WB和RB可能处于的位置,并检测是否会发生RB被污染的事件来寻找一个稳定的会发生冲突的模式。结论:在Skylake和Kaby Lake处理器中,如果所有的偏移位匹配或者如果WB的bit_5为1而RB中的bit_5为0时,两者会发生冲突。
      在这里插入图片描述
      在这里插入图片描述

  • 这种冲突机制和其它的冲突机制之间可以结合使用,而不是一定要求WB和RB之间必须是处于同一个缓存行内。例如,如果两个分支具有匹配的tag和index,但是不匹配高位[47:30],并且遵守bit_5的冲突原则也会发生冲突

    • 在Kaby Lake上的实验结果:将RB放在地址0x300110上,将WB放在可能发生冲突的潜在地址上(0x100300100-0x100300140),利用性能计数器判断是否发生了冲突

    • 当WB跨越32字节边界时,就会发生bit-5冲突
      在这里插入图片描述

  • 基于早期前端分支冲突的木马的隐蔽性和可移植性更好:

    • 不依赖于将分支指令放置在相距很远的地方,因此尺寸可以很小
    • 不依赖于固定的地址(除了要求在缓存行中的偏移量以外),因此使用ASLR功能后仍旧可以使用
    • 木马:将所有攻击组件,WB,RB,小工具都封装在一小段代码中,然后打包到一个或者几条缓存行中。
  • 分散小工具以避免检查:

    • 目前检查小工具的依据:代码序列会产生两个动作,(1) 读取内存地址;(2)执行另一条内存操作指令,并且该指令的地址和步骤1获取的数据之间存在相关。

    • 应对:将小工具分散成两个部分,保证每个部分都不会被识别为恶意指令序列。在两个部分之间增加一条间接跳转指令,在该指令之间执行前两个操作,然后再执行后两个操作。从正常程序的角度,第二部分的指令将不会被执行,因此这两个部分也不会被认为是同一个小工具,也无法被正常检测。
      在这里插入图片描述

8. 跳过分支木马(skipping branch trojans):
  • 跳过间接分支:AMD Ryzen和Intel Haswell架构中的测试
    • 当BTB中没有可用的预测时,CPU会跳过无条件的间接分支指令,继续执行之后的指令。
    • 用途:构建木马,混淆静态/动态分析工具
    • 例如一个程序中使用间接调用指令来调用某个确定的函数,该指令的目标地址会在程序初始化时被设定,也不会被更改。检测工具能够发现这种相关性并且将程序标记为安全的,但是由于间接分支被跳过,将会导致暂态执行的出现。
  • 基于跳过间接分支的暂态执行攻击
    • 图中两个函数会使用函数指针进行调用,在编译时会被会变为间接的call指令。
    • 函数指针f1用于调用函数并返回一个隐私值,将最终将隐私值放入变量sec中;函数指针f2被用于将一个非隐私值放入non-sec变量中
    • 函数调用之后的代码是一段小工具代码,用于将nonsec的值泄露出去。由于nonsec中不包含隐私数据,因此不会认为是不安全的
    • 在System V的ABI中要求,函数的返回值需要使用eax寄存器进行传递,并且在返回之后,函数调用者需要将eax的值作为一个局部变量存储在堆栈中。
    • 攻击发生的情况:f1的间接跳转没有被跳过,而f2被跳过了。结果导致(1)eax中存储着隐私数据,并且传递到了sec变量中;(2)eax的数据同样被存储在non-sec变量中。
    • f2在执行之前,攻击者会提前将目标地址从缓存中刷新出去,即栈基址
  • 实验结果:为了泄露1B的数据需要激活易受攻击的函数888.07次,平均的错误率1.74%
  • f1预测对,f2被跳过的概率很小
    在这里插入图片描述
9. 改善木马的激活率
  • 激活率:数据泄露的次数和总激活尝试次数的比值
    • 基于内核的12.79%,基于早期前端分支冲突的4.86%
  • 利用遗传算法改进提升激活率
10. 现有二进制中的冲突
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200522230805974.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NodWlsaXVzaGVuZw==,size_16,color_FFFFFF,t_70#pic_center)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章