Memory Tagging Extension (MTE)
Last updated
Last updated
Lernen Sie und üben Sie AWS-Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lernen Sie und üben Sie GCP-Hacking: HackTricks Training GCP Red Team Expert (GRTE)
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 jedem Speicherbereich ein kleines Tag anzuhängen und einem entsprechenden Tag jeden Zeiger zuzuweisen, 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.
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 den Zeiger effektiv 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.
Tags innerhalb eines Zeigers werden in 4 Bits im oberen Byte gespeichert:
Daher ermöglicht dies bis zu 16 verschiedene Tagwerte.
Jede 16B physischen Speichers haben ein entsprechendes Speicher-Tag.
Die Speicher-Tags werden in einem dedizierten RAM-Bereich gespeichert (nicht für den normalen Gebrauch zugänglich). Mit 4-Bit-Tags für jeden 16B-Speicher können bis zu 3% des RAMs verwendet werden.
ARM führt die folgenden Anweisungen ein, um diese Tags im dedizierten RAM-Speicher zu manipulieren:
Die CPU überprüft die Tags während der Ausführung des Befehls, und bei einer Nichtübereinstimmung wird eine Ausnahme ausgelöst. Dies ist die langsamste und sicherste Methode.
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.
???
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 die Wahrscheinlichkeit des Wiederverwendens von Tags auf 1/17 -> etwa 7% reduziert.
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 (oder den ungültigen Tag) hat. Wenn der Angreifer Glück hat und der Speicher den gleichen 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 den gleichen 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 Speicher-Tag 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 der gleiche Block wieder mit dem SELBEN Tag wie zuvor allokiert wird, kann ein Angreifer diesen Zugriff nutzen, ohne dass dies erkannt wird (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 werden (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).