Memory Tagging Extension (MTE)

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

基本信息

Memory Tagging Extension (MTE) 旨在通过检测和防止内存相关错误来提高软件的可靠性和安全性,例如 buffer overflows 和 use-after-free 漏洞。MTE 作为 ARM 架构的一部分,提供了一种机制,可以为每次内存分配附加一个小的 tag,并为引用该内存的每个指针附加一个对应的 tag。这种方法允许在运行时检测非法的内存访问,从而显著降低利用这些漏洞执行任意代码的风险。

Memory Tagging Extension 的工作原理

MTE 的工作方式是**将内存划分为小的固定大小的块,为每个块分配一个 tag,**通常为几位。

当创建指针指向该内存时,指针会获得相同的 tag。该 tag 存储在内存指针的未使用位中,从而将指针与其对应的内存块关联起来。

https://www.youtube.com/watch?v=UwMt0e_dC_Q

当程序通过指针访问内存时,MTE 硬件会检查指针的 tag 是否与内存块的 tag 匹配。如果 tag 不匹配,则表示发生了非法内存访问

MTE Pointer Tags

指针内的 tag 存储在高位字节的 4 位中:

https://www.youtube.com/watch?v=UwMt0e_dC_Q

因此,这允许最多 16 种不同的 tag 值

MTE Memory Tags

16B 的物理内存 对应一个 memory tag

这些 memory tags 存储在一个专用的 RAM 区域(普通使用不可访问)。为每 16B 分配 4 位 tag 会占用高达 3% 的 RAM。

ARM 引入了以下指令用于在该专用 RAM 区域操作这些 tag:

STG [<Xn/SP>], #<simm>    Store Allocation (memory) Tag
LDG <Xt>, [<Xn/SP>]       Load Allocatoin (memory) Tag
IRG <Xd/SP>, <Xn/SP>      Insert Random [pointer] Tag
...

检查模式

Sync

CPU 会在指令执行期间检查 tag during the instruction executing,如果不匹配,会触发异常(SIGSEGV with SEGV_MTESERR),你会立即知道确切的指令和地址。
这是最慢但最安全的,因为有问题的 load/store 会被阻止。

Async

CPU 会异步检查 tag asynchronously,当发现不匹配时会在某个系统寄存器中设置异常位。它比前者 faster,但 无法指明 导致不匹配的确切指令,并且不会立即触发异常(SIGSEGV with SEGV_MTEAERR),这会给攻击者一些时间完成攻击。

Mixed

每核偏好(例如将 syncasyncasymm 写入 /sys/devices/system/cpu/cpu*/mte_tcf_preferred)允许内核在不显式通知的情况下悄然升级或降级每个进程的请求,因此生产构建通常请求 ASYNC,而在负载允许时特权核心会强制 SYNC。

实现与检测示例

称为 Hardware Tag-Based KASAN、MTE-based KASAN 或 in-kernel MTE。
内核分配器(如 kmalloc)会 call this module,该模块会随机准备要使用的 tag,并将其附加到分配的内核空间和返回的指针上。

注意它 只会标记足够的 memory granules(每个 16B)以满足请求的大小。所以如果请求大小为 35 且分配到了一个 60B 的 slab,它会用该 tag 标记前 16*3 = 48B,而剩余部分会被标记为所谓的 invalid tag (0xE)

tag 0xFmatch all pointer。带有该 pointer 的内存允许使用 any tag to be used 来访问其内存(不会产生不匹配)。如果被攻击的内存使用了该 tag,MTE 可能无法检测到攻击。

因此可用于生成 tag 的只有 14 个值(0xE 和 0xF 被保留),这使得 重用 tag 的概率为 1/17 -> 大约 7%

如果内核访问了 invalid tag granule,则会检测到不匹配。如果它访问了另一处内存且该内存具有不同的 tag(或 invalid tag),也会检测到不匹配。如果攻击者幸运且内存使用相同的 tag,则不会被检测到。概率大约为 7%。

另一个问题发生在分配内存的最后一个 granule。如果应用请求 35B,则会得到 32 到 48 的 granule。因此,从 36 到 47 的字节使用相同的 tag,但它们并未被请求。如果攻击者访问这些额外字节,则不会被检测到

当执行 kfree() 时,内存会被重新打上 invalid memory tag,所以在 use-after-free 情况下,当内存再次被访问时,不匹配会被检测到

然而,在 use-after-free 中,如果相同的 chunk 被以与之前相同的 TAG 重新分配,攻击者将能够利用该访问且不会被检测到(约 7% 的概率)。

此外,目前只有 slabpage_alloc 使用带 tag 的内存,但未来这也会用于 vmallocstackglobals(在视频制作时这些仍可被滥用)。

检测到不匹配时,内核会 panic 以防止进一步利用和反复尝试利用(MTE 不会产生误报)。

Speculative Tag Leakage (TikTag)

TikTag (2024) 演示了两个 speculative execution gadgets (TIKTAG-v1/v2),能够在 <4 秒内以 >95% 的成功率 leak 任何地址的 4-bit allocation tag。通过对攻击者选择的 cache lines 进行 speculative 访问并观测由 prefetch 引起的时序,攻击者可以对分配给 Chrome 进程、Android 系统服务或 Linux kernel 的 tag 进行 derandomize,然后构造携带 leaked value 的指针。一旦 tag 空间被 brute-forced 掉,概率性的 granule 重用假设(≈7% 假阴性率)就会崩溃,经典堆利用(UAF、OOB)即使在 MTE 启用时也能恢复接近 100% 的可靠性。论文还提供了从 leaked tags 转向 retagging fake slabs 的概念验证利用,说明 speculative side channels 仍然是硬件标记方案的可行绕过路径。

References

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks