Memory Tagging Extension (MTE)

Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Grundlegende Informationen

Memory Tagging Extension (MTE) ist darauf ausgelegt, die Softwarezuverlässigkeit und -sicherheit zu verbessern, indem Speicherfehler erkannt und verhindert werden, wie Pufferüberläufe und Use-after-Free-Schwachstellen. MTE, als Teil der ARM-Architektur, bietet einen Mechanismus, um jeder Speicherzuweisung ein kleines Tag anzuhängen und einem entsprechenden Tag für jeden Zeiger, der auf diesen Speicher verweist. Dieser Ansatz ermöglicht die Erkennung illegaler Speicherzugriffe zur Laufzeit und reduziert das Risiko, solche Schwachstellen zur Ausführung beliebigen Codes auszunutzen erheblich.

Wie Memory Tagging Extension funktioniert

MTE arbeitet, indem der Speicher in kleine, festgelegte Blöcke unterteilt wird, wobei jedem Block ein Tag zugewiesen wird, das in der Regel einige Bits groß ist.

Wenn ein Zeiger erstellt wird, um auf diesen Speicher zu verweisen, erhält er dasselbe Tag. Dieses Tag wird in den unbenutzten Bits eines Speicherzeigers gespeichert und verknüpft effektiv den Zeiger mit seinem entsprechenden Speicherblock.

Wenn ein Programm über einen Zeiger auf den Speicher zugreift, überprüft die MTE-Hardware, ob das Tag des Zeigers mit dem Tag des Speicherblocks übereinstimmt. Wenn die Tags nicht übereinstimmen, deutet dies auf einen illegalen Speicherzugriff hin.

MTE-Zeiger-Tags

Tags innerhalb eines Zeigers werden in 4 Bits im oberen Byte gespeichert:

Daher sind bis zu 16 verschiedene Tagwerte möglich.

MTE-Speichertags

Jede 16B physischen Speichers haben ein entsprechendes Speichertag.

Die Speichertags werden in einem dedizierten RAM-Bereich gespeichert (nicht für den normalen Gebrauch zugänglich). Mit 4-Bit-Tags für jeden 16B-Speichertag bis zu 3% des RAMs.

ARM führt die folgenden Anweisungen ein, um diese Tags im dedizierten RAM-Speicher zu manipulieren:

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

Überprüfungsmodi

Sync

Die CPU überprüft die Tags während der Ausführung des Befehls, bei einer Nichtübereinstimmung wird eine Ausnahme ausgelöst. Dies ist die langsamste und sicherste Methode.

Async

Die CPU überprüft die Tags asynchron, und wenn eine Nichtübereinstimmung gefunden wird, setzt sie ein Ausnahmebit in einem der Systemregister. Es ist schneller als die vorherige Methode, kann jedoch nicht genau angeben, welcher Befehl die Nichtübereinstimmung verursacht hat, und löst die Ausnahme nicht sofort aus, was dem Angreifer Zeit gibt, seinen Angriff abzuschließen.

Mixed

???

Implementierungs- & Erkennungsbeispiele

Genannt Hardware-Tag-basiertes KASAN, MTE-basiertes KASAN oder In-Kernel MTE. Die Kernel-Allokatoren (wie kmalloc) werden dieses Modul aufrufen, das den Tag vorbereitet (zufällig) an den allokierten Kernel-Speicher anhängt und an den zurückgegebenen Zeiger.

Beachten Sie, dass nur genügend Speichergranulate (je 16B) für die angeforderte Größe markiert werden. Wenn also eine Größe von 35 angefordert wurde und ein Block von 60B gegeben wurde, werden die ersten 16*3 = 48B mit diesem Tag markiert und der Rest wird mit einem sogenannten ungültigen Tag (0xE) markiert.

Der Tag 0xF ist der Match-All-Zeiger. Ein Speicher mit diesem Zeiger erlaubt den Zugriff auf seinen Speicher mit beliebigem Tag (keine Nichtübereinstimmungen). Dies könnte verhindern, dass MET einen Angriff erkennt, wenn dieser Tag im angegriffenen Speicher verwendet wird.

Daher gibt es nur 14 Werte, die verwendet werden können, um Tags zu generieren, da 0xE und 0xF reserviert sind, was eine Wahrscheinlichkeit des Wiederverwendens von Tags von 1/17 ergibt -> etwa 7%.

Wenn der Kernel auf das ungültige Tag-Granulat zugreift, wird die Nichtübereinstimmung erkannt. Wenn er auf eine andere Speicherstelle zugreift, wird die Nichtübereinstimmung erkannt, wenn der Speicher einen anderen Tag hat (oder den ungültigen Tag). Wenn der Angreifer Glück hat und der Speicher denselben Tag verwendet, wird dies nicht erkannt. Die Chancen liegen bei etwa 7%.

Ein weiterer Fehler tritt im letzten Granulat des allokierten Speichers auf. Wenn die Anwendung 35B angefordert hat, wurde das Granulat von 32 bis 48 gegeben. Daher verwenden die Bytes von 36 bis 47 denselben Tag, obwohl sie nicht angefordert wurden. Wenn der Angreifer auf diese zusätzlichen Bytes zugreift, wird dies nicht erkannt.

Wenn kfree() ausgeführt wird, wird der Speicher mit dem ungültigen Speichertag versehen, sodass bei einem Use-After-Free, wenn der Speicher erneut zugegriffen wird, die Nichtübereinstimmung erkannt wird.

Jedoch, bei einem Use-After-Free, wenn derselbe Block erneut mit DEMSELBEN Tag wie zuvor allokiert wird, kann ein Angreifer diesen Zugriff nutzen und dies wird nicht erkannt (ca. 7% Chance).

Außerdem verwenden nur slab und page_alloc markierten Speicher, aber in Zukunft wird dies auch bei vmalloc, stack und globals verwendet (zum Zeitpunkt des Videos können diese noch missbraucht werden).

Wenn eine Nichtübereinstimmung erkannt wird, wird der Kernel abstürzen, um eine weitere Ausnutzung und Wiederholungen des Exploits zu verhindern (MTE hat keine falschen Positiven).

Referenzen

Last updated