MTE 实现详解,第二部分:缓解措施案例研究

访问原始链接 Google 翻译

作者:Mark Brand,Project Zero

背景

2018年,ARM在其架构v8.5a版本中提出了一种硬件实现的标记内存方案,称为MTE(内存标记扩展)。

在第一部分中,我们讨论了在我们能够接触到的硬件上测试MTE的技术(和实现)限制。本文将基于我们已知的信息,探讨MTE在几个重要产品/场景中作为缓解措施的有效性。

总结来说,基于内存标记的缓解措施存在两类关键的绕过技术(一些例子可参见第一部分):

  1. 已知标记绕过 - 通常,标记值的保密性是内存标记作为缓解措施有效性的关键。一旦标记保密性被破坏,攻击者就能直接或间接地确保其无效的内存访问具有正确的标记,从而无法被检测到。
  2. 未知标记绕过 - 实现的限制可能意味着,即使攻击者执行了可能被检测到的标记不正确的内存访问,仍然有机会利用漏洞。

MTE强制执行有两种主要模式:

  1. 同步模式(sync-MTE) - 标记检查失败会导致指令退休时产生硬件故障。这意味着无效读取的结果和无效写入的影响在架构上应该是不可见的。
  2. 异步模式(async-MTE) - 标记检查失败不会直接导致故障。无效读取的结果和无效写入的影响在架构上是可见的,故障会在错误指令执行后的某个时间点,以每CPU标志的形式传递。

自Spectre漏洞以来,很明显,将标准的内存标记方法用作"硬概率缓解"1通常是不可能的。在任何攻击者能够构建推测性侧信道的场景中,已知标记绕过都是一个必须考虑的根本弱点。

另一种提议的方法是将MTE与另一种软件方法结合,构建"硬确定性缓解"2。主要的例子是Chrome中提出的*Scan+MTE组合,旨在通过确保在仍有任何悬空指针指向某个分配时,不为该分配重用标记,从而缓解释放后重用漏洞。在这种情况下,async-MTE是否足以作为一种有效的缓解措施?我们已经展示了在使用async-MTE时允许未知标记绕过的技术,因此很明显,对于"硬"缓解措施,(至少)需要sync-MTE。然而,这不应被理解为暗示这种"软"缓解措施不会给攻击者带来显著的不便——我们将在下面详细讨论这一点。

MTE会给攻击者带来多大麻烦?

为了理解攻击者在编写能够绕过基于MTE的缓解措施的漏洞利用程序时将面临的"额外困难",我们需要仔细考虑攻击者所处的环境。

我们在此假设,高级攻击者期望的目标可靠性约为95%——这可能低于目前大多数情况下的预期,但可能高于漏洞利用程序因操作需求而变得过于不可靠的绝对极限。我们还注意到,在某些情况下,攻击者甚至可能使用极其不可靠的漏洞利用程序,而不会显著增加被检测的风险。虽然我们预计攻击者会渴望(并投入资源)实现可靠性,但即使我们能够强制设定一个可靠性的上限,这也不足以完全阻止漏洞利用。然而,任何此类可靠性的下降通常都应会提高对野外漏洞利用使用的检测率,从而相应地增加攻击者的风险。另外需要注意的是,大多数未知标记绕过可以通过使用sync-MTE来防止,至少在应用程序不存在特定弱点的情况下是如此,而随着利用这些弱点的漏洞利用程序被发现,这些弱点很可能会被修复。

我们在此考虑4个主要场景,因为我们认为这些是用户模式缓解措施最相关/最可能的使用案例:

场景 模式 绕过技术 已知标记绕过 未知标记绕过
Chrome:渲染器漏洞利用 async 绕过技术 简单 ♻️ 很可能简单 ♻️
sync 绕过技术 简单 ♻️ 绕过技术应属罕见 🛠️
Chrome:IPC沙箱逃逸 async 绕过技术 在许多情况下很可能可行 ♻️ 在许多情况下很可能可行 🐛*
sync 绕过技术 在许多情况下很可能可行 ♻️ 绕过技术应属罕见 🛠️
Android:Binder沙箱逃逸 async 绕过技术 难度取决于服务 难度取决于服务 🐛*
sync 绕过技术 难度取决于服务 绕过技术应属罕见 🛠️
Android:消息应用一次性利用 async 绕过技术 在大多数情况下很可能不可能 足够好的漏洞将非常罕见 🐛*
sync 绕过技术 在大多数情况下很可能不可能 绕过技术应属罕见 🛠️

攻击者因需要绕过MTE而面临的困难程度大致从低到非常高。

♻️:一旦开发出来,通用绕过技术很可能可以在不同漏洞利用之间共享。
🛠️:可被修复的绕过技术数量有限,最终会消除这种绕过方式。
🐛:绕过技术施加的额外约束意味着,在MTE下可利用的问题子集显著减少。

  • 注意,也有可能通过设计软件来使利用这些未知标记绕过技术更具限制性,例如在特定的瓶颈点插入系统调用。我们目前尚未研究这种方法的实用性或局限性,但它不太可能普遍适用,尤其是在涉及第三方代码的情况下。

Chrome:Javascript -> 受感染的渲染器

Spectre类型的推测性侧信道可用于破坏标记保密性,因此已知标记绕过是必然的。

对于未知标记绕过,在大多数情况下,javascript应该能够在漏洞利用期间避免系统调用,因此漏洞利用需要在软时间限制内完成。已知标记绕过和未知标记绕过技术都可能被通用化,并在多个不同的漏洞中重复使用。

Chrome:受感染的渲染器 -> Mojo IPC沙箱逃逸

Spectre类型的推测性侧信道很可能可用于破坏标记保密性,因此已知标记绕过是可能的。

对于未知标记绕过,我们认为存在某些情况,可以在不进行系统调用的情况下处理多个IPC消息。这并非适用于所有情况,并且当前公开的最先进的浏览器进程IPC利用技术会执行多次系统调用,因此不适用。有可能开发出一种通用的推测性侧信道攻击,允许针对特定特权进程(很可能是浏览器进程)重复使用已知标记绕过技术。任何未知标记绕过漏洞利用都可能需要额外的、针对每个漏洞的开发成本,因为在漏洞利用期间避免系统调用需要额外的复杂性。

Android:应用 -> Binder IPC沙箱逃逸

Spectre类型的推测性侧信道很可能可用于破坏标记保密性,因此已知标记绕过是可能的。

对于未知标记绕过,我们注意到在不同的IPC消息之间有一个强制性的系统调用 ioctl(..., BINDER_WRITE_READ, …)。这意味着漏洞利用不仅需要满足软时间限制,还需要在触发IPC消息的执行过程中完成。由于有大量不同的Binder IPC服务托管在不同的进程中,已知标记绕过技术在不同漏洞之间重复使用的可能性较低。未知标记绕过的利用不太可能被重复使用,需要针对每个漏洞进行特定的开发。另外需要注意的是——目前,.data 节指针没有被标记,因此zygote架构意味着攻击者在某些上下文之间伪造指针会很容易,这可能成为利用某些导致二阶内存损坏的漏洞(例如,类型混淆允许攻击者将数据视为指针)的有用技术。

Android:远程 -> 消息应用

Spectre类型的推测性侧信道不太可能用于破坏标记保密性,因此已知标记绕过极不可能,除非应用程序允许替代的侧信道(或例如,重复尝试利用直到标记正确)。

对于未知标记绕过,攻击者将需要一个非常好的"一次性"漏洞,很可能出现在复杂的文件格式解析中。漏洞利用仍然需要满足软时间限制。

即使不同的消息应用程序之间有大量共享代码,这里的利用技术也很可能是定制的,并且针对每个应用程序和每个漏洞。

第三部分将继续本系列,更详细地讨论将MTE应用于内核的具体细节,这有一些额外的细微差别(即使你只对用户空间应用程序感兴趣,也可能包含一些有价值的信息)。

[1] 一种不提供确定性保护的硬缓解措施,但攻击者可以通过"赢得"一个概率条件来普遍绕过。对于MTE(假设有4个标记位可用,可能有一个值被保留),这可能意味着1/15的成功几率。

[2] 一种确实提供确定性保护的硬缓解措施。