Memory Tagging Extension (MTE)

从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家)

支持HackTricks的其他方式:

基本信息

内存标记扩展(MTE) 旨在通过检测和防止与内存相关的错误(如缓冲区溢出和使用后释放漏洞)来增强软件的可靠性和安全性。作为ARM架构的一部分,MTE提供了一种机制,可以为每个内存分配附加一个小标记,并为引用该内存的每个指针附加一个相应的标记。这种方法允许在运行时检测非法内存访问,显著降低利用此类漏洞执行任意代码的风险。

内存标记扩展的工作原理

MTE通过将内存划分为小的固定大小块,并为每个块分配一个标记来运作。

当创建一个指针指向该内存时,它会获得相同的标记。该标记存储在内存指针的未使用位中,有效地将指针与其对应的内存块关联起来。

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

MTE指针标记

指针内的标记存储在顶部字节的4位中:

因此,这允许最多16个不同的标记值

MTE内存标记

16B的物理内存对应一个内存标记

内存标记存储在一个专用的RAM区域中(无法正常访问)。每16B内存标签占用RAM的3%。

ARM引入以下指令来操作专用RAM内存中的这些标记:

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
...

检查模式

同步

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%的几率)。

此外,只有**slabpage_alloc**使用带标记的内存,但在将来,这也将用于vmallocstack和``globals`(在视频时刻,这些仍然可能被滥用)。

检测到不匹配时,内核将恐慌以防止进一步利用和重试利用(MTE不会产生误报)。

参考

最后更新于