Memory Tagging Extension (MTE)

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) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Grundlegende Informationen

Memory Tagging Extension (MTE) wurde entwickelt, um die Zuverlässigkeit und Sicherheit von Software zu verbessern, indem speicherbezogene Fehler erkannt und verhindert werden, wie z. B. buffer overflows und use-after-free vulnerabilities. MTE, als Teil der ARM-Architektur, stellt einen Mechanismus bereit, um jeder Speicherzuweisung einen kleinen Tag zuzuordnen und jedem darauf verweisenden Zeiger einen entsprechenden Tag zu geben. Dieser Ansatz ermöglicht die Erkennung illegaler Speicherzugriffe zur Laufzeit und reduziert so das Risiko, dass solche Schwachstellen zum Ausführen von beliebigem Code ausgenutzt werden.

Wie Memory Tagging Extension funktioniert

MTE arbeitet, indem der Speicher in kleine, feste Blöcke unterteilt wird, wobei jedem Block ein Tag zugewiesen wird, der typischerweise nur wenige Bits groß ist.

Wenn ein Zeiger erstellt wird, der auf diesen Speicher zeigt, erhält er denselben Tag. Dieser Tag wird in den unbenutzten Bits eines Speicherzeigers gespeichert und verbindet so den Zeiger mit dem zugehörigen Speicherblock.

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

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

MTE Pointer-Tags

Die Tags innerhalb eines Zeigers werden in 4 Bits des obersten Bytes gespeichert:

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

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

MTE Memory-Tags

Für je 16B physischen Speichers existiert ein entsprechender Speichertag.

Die Speichertags werden in einem dedizierten RAM-Bereich gespeichert (nicht für den normalen Gebrauch zugänglich). Bei 4-Bit-Tags für je 16B Speicher beträgt der Bedarf bis zu 3% des RAM.

ARM führt die folgenden Instruktionen ein, um diese Tags im dedizierten RAM 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
...

Checking Modes

Sync

Die CPU überprüft die tags während der Ausführung der Instruktion; bei einem Mismatch löst sie eine Exception aus (SIGSEGV mit SEGV_MTESERR) und du weißt sofort genau, welche Instruktion und welche Adresse betroffen ist.
Das ist die langsamste, aber sicherste Option, weil der fehlerhafte Load/Store blockiert wird.

Async

Die CPU überprüft die tags asynchron, und wenn ein Mismatch gefunden wird, setzt sie ein Exception-Bit in einem der Systemregister. Es ist schneller als die vorherige Variante, kann aber nicht die genaue Instruktion benennen, die den Mismatch verursacht hat, und löst die Exception nicht sofort aus (SIGSEGV mit SEGV_MTEAERR), wodurch dem Angreifer etwas Zeit bleibt, seinen Angriff abzuschließen.

Mixed

Per-Core-Einstellungen (z. B. Schreiben von sync, async oder asymm nach /sys/devices/system/cpu/cpu*/mte_tcf_preferred) erlauben es Kernen, per-Process-Anfragen stillschweigend hoch- oder herunterzustufen. Daher fordern Produktions-Builds normalerweise ASYNC an, während privilegierte Kerne SYNC erzwingen, wenn die Workload es erlaubt.

Implementation & Detection Examples

Genannt Hardware Tag-Based KASAN, MTE-based KASAN oder in-kernel MTE.
Die Kernel-Allocatoren (wie kmalloc) werden dieses Modul aufrufen, welches das zu verwendende tag (zufällig) vorbereitet, es an den im Kernel reservierten Speicher anfügt und an den zurückgegebenen Pointer hängt.

Beachte, dass es nur so viele memory granules (je 16B) markiert, wie für die angeforderte Größe notwendig sind. Wenn also eine Größe von 35 angefragt wurde und ein slab von 60B vergeben wurde, markiert es die ersten 16*3 = 48B mit diesem tag und der Rest wird mit einem sogenannten invalid tag (0xE) markiert.

Das tag 0xF ist der match all pointer. Ein Memory mit diesem Pointer erlaubt es, jedes tag zu verwenden, um auf den Speicher zuzugreifen (keine Mismatches). Das kann verhindern, dass MTE einen Angriff erkennt, wenn dieses tag im angegriffenen Speicher verwendet wird.

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

Wenn der Kernel das invalid tag granule zugreift, wird der Mismatch detektiert. Wenn er eine andere Speicherstelle zugreift und der Speicher ein anderes tag (oder das invalid tag) hat, wird der Mismatch ebenfalls detektiert. Ist der Angreifer Glücklich und der Speicher verwendet dasselbe tag, wird es nicht detektiert. Die Chancen liegen bei etwa 7%.

Ein weiterer Fehler tritt im letzten granule des allozierten Speichers auf. Wenn die Anwendung 35B angefragt hat, wurde das Granule von 32 bis 48 gegeben. Daher verwenden die Bytes von 36 bis 47 dasselbe tag, wurden aber nicht angefordert. Greift der Angreifer auf diese zusätzlichen Bytes zu, wird das nicht detektiert.

Wenn kfree() ausgeführt wird, wird der Speicher mit dem invalid memory tag neu getaggt, sodass bei einem use-after-free beim erneuten Zugriff der Mismatch detektiert wird.

Allerdings: Bei einem use-after-free, wenn derselbe Chunk erneut mit DEM SELBEN tag alloziert wird, kann ein Angreifer diesen Zugriff weiterhin ausnutzen und dies wird nicht detektiert (etwa 7% Chance).

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

Wenn ein Mismatch detektiert wird, wird der Kernel einen panic auslösen, um weitere Ausbeutung und Wiederholungsversuche des Exploits zu verhindern (MTE hat keine False Positives).

Speculative Tag Leakage (TikTag)

TikTag (2024) zeigte zwei speculative execution gadgets (TIKTAG-v1/v2), die in <4 Sekunden mit >95% Erfolg das 4-bit allocation tag jeder Adresse leak-en können. Durch spekulatives Antasten attacker-ausgewählter Cache-Lines und Beobachten von prefetch-induzierten Timings kann ein Angreifer das Tag der Chrome-Prozesse, Android-System-Services oder des Linux-Kernels derandomisieren und dann Pointer mit dem geleakten Wert konstruieren. Sobald der Tag-Raum auf diese Weise ermittelt ist, brechen die probabilistischen Annahmen zur Granule-Wiederverwendung (≈7% false-negative Rate) zusammen und klassische Heap-Exploits (UAF, OOB) erreichen wieder nahezu 100% Zuverlässigkeit, selbst wenn MTE aktiviert ist. Das Paper enthält auch Proof-of-Concept-Exploits, die von geleakten tags zu Retagging gefälschter Slabs pivotieren und damit zeigen, dass speculative side channels weiterhin ein praktikabler Bypass-Pfad für hardware tagging schemes sind.

References

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) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks