Memory Tagging Extension (MTE)

Reading time: 5 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks

Grundinformationen

Memory Tagging Extension (MTE) wurde entwickelt, um die Zuverlässigkeit und Sicherheit von Software zu verbessern, indem Speicherfehler wie Pufferüberläufe und Use-after-free-Schwachstellen erkannt und verhindert werden. MTE, als Teil der ARM-Architektur, bietet einen Mechanismus, um einen kleinen Tag an jede Speicherzuweisung anzuhängen und einen entsprechenden Tag an jeden Zeiger, der auf diesen Speicher verweist. Dieser Ansatz ermöglicht die Erkennung illegaler Speicherzugriffe zur Laufzeit, wodurch das Risiko, solche Schwachstellen auszunutzen, um beliebigen Code auszuführen, erheblich verringert wird.

Wie die Memory Tagging Extension funktioniert

MTE funktioniert, indem es Speicher in kleine, feste Blöcke unterteilt, wobei jeder Block einen Tag zugewiesen bekommt, der typischerweise einige Bits groß ist.

Wenn ein Zeiger erstellt wird, um auf diesen Speicher zu zeigen, erhält er denselben Tag. Dieser Tag wird in den ungenutzten Bits eines Speicherzeigers gespeichert, wodurch der Zeiger effektiv mit seinem entsprechenden Speicherblock verknüpft wird.

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

Wenn ein Programm über einen Zeiger auf den Speicher zugreift, überprüft die MTE-Hardware, ob der 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:

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

Daher sind bis zu 16 verschiedene Tag-Werte möglich.

MTE-Speicher-Tags

Jede 16B physischer Speicher hat einen entsprechenden Speicher-Tag.

Die Speicher-Tags werden in einem dedizierten RAM-Bereich gespeichert (nicht für die normale Nutzung zugänglich). Mit 4-Bit-Tags für jede 16B-Speicherzuweisung bis zu 3% des RAM.

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 der Anweisung, wenn es eine Diskrepanz gibt, wird eine Ausnahme ausgelöst.
Dies ist die langsamste und sicherste Methode.

Async

Die CPU überprüft die Tags asynchron, und wenn eine Diskrepanz gefunden wird, setzt sie ein Ausnahmebit in einem der Systemregister. Es ist schneller als die vorherige Methode, aber es ist unfähig, die genaue Anweisung, die die Diskrepanz verursacht hat, anzugeben, und es löst die Ausnahme nicht sofort aus, was dem Angreifer etwas Zeit gibt, seinen Angriff abzuschließen.

Mixed

???

Implementierungs- & Erkennungsbeispiele

Genannt Hardware Tag-Based KASAN, MTE-basiertes KASAN oder in-kernel MTE.
Die Kernel-Allocatoren (wie kmalloc) werden dieses Modul aufrufen, das das Tag vorbereitet, um es (zufällig) an den zugewiesenen Kernel-Speicher und an den zurückgegebenen Zeiger anzuhängen.

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

Das Tag 0xF ist der Übereinstimmungszeiger für alle. Ein Speicher mit diesem Zeiger erlaubt es, jeden Tag zu verwenden, um auf seinen Speicher zuzugreifen (keine Diskrepanzen). Dies könnte verhindern, dass MET einen Angriff erkennt, wenn dieses Tag im angegriffenen Speicher verwendet wird.

Daher gibt es nur 14 Werte, die zur Generierung von Tags verwendet werden können, da 0xE und 0xF reserviert sind, was die Wahrscheinlichkeit der Wiederverwendung von Tags auf 1/17 -> etwa 7% erhöht.

Wenn der Kernel auf das ungültige Tag-Granulat zugreift, wird die Diskrepanz erkannt. Wenn er auf einen anderen Speicherort zugreift, wird die Diskrepanz erkannt, wenn der Speicher ein anderes Tag (oder das ungültige Tag) hat. Wenn der Angreifer Glück hat und der Speicher dasselbe Tag verwendet, wird es nicht erkannt. Die Chancen liegen bei etwa 7%.

Ein weiterer Fehler tritt im letzten Granulat des zugewiesenen Speichers auf. Wenn die Anwendung 35B angefordert hat, wurde das Granulat von 32 bis 48 gegeben. Daher verwenden die Bytes von 36 bis 47 dasselbe Tag, wurden jedoch nicht angefordert. 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 neu markiert, sodass bei einem use-after-free, wenn der Speicher erneut zugegriffen wird, die Diskrepanz erkannt wird.

Wenn jedoch bei einem use-after-free derselbe Block erneut mit demselben Tag wie zuvor zugewiesen wird, kann ein Angreifer diesen Zugriff nutzen und dies wird nicht erkannt (etwa 7% Chance).

Darüber hinaus verwenden nur slab und page_alloc getaggten Speicher, aber in Zukunft wird dies auch in vmalloc, stack und globals verwendet (zum Zeitpunkt des Videos können diese noch missbraucht werden).

Wenn eine Diskrepanz erkannt wird, wird der Kernel panic auslösen, um weitere Ausbeutungen und Versuche des Exploits zu verhindern (MTE hat keine falsch positiven Ergebnisse).

Referenzen

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks