
Demo proof-of-concept e libreria libkdump che dimostrano l'attacco microarchitetturale Meltdown, con fuga di memoria kernel e fisica su CPU Intel vulnerabili.
Questo repository contiene diverse applicazioni che dimostrano il bug Meltdown. Per informazioni tecniche sul bug, fare riferimento al paper:
Le applicazioni in questo repository sono costruite con libkdump, una libreria che abbiamo sviluppato per il paper. Questa libreria semplifica lo sfruttamento del bug adattandosi automaticamente a determinate proprietà dell'ambiente.
Questo repository contiene diversi video che dimostrano Meltdown
Questo repository contiene cinque demo per dimostrare diversi casi d'uso. Tutte le demo sono testate su Ubuntu 16.04 con un Intel Core i7-6700K, ma dovrebbero funzionare su qualsiasi sistema Linux con qualsiasi CPU Intel moderna dal 2010 in poi.
Per risultati ottimali, raccomandiamo una CPU veloce che supporti Intel TSX (ad es. qualsiasi Intel Core i7-5xxx, i7-6xxx o i7-7xxx). Inoltre, ogni demo dovrebbe essere vincolata a un singolo core della CPU, ad es. con taskset.
Come prerequisito, è necessario installare glibc-static sulla propria macchina.
Per sistemi basati su RPM:
sudo yum install -y glibc-static
test)Questa è la demo più basilare. Usa Meltdown per leggere indirizzi accessibili dal proprio spazio di indirizzamento, senza violare alcun meccanismo di isolamento.
Se questa demo non funziona, molto probabilmente anche le demo rimanenti non funzioneranno. Le ragioni sono molteplici, ad es. la CPU potrebbe essere troppo lenta, non supportare l'esecuzione out-of-order, il timer ad alta risoluzione non è abbastanza preciso (specialmente nelle VM), il sistema operativo non supporta gestori di segnali personalizzati, ecc.
make
taskset 0x1 ./test
Se si vede un output simile a questo
Expect: Welcome to the wonderful world of microarchitectural attacks
Got: Welcome to the wonderful world of microarchitectural attacks
allora la demo di base funziona.
kaslr)A partire dal kernel Linux 4.12, KASLR (Kernel Address Space Layout Randomizaton) è attivo per impostazione predefinita. Ciò significa che la posizione del kernel (e anche la mappa fisica diretta che mappa l'intera memoria fisica) cambia ad ogni riavvio.
Questa demo usa Meltdown per rivelare la randomizzazione (segreta) della mappa fisica diretta. Questa demo richiede privilegi di root per velocizzare il processo. Il paper descrive una variante che non richiede privilegi di root.
make
sudo taskset 0x1 ./kaslr
Dopo alcuni secondi, si dovrebbe vedere qualcosa di simile a questo
[+] Direct physical map offset: 0xffff880000000000
reliability)Questa demo verifica quanto affidabilmente possa essere letta la memoria fisica. Per questa demo, è necessario l'offset della mappa fisica diretta (ad es. dalla demo #2) oppure è necessario disabilitare KASLR specificando nokaslr nella riga di comando del kernel.
Compilare e avviare reliability. Se KASLR è abilitato, il primo parametro è l'offset della mappa fisica diretta. Altrimenti, il programma non richiede alcun parametro.
make
sudo taskset 0x1 ./reliability 0xffff880000000000
Dopo alcuni secondi, si dovrebbe ottenere un output simile a questo:
[-] Success rate: 99.93% (read 1354 values)
physical_reader)Questa demo legge la memoria da un processo diverso leggendo direttamente la memoria fisica. Per questa demo, è necessario l'offset della mappa fisica diretta (ad es. dalla demo #2) oppure è necessario disabilitare KASLR specificando nokaslr nella riga di comando del kernel.
In linea di principio, questo programma può leggere indirizzi fisici arbitrari. Tuttavia, poiché la memoria fisica contiene molti dati non leggibili dall'uomo, forniamo uno strumento di test (secret), che inserisce una stringa leggibile dall'uomo in memoria e fornisce direttamente l'indirizzo fisico di questa stringa.
Per la demo, eseguire prima secret (come root) per ottenere l'indirizzo fisico di una stringa leggibile dall'uomo:
make
sudo ./secret
Dovrebbe produrre un output simile a questo:
[+] Secret: If you can read this, this is really bad
[+] Physical address of secret: 0x390fff400
[+] Exit with Ctrl+C if you are done reading the secret
Mentre il programma secret è in esecuzione, avviare physical_reader. Il primo parametro è l'indirizzo fisico stampato da secret. Se KASLR non è disabilitato, il secondo parametro è l'offset della mappa fisica diretta.
taskset 0x1 ./physical_reader 0x390fff400 0xffff880000000000
Dopo alcuni secondi, si dovrebbe ottenere un output simile a questo:
[+] Physical address : 0x390fff400
[+] Physical offset : 0xffff880000000000
[+] Reading virtual address: 0xffff880390fff400
If you can read this, this is really bad
memdump)Questa demo esegue il dump del contenuto della memoria. Come le demo #3 e #4, usa la mappa fisica diretta per eseguire il dump del contenuto della memoria fisica in un formato simile a un hexdump.
Ancora una volta, poiché la memoria fisica contiene molti contenuti non leggibili dall'uomo, forniamo uno strumento di test per riempire grandi quantità di memoria fisica con stringhe leggibili dall'uomo.
Per la demo, eseguire prima memory_filler per riempire la memoria con stringhe leggibili dall'uomo. Il primo argomento è la quantità di memoria (in gigabyte) da riempire.
make
./memory_filler 9
Poi, eseguire lo strumento memdump per eseguire il dump del contenuto della memoria. Se si è eseguito memory_filler in precedenza, si dovrebbero vedere alcuni frammenti di stringhe.
Se si ha Firefox o Chrome con più schede aperte, si potrebbero anche vedere parti dei siti web aperti o chiusi di recente.
Il primo parametro è l'indirizzo fisico da cui deve iniziare il dump (lasciare vuoto per iniziare dal primo gigabyte). Il secondo parametro è la quantità di byte che si desidera leggere; per leggere tutto, dare -1. Se KASLR non è disabilitato, il terzo parametro è l'offset della mappa fisica diretta.
taskset 0x1 ./memdump 0x240000000 -1 0xffff880000000000 # start at 9 GB
Si dovrebbe ottenere un hexdump di parti della memoria (potenzialmente contenente anche segreti come password, vedere l'esempio nel paper), ad es.:
240001c9f: | 00 6d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | .m.............. |
24000262f: | 00 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | .}.............. |
24000271f: | 00 00 00 00 00 00 00 00 00 00 00 00 65 6e 20 75 | ............en u |
24000272f: | 73 65 72 20 73 70 61 63 65 20 61 6e 64 20 6b 65 | ser space and ke |
24000273f: | 72 6e 65 6c 57 65 6c 63 6f 6d 65 20 74 6f 20 74 | rnelWelcome to t |
24000298f: | 00 61 72 79 20 62 65 74 77 65 65 6e 20 75 73 65 | .ary between use |
24000299f: | 72 20 73 70 61 63 65 20 61 6e 64 20 6b 65 72 6e | r space and kern |
2400029af: | 65 6c 42 75 72 6e 20 61 66 74 65 72 20 72 65 61 | elBurn after rea |
2400029bf: | 64 69 6e 67 20 74 68 69 73 20 73 74 72 69 6e 67 | ding this string |
240002dcf: | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c8 | ................ |
2400038af: | 6a 75 73 74 20 73 70 69 65 64 20 6f 6e 20 61 00 | just spied on a. |
240003c8f: | 00 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
24000412f: | 00 00 00 00 00 00 00 00 00 00 00 00 65 74 73 2e | ............ets. |
24000413f: | 2e 2e 57 65 6c 63 6f 6d 65 20 74 6f 20 74 68 65 | ..Welcome to the |
2400042ff: | 00 00 00 00 00 00 00 00 00 6e 67 72 61 74 75 6c | .........ngratul |
24000430f: | 61 74 69 6f 6e 73 2c 20 79 6f 75 20 6a 75 73 74 | ations, you just |
24000431f: | 20 73 70 69 65 64 20 6f 6e 20 61 6e 20 61 70 70 | spied on an app |
Funziona su Windows / Ubuntu su Windows (WSL) / Mac OS?
No. Questo PoC funziona solo su Linux, poiché utilizza proprietà specifiche del kernel Linux, come la mappa fisica diretta.
Posso eseguire il PoC in una macchina virtuale?
Sì, il PoC funziona anche su macchine virtuali. Tuttavia, a causa del livello aggiuntivo introdotto da una macchina virtuale, potrebbe non funzionare bene come su hardware nativo.
Il programma KASLR (kaslr) non trova l'offset!
Lo strumento kaslr esegue solo pochissime misurazioni per essere veloce. Se non trova l'offset, ci sono due possibilità:
kaslr.c: config.retries = 1000;kaslr_offset per leggere direttamente l'offset dal kernel. Installare gli header del kernel per il proprio kernel (sudo apt-get install linux-headers-`uname -r` ) ed eseguire sudo ./direct_physical_map.shHai detto che funziona su memoria non in cache, ma tutte le tue demo assicurano che la memoria sia in cache!
Farlo funzionare su memoria non in cache è più complicato e spesso richiede un po' di aggiustamento dei parametri. Pertanto, nel PoC assicuriamo che la memoria sia in cache per rendere più facile la riproduzione. Tuttavia, è sufficiente rimuovere il codice che mette in cache i valori e sostituirlo con un clflush per testare l'exploit su memoria non in cache (vedere il Video #5 per un esempio).
Sebbene non presente nel post originale del blog di Google, ciò è stato confermato anche da ricercatori indipendenti (ad es. , , ).
Avvertenza #1: Forniamo questo codice così com'è. Sei responsabile di proteggere te stesso, la tua proprietà e i tuoi dati, e gli altri, da qualsiasi rischio causato da questo codice. Questo codice può causare comportamenti inaspettati e indesiderati sulla tua macchina. Questo codice potrebbe non rilevare la vulnerabilità sulla tua macchina.
Avvertenza #2: Se scopri che un computer è suscettibile al bug Meltdown, potresti voler evitare di usarlo come sistema multiutente. Meltdown viola la protezione della memoria della CPU. Su una macchina suscettibile al bug Meltdown, un processo può leggere tutte le pagine usate da altri processi o dal kernel.
Avvertenza #3: Questo codice è solo a scopo di test. Non eseguirlo su sistemi produttivi. Non eseguirlo su alcun sistema che potrebbe essere usato da un'altra persona o entità.
Semplicemente non funziona sul mio computer, cosa posso fare?
Ci possono essere molte ragioni diverse per questo. Abbiamo raccolto alcune cose che si possono provare:
libkdump/libkdump.c nella riga #define MELTDOWN meltdown_nonull. Provare ad esempio meltdown invece di meltdown_nonull, che funziona molto meglio su alcune macchine (ma per niente su altre).stress con stress -i 2 (o altri valori per il parametro i, a seconda del numero di core).