Memory Tagging Extension (MTE)
Last updated
Last updated
学习并练习 AWS 黑客技能:HackTricks 培训 AWS 红队专家 (ARTE) 学习并练习 GCP 黑客技能:HackTricks 培训 GCP 红队专家 (GRTE)
内存标记扩展(MTE) 旨在通过检测和防止与内存相关的错误(如缓冲区溢出和使用已释放内存漏洞)来增强软件的可靠性和安全性。作为 ARM 架构的一部分,MTE 提供了一种机制,可以为每个内存分配附加一个小标记,并为引用该内存的每个指针附加一个相应的标记。这种方法允许在运行时检测非法内存访问,显著降低利用此类漏洞执行任意代码的风险。
MTE 通过将内存划分为小的固定大小块,每个块分配一个标记来运作。
当创建指针指向该内存时,它会获得相同的标记。该标记存储在内存指针的未使用位中,有效地将指针与其对应的内存块关联起来。
当程序通过指针访问内存时,MTE 硬件会检查指针的标记是否与内存块的标记匹配。如果标记不匹配,则表示存在非法内存访问。
指针内的标记存储在顶部字节的 4 位中:
因此,这允许最多 16 个不同的标记值。
每16B 物理内存对应一个内存标记。
内存标记存储在一个专用的 RAM 区域中(无法正常访问)。每 16B 内存标签占用 RAM 的 3%。
ARM 引入以下指令来操作专用 RAM 内存中的这些标记:
CPU在执行指令期间检查标签,如果不匹配,会引发异常。 这是最慢且最安全的模式。
CPU异步检查标签,当发现不匹配时,会在系统寄存器中设置异常位。比起同步模式,这种模式更快,但无法指出导致不匹配的确切指令,并且不会立即引发异常,给攻击者一些时间来完成攻击。
???
称为基于硬件标签的KASAN、基于MTE的KASAN或内核MTE。
内核分配器(如kmalloc
)将调用此模块,该模块将准备要使用的标签(随机)附加到分配的内核空间和返回的指针上。
请注意,它将仅标记足够的内存粒度(每个16字节)以满足请求的大小。因此,如果请求的大小为35,给出了一个60字节的slab,它将使用此标签标记前16*3 = 48字节,其余部分将用所谓的**无效标签(0xE)**标记。
标签0xF是匹配所有指针。具有此指针的内存允许使用任何标签访问其内存(无不匹配)。如果在受攻击的内存中使用此标签,这可能会阻止MET检测到攻击。
因此,只有14个值可用于生成标签,0xE和0xF已保留,导致标签重用的概率为1/17 -> 约7%。
如果内核访问无效标签粒度,将检测到不匹配。如果访问另一个内存位置,如果内存具有不同的标签(或无效标签),将检测到不匹配。如果攻击者幸运,内存使用相同的标签,则不会检测到不匹配。概率约为7%。
另一个错误发生在分配内存的最后一个粒度上。如果应用程序请求了35字节,它将获得从32到48的粒度。因此,从36到47的字节使用相同的标签,但未被请求。如果攻击者访问这些额外字节,这不会被检测到。
当执行**kfree()
时,内存将重新标记为无效内存标签,因此在使用后释放时,再次访问内存时,将检测到不匹配**。
然而,在使用后释放中,如果相同的块再次使用与之前相同的标签重新分配,攻击者将能够使用此访问,这不会被检测到(约7%的几率)。
此外,只有**slab
和page_alloc
**使用带标记的内存,但在将来,vmalloc
、stack
和globals
也将使用(在视频时刻,这些仍然可能被滥用)。
当检测到不匹配时,内核将恐慌以防止进一步利用和尝试利用漏洞(MTE不会产生误报)。