
Im Bereich des modernen Computings erstrecken sich Sicherheitsprobleme über Betriebssystemverletzlichkeiten und Softwarefehler hinaus. Tief unter den Abstraktionen haben sich unsere Prozessoren zu komplexen Mikroarchitekturen entwickelt—Pipelines, Caches, Puffer und Ausführungs-Engines—, die darauf ausgelegt sind, maximale Leistung zu erzielen. Ironischerweise führen diese Merkmale zu neuen und subtilen Sicherheitsrisiken, die zu den sogenannten Mikroarchitekturangriffen führen. Solche Angriffe nutzen die unbeabsichtigte gemeinsame Nutzung—und das Auslaufen—von mikroarchitektonischen Zuständen zwischen gleichzeitig ausgeführten Anwendungen aus, manchmal sogar in perfekt sicherer Software.
Dieser umfassende Blogbeitrag zielt darauf ab, Mikroarchitekturangriffe zu entmystifizieren und behandelt:
Ob Sie ein Anfänger, Forscher, Softwareentwickler oder Cybersicherheitsexperte sind, dieser Leitfaden wird Ihnen helfen, diese mächtigen modernen Angriffe zu verstehen—und wie Sie sich dagegen schützen können.
Mikroarchitekturangriffe sind Ausnutzungstechniken, die unbeabsichtigte Informationslecks im unteren Design der Hardware eines Prozessors nutzen.
Anders als typische Softwareausnutzungen erfordern Mikroarchitekturangriffe keine Programmfehler in der Anwendung oder dem Betriebssystem. Stattdessen nutzen sie aus, wie moderne CPUs versuchen, die Leistung zu maximieren, wie das gemeinsame Nutzen von Caches oder das Neuordnen von Anweisungen.
Moderne CPUs teilen kritische Hardwarestrukturen zwischen Anwendungen und sogar virtuellen Maschinen, wie z.B.:
Da diese Strukturen nicht perfekt isoliert sind, kann ein Prozess oft die Auswirkungen eines anderen beobachten oder schlussfolgern. Angreifer nutzen dieses implizite Teilen aus, um Geheimnisse durch Beobachtung indirekter physischer Effekte (wie leichte Änderungen der Speicherzugriffsdauer) zu extrahieren.
Es gibt zwei große Kategorien:
Verdeckte Kanäle schaffen einen Kommunikationsweg zwischen zwei Akteuren (Sender und Empfänger), der vom Design des Systems nicht beabsichtigt ist. Eine Anwendung moduliert einige gemeinsame Ressourcen, während eine andere diese Änderungen beobachtet, um eine Nachricht zu rekonstruieren.
Beispiele:
Seitenkanalangriffe lecken sensible Informationen, ohne direkte Kommunikation. Stattdessen nutzen sie Informationen aus, die durch die Tätigkeit des Opfers „verschüttet“ werden.
Beispiele:
Beide Kanäle erlauben es einem Prozess, Informationen über einen anderen zu erkennen—manchmal über Container-, VM- oder Benutzergrenzen hinweg.
Heterogene Computersysteme bestehen aus mehreren Prozessortypen (allgemeine CPUs, GPUs, FPGAs, KI-Beschleuniger usw.) auf derselben Plattform, die oft einige Speicher und/oder mikroarchitektonischen Zustand teilen.
Angenommen, ein GPU und eine CPU teilen einen Cache-Bereich. Ein wenig privilegierter Prozess, der auf der GPU läuft, könnte den Cache „primen“, und ein hoch privilegierter Prozess, der auf der CPU läuft, könnte unwissentlich Geheimnisse durch seine Speicherzugriffe preisgeben. Dann könnte der wenig privilegierte Prozess Änderungen beobachten, um geschützte Informationen zu ermitteln.
RISC-V ist eine quelloffene, modulare Befehlssatzarchitektur, die schnell an Popularität für Forschung und kommerzielle eingebettete Systeme gewinnt. Während Mikroarchitekturangriffe gut auf x86 und ARM untersucht sind, zeigt die jüngste Forschung, dass RISC-V genauso anfällig ist.
Wichtige Erkenntnis: Kein Befehlssatz oder keine offene Hardware ist immun—alle CPUs mit gemeinsamer Mikroarchitektur sind anfällig, es sei denn, sie sind speziell gehärtet.
Ein neuartiger Bereich: Stack-Engine-Angriffe (Quelle)
Wenn Angreifer und Opfer eine CPU teilen, kann der Angreifer durch gezielte Stack-Operationen und die Beobachtung der resultierenden Laufzeit herausfinden, welche Art von Stack-Aktivität das Opfer kürzlich durchgeführt hat.
Spectre und Meltdown (2018) machten der Welt verständlich, dass Mikroarchitekturangriffe mehr als Theorie sind—sie betreffen Milliarden von Computern.
[Opferprozess] [Angreiferprozess]
Führt Anweisung über Primet Cache, Zeiten Zugriffe
geheime Daten aus Dekodiert Änderungen durch Aktivität des Opfers
---[Physisch geteilter Cache]---
Prime+Probe ist ein klassischer Angriff, der wie folgt funktioniert:
Wie das Platzieren von Münzen auf allen Sitzen in einem Theater (prime), jemand anderen hereingehen lassen (Opfer) und dann prüfen, welche Sitze leer sind (probe)—dadurch wird aufgedeckt, wo das Opfer gesessen hat, ohne es direkt zu beobachten.
Neuere Angriffe zielen auf die Stack-Engine-Optimierung ab:
Es ist wichtig zu betonen: Praktische Angriffe auf Produktionssysteme sind ohne Zustimmung illegal. Allerdings können Leistungsmessungen, die Zeitkanäle sichtbar machen, auf Ihren eigenen Testmaschinen zu Forschungs- und Verteidigungszwecken durchgeführt werden.
Ein einfaches Timing-Probe, um auf Cache-Sharing (z.B. in virtuellen Maschinen) zu überprüfen.
#!/bin/bash
buffer=/tmp/testmem
size=1024000
# Großen Buffer anlegen
dd if=/dev/urandom of="$buffer" bs=1K count=1000
# Wiederholtes Zugreifen auf Speicher, um Cache zu "primen"
function prime_cache {
for i in $(seq 1 $size); do
tail -c +$i "$buffer" | head -c 1 >/dev/null
done
}
# Einen Zugriff zeitlich erfassen
function time_access {
/usr/bin/time -f "%e" dd if="$buffer" of=/dev/null bs=1K count=1000 2>&1
}
echo "Cache wird geprimet..."
prime_cache
echo "Zugriffszeit wird erfasst..."
time_access
# Nun einen anderen Prozess bitten, eine speicherintensive Arbeitslast auszuführen und wiederholen
# Vergleiche, um zu sehen, ob sich die Zeiten ändern, was auf Cache-Konkurrenz hinweist!
Deutliche Änderungen als Hinweis auf Cache-Konkurrenz mit anderen Prozessen interpretieren—was möglicherweise Prime+Probe-Angriffe ermöglicht.
Eine genauere Methode verwendet das time Modul von Python und numpy Arrays für wiederholte Speicherzugriffsmuster.
import numpy as np
import time
# Ein großes Array anlegen
arr = np.zeros((1024 * 1024 * 10,), dtype=np.uint8)
def probe_access():
ts = time.time()
# Zugriff auf alle Elemente, um Cache-Laden zu erzwingen
for i in range(0, len(arr), 64):
arr[i] += 1
te = time.time()
print(f"Zugriffszeit: {te - ts:.6f} Sekunden")
# Erster Durchlauf: sollte kalt sein (kann zu Page Fault führen)
probe_access()
# Zweiter Durchlauf: Cache wahrscheinlich heiß
probe_access()
Führen Sie nun in einem zweiten Terminal (oder separaten Prozess) ein speicherintensives Skript aus (z.B. stress-ng oder ähnliches), das Cache-Linien vertreibt. Führen Sie probe_access() erneut aus und beobachten Sie die Zeiterhöhung.
Wenn Sie größere Zugriffzeiten nach dem Ausführen eines anderen Prozesses sehen, bedeutet das, dass der Cache Ihres Systems anfällig für Timing-Angriffe ist.
Angesichts der Beharrlichkeit von Mikroarchitekturangriffen, was können Sicherheitsverteidiger tun?
# Prüfen auf flush-bezogene CPU-Features
grep . /proc/cpuinfo | grep -E 'flush|clflush|clwb'
# Könnte anzeigen: clflush, weist auf verfügbare Anweisungen für Software hin, um Caches zu leeren
Viele CPU-Hersteller führen Funktionen ein wie:
Jedoch sind die meisten eingesetzten CPUs immer noch anfällig, insbesondere in Cloud-Umgebungen oder mit komplexer Hardware.
Mikroarchitekturangriffe sind längst keine "theoretische Kuriosität" mehr. Während unsere Prozessoren immer optimierter—und mehr geteilt—werden, werden die Feinheiten ihrer internen Designs zu mächtigen Werkzeugen in den Händen geschickter Angreifer.
Vor allem in heterogenen Systemen, in denen CPUs, GPUs und Beschleuniger mikroarchitektonischen Zustand teilen, sind verdeckte und Seitenkanäle nicht nur möglich—sie sind alltäglich. Kürzliche Angriffe auf RISC-V-CPUs und die Stack-Engine zeigen die Universalität und anhaltende Relevanz dieser Risiken, selbst für neue Architekturen und Optimierungen.
Bleiben Sie auf dem Laufenden, testen Sie Ihre eigenen Umgebungen und fordern Sie bessere Isolation—sowohl in Software als auch in Hardware.
Dieser Beitrag dient nur zu Bildungszwecken. Testen Sie immer in sicheren, kontrollierten Umgebungen.
Wenn Sie diesen Inhalt wertvoll fanden, stellen Sie sich vor, was Sie mit unserem umfassenden 47-wöchigen Elite-Trainingsprogramm erreichen könnten. Schließen Sie sich über 1.200 Studenten an, die ihre Karrieren mit den Techniken der Unit 8200 transformiert haben.