Memory Tagging Extension (MTE)
Last updated
Last updated
Impara e pratica l'Hacking su AWS: HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica l'Hacking su GCP: HackTricks Training GCP Red Team Expert (GRTE)
Memory Tagging Extension (MTE) è progettato per migliorare l'affidabilità e la sicurezza del software rilevando e prevenendo errori legati alla memoria, come buffer overflow e vulnerabilità di uso dopo la liberazione. MTE, come parte dell'architettura ARM, fornisce un meccanismo per allegare un piccolo tag a ogni allocazione di memoria e un tag corrispondente a ogni puntatore che fa riferimento a quella memoria. Questo approccio consente di rilevare gli accessi illegali alla memoria durante l'esecuzione, riducendo significativamente il rischio di sfruttare tali vulnerabilità per eseguire codice arbitrario.
MTE opera dividendo la memoria in blocchi di dimensioni fisse, con ciascun blocco assegnato un tag, tipicamente di pochi bit.
Quando viene creato un puntatore per puntare a quella memoria, ottiene lo stesso tag. Questo tag è memorizzato nei bit non utilizzati di un puntatore di memoria, collegando efficacemente il puntatore al suo blocco di memoria corrispondente.
Quando un programma accede alla memoria tramite un puntatore, l'hardware MTE controlla che il tag del puntatore corrisponda al tag del blocco di memoria. Se i tag non corrispondono, indica un accesso illegale alla memoria.
I tag all'interno di un puntatore sono memorizzati in 4 bit all'interno del byte superiore:
Ciò consente fino a 16 valori di tag diversi.
Ogni 16B di memoria fisica ha un tag di memoria corrispondente.
I tag di memoria sono memorizzati in una regione RAM dedicata (non accessibile per un uso normale). Avendo tag di 4 bit per ogni tag di memoria di 16B, fino al 3% di RAM.
ARM introduce le seguenti istruzioni per manipolare questi tag nella memoria RAM dedicata:
La CPU controlla i tag durante l'esecuzione dell'istruzione, se c'è una discrepanza, genera un'eccezione. Questa è la più lenta e sicura.
La CPU controlla i tag in modo asincrono, e quando trova una discrepanza imposta un bit di eccezione in uno dei registri di sistema. È più veloce della precedente ma non è in grado di indicare l'istruzione esatta che ha causato la discrepanza e non genera immediatamente l'eccezione, dando del tempo all'attaccante per completare il suo attacco.
???
Chiamato KASAN basato su tag hardware, KASAN basato su MTE o MTE nel kernel.
Gli allocatori del kernel (come kmalloc
) chiameranno questo modulo che preparerà il tag da utilizzare (casualmente) per attaccarlo allo spazio kernel allocato e al puntatore restituito.
Si noti che verranno contrassegnati solo abbastanza granuli di memoria (16B ciascuno) per la dimensione richiesta. Quindi, se la dimensione richiesta era 35 e veniva fornito uno slab di 60B, verranno contrassegnati i primi 16*3 = 48B con questo tag e il resto verrà contrassegnato con un cosiddetto tag non valido (0xE).
Il tag 0xF è il puntatore di corrispondenza totale. Una memoria con questo puntatore consente l'uso di qualsiasi tag per accedere alla sua memoria (nessuna discrepanza). Ciò potrebbe impedire a MET di rilevare un attacco se questo tag viene utilizzato nella memoria attaccata.
Pertanto ci sono solo 14 valori che possono essere utilizzati per generare tag poiché 0xE e 0xF sono riservati, dando una probabilità di riutilizzo dei tag pari a 1/17 -> circa 7%.
Se il kernel accede al granulo con tag non valido, la discrepanza verrà rilevata. Se accede a un'altra posizione di memoria, se la memoria ha un tag diverso (o il tag non valido) la discrepanza verrà rilevata. Se l'attaccante ha fortuna e la memoria utilizza lo stesso tag, non verrà rilevata. Le probabilità sono circa del 7%.
Un altro bug si verifica nell'ultimo granulo della memoria allocata. Se l'applicazione ha richiesto 35B, le è stato dato il granulo dal 32 al 48. Pertanto, i byte dal 36 al 47 utilizzano lo stesso tag ma non sono stati richiesti. Se l'attaccante accede a questi byte extra, ciò non viene rilevato.
Quando viene eseguito kfree()
, la memoria viene contrassegnata nuovamente con il tag di memoria non valido, quindi in un uso dopo la liberazione, quando la memoria viene nuovamente accessa, la discrepanza viene rilevata.
Tuttavia, in un uso dopo la liberazione, se lo stesso blocco viene riallocato nuovamente con lo STESSO tag come precedentemente, un attaccante potrà utilizzare questo accesso e ciò non verrà rilevato (circa il 7% di probabilità).
Inoltre, solo slab
e page_alloc
utilizzano la memoria contrassegnata ma in futuro verrà utilizzata anche in vmalloc
, stack
e globals
(al momento del video questi possono ancora essere abusati).
Quando viene rilevata una discrepanza, il kernel va in panico per impedire ulteriori sfruttamenti e tentativi dell'exploit (MTE non ha falsi positivi).