Memory Tagging Extension (MTE)

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Basic Information

Memory Tagging Extension (MTE) è progettata per migliorare l’affidabilità e la sicurezza del software mediante la rilevazione e la prevenzione degli errori legati alla memoria, come buffer overflows e use-after-free vulnerabilities. MTE, come parte dell’architettura ARM, fornisce un meccanismo per associare 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 accessi illegali alla memoria a runtime, riducendo significativamente il rischio di sfruttare tali vulnerabilità per eseguire codice arbitrario.

Come funziona Memory Tagging Extension

MTE opera dividendo la memoria in blocchi piccoli e di dimensione fissa, a ciascuno dei quali viene assegnato un tag, tipicamente di pochi bit.

Quando viene creato un puntatore che punta a quella memoria, riceve lo stesso tag. Questo tag è memorizzato nei bit inutilizzati di un puntatore di memoria, collegando di fatto il puntatore al blocco di memoria corrispondente.

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

Quando un programma accede alla memoria tramite un puntatore, l’hardware MTE verifica che il tag del puntatore corrisponda al tag del blocco di memoria. Se i tag non corrispondono, ciò indica un accesso illegale alla memoria.

Tag dei puntatori MTE

I tag all’interno di un puntatore sono memorizzati in 4 bit nel byte più alto:

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

Di conseguenza, questo permette fino a 16 diversi valori di tag.

Tag di memoria MTE

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 l’uso normale). Avere tag a 4 bit per ogni 16B di memoria utilizza fino al 3% della RAM.

ARM introduce le seguenti istruzioni per manipolare questi tag nella memoria RAM dedicata:

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

Modalità di controllo

Sync

La CPU verifica i tag durante l’esecuzione dell’istruzione, se c’è una discrepanza genera un’eccezione (SIGSEGV con SEGV_MTESERR) e si conosce immediatamente l’istruzione e l’indirizzo esatti.
È la modalità più lenta ma anche la più sicura perché l’operazione di load/store incriminata viene bloccata.

Async

La CPU verifica i tag in modo asincrono, e quando viene trovata 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 solleva l’eccezione immediatamente (SIGSEGV con SEGV_MTEAERR), dando così all’attaccante del tempo per completare l’attacco.

Mixed

Preferenze per core (per esempio scrivendo sync, async o asymm in /sys/devices/system/cpu/cpu*/mte_tcf_preferred) permettono ai kernel di fare implicitamente upgrade o downgrade delle richieste per processo, quindi le build di produzione solitamente richiedono ASYNC mentre i core privilegiati forzano SYNC quando il carico di lavoro lo consente.

Implementation & Detection Examples

Chiamato Hardware Tag-Based KASAN, MTE-based KASAN o in-kernel MTE.
Gli allocator del kernel (come kmalloc) chiameranno questo modulo che preparerà il tag da usare (randomicamente), lo assocerà allo spazio kernel allocato e al puntatore restituito.

Nota che marcherà solo i granuli di memoria necessari (16B ciascuno) per la dimensione richiesta. Quindi se la dimensione richiesta era 35 e è stato fornito uno slab di 60B, marcherà i primi 16*3 = 48B con questo tag e il resto verrà marcato con il cosiddetto invalid tag (0xE).

Il tag 0xF è il match all pointer. Una memoria con questo puntatore permette che qualsiasi tag venga usato per accedere alla sua memoria (nessuna discrepanza). Questo può impedire a MTE di rilevare un attacco se quel tag è usato nella memoria attaccata.

Pertanto ci sono solo 14 valori che possono essere usati per generare tag poiché 0xE e 0xF sono riservati, dando una probabilità di riuso dei tag pari a 1/17 -> circa 7%.

Se il kernel accede al granulo con invalid tag, la discrepanza verrà rilevata. Se accede ad un’altra locazione di memoria e la memoria ha un tag diverso (o l’invalid tag) la discrepanza verrà anch’essa rilevata. Se l’attaccante è fortunato e la memoria sta usando lo stesso tag, non verrà rilevata. Le probabilità sono intorno al 7%.

Un altro bug si verifica nell’ultimo granulo della memoria allocata. Se l’applicazione ha richiesto 35B, le è stato assegnato il granulo da 32 a 48. Quindi, i byte da 36 a 47 usano lo stesso tag ma non erano stati richiesti. Se l’attaccante accede a questi byte extra, questo non viene rilevato.

Quando viene eseguita kfree(), la memoria viene ri-taggata con l’invalid memory tag, quindi in un use-after-free, quando la memoria viene nuovamente acceduta, la discrepanza viene rilevata.

Tuttavia, in un use-after-free, se lo stesso chunk viene riallocato con lo STESSO tag di prima, un attaccante potrà usare questo accesso e non verrà rilevato (circa 7% di probabilità).

Inoltre, solo slab and page_alloc usano memoria taggata ma in futuro questo sarà usato anche in vmalloc, stack e globals (al momento del video questi possono ancora essere abusati).

Quando viene rilevata una discrepanza il kernel andrà in panic per prevenire ulteriori exploitation e retry dell’exploit (MTE non ha falsi positivi).

Speculative Tag Leakage (TikTag)

TikTag (2024) ha dimostrato due gadget di speculative execution (TIKTAG-v1/v2) in grado di leak il tag di allocazione a 4 bit di qualsiasi indirizzo in <4 secondi con >95% di successo. Toccando speculativamente linee di cache scelte dall’attaccante e osservando i timing indotti dal prefetch, un attaccante può derandomizzare il tag assegnato ai processi Chrome, ai servizi di sistema Android o al Linux kernel e poi creare puntatori che trasportano il leaked value. Una volta che lo spazio dei tag viene brute-forzato, le assunzioni probabilistiche sul riuso dei granuli (≈7% false-negative rate) collassano e gli exploit classici di heap (UAF, OOB) riconquistano una affidabilità quasi del 100% anche quando MTE è abilitato. Il paper include anche proof-of-concept che pivotano da leaked tags a retagging di fake slabs, illustrando che i canali laterali speculativi restano una via di bypass praticabile per gli schemi di tagging hardware.

Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks