Kernel Security Story: Against code reuse attacks - CET

作者:zrz

原文地址:https://secvul.com/topics/1291.html


源起

早在2015年10月24,PaX Team 在H2HC上发表了关于code reuse attack的防御方案,即RAP。[1]几个月之后Intel公布了其CPU的新特性control-flow enforcement(CET)用于防御该攻击。不禁感慨,从提出概念再到生成环境这得多久。Intel是否会再次失信,让我们拭目以待吧。

去年10月20日,Intel向gcc社区提交了CET的实现补丁[2],于今年5月初正式版本gcc 8.1中第一次被集成(使用 -mcet 选项开启该保护)。最近Intel又向Linux Kernel社区提交了CET的实现补丁,这意味着CET的软实现已经完成了(Intel CPU支持CET就不清楚是哪一代了),剩余就是迭代与完善。

Kernel中CET的故事

Control-flow enforcement(CET)是为防御code reuse attack提供的特性,即防ROP/COP/JOP。
CET中实现了2中独立的机制进行防护:
1.Shadow Stack
—— 防护ROP
2.Indirect branch tracking(IBT)
—— 防护COP/JOP

Shadow Stack

防护ROP其中之一的方法是将返回地址放在另一个上下文中,这是Shadow Stack的核心理念。Shadow Stack和Data Stack分离,可以在当独在user-mode或super-mode下开启。当开启Shadow Stack时,CALL指令将push它的返回地址到Shadow Stack和Data Stack。RET指令将从Shadow Stack和Data Stack中pop返回地址进行比较。如果两个栈的返回地址不匹配CPU将报异常(#CP)。Shadow Stack仅保存返回地址,不包含参数的调用地址。只要攻击者无法篡改Shadow Stack,就应该阻止使用返回指令来转移控制流。
防篡改需要对Shadow Stack进行特殊处理。它从一个virtual-memory范围内被分配,它的基地址存储在MSR中。Shadow Stack的pages必须有一组奇怪的bits组合:read-only but dirty。上面的read-only保护可以防止攻击者添加特殊的项,因此Shadow Stack被分配在一个特殊的VMA中,并标记为VM_SHSTK标志。其中ARCH_CET_LOCK可用于防止Shadow Stack和IBT被关闭。
Indirect Branch Tracking(IBT)
CPU通过双状态去追踪call/jmp的间接调用。一个状态在user-mode下维护,另一个在super-mode下。他们默认处于IDLE状态,即重置后为该状态。为实现该机制CPU实现了新指令集ENDBRANCH(endbr32和endbr64)。该指令细节,请移步至Intel CET文档[3]。

目前的补丁仅支持64位的系统,仅对user-space做了支持。
该补丁一共包含4个部分: 内存管理、Shadow Stack、Indirect Branch Tracking、CPUID。
在内存管理中做了3个更改:
1.Shadow stack 内核配置选项;
2.控制保护异常;
3.Shadow stack内存管理;

后记

有关CET防护效果2年前PaX Team就做了有关讨论。他们认为CET只不过是微软CFI的弱实现并加了Shadow Stack,而且还要在硬件上支持。有兴趣的朋友可看看原文[4]。个人认为,至少填补了Kernel层对code reuse attack防护的空缺,相对来说提高了攻击的成本与门槛。

参考

[1]. https://pax.grsecurity.net/docs/PaXTeam-H2HC15-RAP-RIP-ROP.pdf
[2]. https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=3c0f15b4cebccdbb6388a8df5933e69c9b773149
[3]. https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
[4]. https://forums.grsecurity.net/viewtopic.php?f=7&t=4490
[5]. https://www.kernel.org/

点赞

发表评论