Memory Tagging Extension (MTE)

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Informations de base

Memory Tagging Extension (MTE) est conçue pour améliorer la fiabilité et la sécurité des logiciels en détectant et en empêchant les erreurs liées à la mémoire, telles que buffer overflows et use-after-free. MTE, en tant que partie de l’architecture ARM, fournit un mécanisme permettant d’attacher un petit tag à chaque allocation mémoire et un tag correspondant à chaque pointeur référant cette mémoire. Cette approche permet de détecter les accès mémoire illégaux à l’exécution, réduisant significativement le risque d’exploiter ces vulnérabilités pour exécuter du code arbitraire.

Comment fonctionne Memory Tagging Extension

MTE opère en divisant la mémoire en petits blocs de taille fixe, chaque bloc se voyant attribuer un tag, typiquement de quelques bits.

Lorsqu’un pointeur est créé pour pointer vers cette mémoire, il reçoit le même tag. Ce tag est stocké dans les bits inutilisés d’un pointeur mémoire, reliant ainsi le pointeur à son bloc mémoire correspondant.

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

Quand un programme accède à la mémoire via un pointeur, le matériel MTE vérifie que le tag du pointeur correspond au tag du bloc mémoire. Si les tags ne correspondent pas, cela indique un accès mémoire illégal.

Tags de pointeur MTE

Les tags à l’intérieur d’un pointeur sont stockés sur 4 bits dans l’octet de poids fort :

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

Par conséquent, cela permet jusqu’à 16 valeurs de tag différentes.

Tags mémoire MTE

Chaque 16B de mémoire physique possède un tag mémoire correspondant.

Les tags mémoire sont stockés dans une région RAM dédiée (non accessible pour un usage normal). Avoir des tags de 4 bits pour chaque bloc de 16B peut représenter jusqu’à 3% de la RAM.

ARM introduit les instructions suivantes pour manipuler ces tags dans la RAM dédiée :

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

Modes de vérification

Sync

Le CPU vérifie les tags pendant l’exécution de l’instruction, s’il y a un mismatch, il déclenche une exception (SIGSEGV with SEGV_MTESERR) et vous savez immédiatement l’instruction et l’adresse exactes.
C’est le plus lent et le plus sûr car la load/store fautive est bloquée.

Async

Le CPU vérifie les tags de manière asynchrone, et lorsqu’un mismatch est détecté il met un bit d’exception dans un des registres système. C’est plus rapide que le précédent mais il est incapable d’indiquer l’instruction exacte qui a causé le mismatch et il ne déclenche pas l’exception immédiatement (SIGSEGV with SEGV_MTEAERR), donnant du temps à l’attaquant pour compléter son attaque.

Mixed

Les préférences par cœur (par exemple écrire sync, async ou asymm dans /sys/devices/system/cpu/cpu*/mte_tcf_preferred) permettent au kernel de surclasser ou déclasser silencieusement les demandes par processus, donc les builds de production demandent généralement ASYNC tandis que les cœurs privilégiés forcent SYNC lorsque la charge le permet.

Implementation & Detection Examples

Called Hardware Tag-Based KASAN, MTE-based KASAN or in-kernel MTE.
Les allocateurs du kernel (comme kmalloc) appelleront ce module qui préparera le tag à utiliser (aléatoirement), l’attachera à l’espace kernel alloué et au pointeur retourné.

Notez qu’il marquera seulement autant de granules mémoire (16B chacun) que nécessaire pour la taille demandée. Donc si la taille demandée était 35 et qu’un slab de 60B est fourni, il marquera les premiers 16*3 = 48B avec ce tag et le reste sera marqué avec un soi‑disant invalid tag (0xE).

Le tag 0xF est le match all pointer. Une zone mémoire avec ce pointer permet que n’importe quel tag soit utilisé pour y accéder (pas de mismatches). Cela peut empêcher MTE de détecter une attaque si ce tag est utilisé dans la mémoire visée.

Il n’y a donc que 14 valeurs utilisables pour générer des tags car 0xE et 0xF sont réservés, donnant une probabilité de réutilisation des tags de 1/17 -> environ 7%.

Si le kernel accède au granule au tag invalide, le mismatch sera détecté. S’il accède à une autre adresse mémoire et que la mémoire a un tag différent (ou le tag invalide) le mismatch sera aussi détecté. Si l’attaquant a de la chance et que la mémoire utilise le même tag, cela ne sera pas détecté. Les chances sont d’environ 7%.

Un autre bug survient dans le dernier granule de la mémoire allouée. Si l’application a demandé 35B, elle reçoit le granule de 32 à 48. Par conséquent, les octets de 36 à 47 utilisent le même tag alors qu’ils n’ont pas été demandés. Si l’attaquant accède à ces octets supplémentaires, cela n’est pas détecté.

Quand kfree() est exécuté, la mémoire est retaggée avec le invalid memory tag, donc dans un use-after-free, lorsque la mémoire est à nouveau accédée, le mismatch est détecté.

Cependant, dans un use-after-free, si le même chunk est réalloué avec le MÊME tag qu’auparavant, un attaquant pourra exploiter cet accès et cela ne sera pas détecté (environ 7% de chance).

De plus, seuls slab et page_alloc utilisent la mémoire taggée mais à l’avenir cela sera aussi appliqué à vmalloc, stack et globals (au moment de la vidéo ces éléments peuvent encore être abusés).

Quand un mismatch est détecté le kernel fera un panic pour empêcher toute exploitation ultérieure et les nouvelles tentatives d’exploit (MTE n’a pas de faux positifs).

Speculative Tag Leakage (TikTag)

TikTag (2024) a démontré deux gadgets d’exécution spéculative (TIKTAG-v1/v2) capables de leak le tag d’allocation 4-bit de n’importe quelle adresse en <4 secondes avec >95% de succès. En touchant spéculativement des lignes de cache choisies par l’attaquant et en observant les timings induits par le prefetch, un attaquant peut dérandomiser le tag assigné aux processus Chrome, aux services système Android ou au Linux kernel puis fabriquer des pointeurs portant la valeur leaked. Une fois l’espace de tags forcé par brute-force, les hypothèses probabilistes de réutilisation de granules (≈7% taux de faux-négatifs) s’effondrent et les exploits classiques du heap (UAF, OOB) retrouvent une fiabilité proche de 100% même lorsque MTE est activé. L’article fournit aussi des proof-of-concept exploits qui pivotent des tags leaked vers le retagging de fake slabs, illustrant que les canaux latéraux spéculatifs restent une voie de contournement viable pour les schémas de tagging matériel.

Références

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks