Hardwaresicherheit, Part 2: Inception, Downfall, div0, Collide+Power


Veröffentlicht am 23. August 2023 von Dominik Pataky

Neue Woche, neue Bugs. Auch heute geht es erneut um Hardware-Bugs, die sich letztlich zu Security-Issues ausweiten. Zenbleed, bekannt geworden im Juli 2023, haben wir bereits im Post “Zenbleed - Hardwaresicherheit in geteilten Infrastrukturen” kennengelernt. Heute schauen wir auf vier weitere Bugs: Inception, Downfall, div0 und Collide+Power.

NameWebsiteCVECPUsCVSS
Zenbleedlock.cmpxchg8b.comCVE-2023-20593AMD Zen 25.5
Inceptioncomsec.ethz.chCVE-2023-20569alle AMD Zen7.5
Downfalldownfall.pageCVE-2022-40982Intel Core Skylake (6th) bis Tiger Lake (11th), Xeon 1st bis 4th6.5
div0git.kernel.org-AMD Zen 1-
Collide+Powercollidepower.comCVE-2023-20583alle Intel, AMD, ARM4.7

tl;dr: Zusammenfassend kann man sagen, dass die meisten dieser Angriffe durch Patches (Microcode-Updates) und der Verwendung von dedizierten CPU-Kernen entgegengewirkt werden kann. Gerade zweiteres ist im Zusammenhang mit Cloud-Systemen sehr zu empfehlen. Sicherheitsmaßnahmen für Hardwaresicherheit sollten in jeder Security-Abteilung bewusst aufgegriffen und implementiert werden. Denn leider ist kein Ende in Sicht, neue Anfälligkeiten überschreiben bisherige Security-Patches und -Mitigations.

Inception (AMD Zen)

Die Beschreibung des CVEs fasst den Impact von Inception relativ gut zusammen:

A side channel vulnerability on some of the AMD CPUs may allow an attacker to influence the return address prediction. This may result in speculative execution at an attacker-controlled address, potentially leading to information disclosure.

Für Inception kommen wir, wie bei Zenbleed, wieder zum Thema speculative execution und branch prediction. Der Angriff nutzt zwei Angriffsmethoden, um einen Abfluss von Daten zu ermöglichen:

  • Phantom speculation (CVE-2022-23825): Triggern einer misprediction, ohne dass tatsächlich ein Branch zu Grunde liegen muss.
  • Training in Transient Execution (TTE): Triggern von zukünftigen mispredictions durch eine vergangene, ebenfalls aktiv getriggerte, misprediction. TE-Attacken ermöglichen das Ausführen von Code im Kontext eines Zielprogramms.

Mit „Kontext des Zielprogramms“ ist an dieser Stelle der Kernel gemeint, denn Inception zielt ab auf die Manipulation des Programmablaufs des Kernels, nachdem ein Userspace-Programm diesen aufgerufen hat.

Der Begriff transient execution bezieht sich hierbei auf Berechnungen, die auf Grund von predictions berechnet, aber dann verworfen werden. Entsprechend ist das transient window der Zeitrahmen, in welchem die zu-verwerfenden Berechnungen/Daten existieren, d. h. noch kein revert einer misprediction durchgeführt wurde.

Transient execution CPU vulnerabilities are vulnerabilities in a computer system in which a speculative execution optimization implemented in a microprocessor is exploited to leak secret data to an unauthorized party. (Wikipedia)

TTE expands the attack surface of transient control-flow hijacks by using the kernel and in some instances even the CPU as confused deputies for manipulating the BTB (Branch Target Buffer) and RSB (Return Stack Buffer). (Paper, abbr. expanded)

Besondere Erkenntnis ist auch, dass Inception auf Phantom und TTE aufbaut und alle bisher für diese Schwachstellen eingesetzten Gegenmaßnahmen aushebeln kann.

Inception plants an “idea” in the CPU while it is in a sense “dreaming”, to make it take wrong actions based on supposedly self conceived experiences. Using this approach, Inception hijacks the transient control-flow of return instructions on all AMD Zen CPUs. (Website)

In essence, the CPU trains the RSB autonomously with a non-existent control flow. (Paper)

Die Idee hinter Inception ist letztlich die Umsetzung eines Exploits, der den TTE-Angriffsvektor nutzt für die Erstellung eines „infinite transient loop“. Dieser trainiert den return stack buffer so, dass in diesem eine vom Angriffsprogramm kontrollierte Adresse eingetragen wird. Das Ergebnis ist dann, dass ein unprivilegiertes Programm durch Phantom und TTE die CPU so manipuliert, dass diese, beim Wechsel in den sensiblen Kernel-Kontext, Code des Angriffsprogramms ausführt (eine Rücksprungadresse auf Angriffscode setzt). Damit wird die security boundary durchbrochen und Programmcode mit höheren Privilegien wird getäuscht, eine gefälschte Return-Adresse zu verwenden.

Inception leaks arbitrary kernel memory at a rate of 39 bytes/s on AMD Zen 4 despite all mitigations against transient control-flow hijacks, including the recent Automatic IBRS. […] Constructing Inception by creating nested PhantomCalls to pollute the RSB recursively. Inception leaks /etc/shadow on fully patched AMD Zen 4 systems in 40 minutes, in 6 out of 10 trials.

“Inception makes the CPU believe that a XOR instruction is a recursive call instruction which overflows the return stack buffer with an attacker-controlled target,” the researchers explained. (thehackernews.com)

Im Paper werden auch eine Reihe von Mitigations besprochen, so u.a.

  • Synchronization: Explizite Serialisierung von Instruktionen, um den Einsatz von transient execution (d. h. parallele Vorberechnung) zu reduzieren. Reduziert die Anfälligkeit für Angriffe auf TE.
  • Address Space Isolation (ASI): Größer angelegte Bestrebung, secrets aus dem Kernel-Space rauszuhalten. Stößt aber natürlich an Grenzen, da die Daten irgendwie verarbeitet werden müssen.
  • Avoid transient training: Wenn von einem fortlaufenden Training hin zu einem gezielteren Training an gewissen Zeitpunkten („If branch predictors were only updated at retirement“) gewechselt wird, könnten TTE-Angriffe gänzlich ausgeschaltet werden.
  • Isolating the branch predictor state: Der State der branch prediction sollte beim Übergang in den Kernel-Kontext entweder ignoriert oder sogar gänzlich verworfen („flushing“) werden. Damit wäre die Verwendung eines manipulierten States nicht mehr möglich

In der Kernel-Dokumentation wird Inception als „speculative return stack overflow (SRSO)“ beschrieben:

This is a mitigation for the speculative return stack overflow (SRSO) vulnerability found on AMD processors. The mechanism is by now the well known scenario of poisoning CPU functional units - the Branch Target Buffer (BTB) and Return Address Predictor (RAP) in this case - and then tricking the elevated privilege domain (the kernel) into leaking sensitive data. AMD CPUs predict RET instructions using a Return Address Predictor (aka Return Address Stack/Return Stack Buffer). In some cases, a non-architectural CALL instruction (i.e., an instruction predicted to be a CALL but is not actually a CALL) can create an entry in the RAP which may be used to predict the target of a subsequent RET instruction. The specific circumstances that lead to this varies by microarchitecture but the concern is that an attacker can mis-train the CPU BTB to predict non-architectural CALL instructions in kernel space and use this to control the speculative target of a subsequent kernel RET, potentially leading to information disclosure via a speculative side-channel.

Fazit: Da wir erneut über CPU-interne Speicher und States sprechen, wird auch Inception durch den Einsatz von dedizierten CPU-Kernen wesentlich abgeschwächt. Mit Hilfe der zur Verfügung gestellten Test-Tools kann die eigene Anfälligkeit geprüft werden. Darüber hinaus kann ggf. auch bei der Programmierung bereits darauf geachtet werden, ob Gegenmaßnahmen in Software implementiert werden können. Microcode-Updates sollten eingespielt und geprüft werden, auch wenn die Performance darunter leiden wird.

Referenzen:

Downfall (Intel)

Auch Intel bleibt leider nicht verschont von Bugs in ihren Prozessoren. Downfall nutzt, ähnlich wie Inception, den Kontext der speculative execution für Angriffe auf vertrauliche Daten:

The vulnerability is caused by memory optimization features in Intel processors that unintentionally reveal internal hardware registers to software. This allows untrusted software to access data stored by other programs, which should not normally be accessible. I discovered that the Gather instruction, meant to speed up accessing scattered data in memory, leaks the content of the internal vector register file during speculative execution. To exploit this vulnerability, I introduced Gather Data Sampling (GDS) and Gather Value Injection (GVI) techniques.

Moghimi geht in Downfall aber noch weiter und eröffnet einen gänzlich neuen Angriffsvektor: die gather-Instruction. Mit Hilfe eines entsprechenden Exploits hat er es geschafft, sensible Daten wie kryptographische Keys und beliebige weitere Speicherinhalte von anderen Programmen auszulesen. Dies betrifft insbesondere die Inhalte aus Vektor-Registern, die über AVX angesteuert werden. Analog zu Zenbleed sind hierbei so triviale Funktionen wie strlen() und memcpy() anfällig.

Intel beschreibt das Problem wie folgt:

Gather Data Sampling (GDS) is a transient execution side channel vulnerability […]. In some situations when a gather instruction performs certain loads from memory, it may be possible for a malicious attacker to use this type of instruction to infer stale data from previously used vector registers. Similar to data sampling transient execution attacks like Microarchitectural Data Sampling (MDS), GDS may allow a malicious actor who can locally execute code on a system to infer the values of secret data which is otherwise protected by architectural mechanisms.

Zwei neue Angriffsmethoden werden also in Downfall demonstriert:

  1. Gather Data Sampling (GDS): Hier wird die gather instruction verwendet, um fremde Daten aus den SIMD register buffers zu lesen, die vor allem von AVX-Instruktionen (Vektor-basierte, parallele Berechnungen) mit Daten befüllt werden.
  2. Gather Value Injection (GVI): Kombination aus GDS mit dem bereits existierenden “Load Value Injection”-Angriff (lviattack.eu, Jan. 2020)

Das zugehörige Paper enthält eine ganze Reihe von neuen Angriffsmethoden und technischen Details, ist sehr zu empfehlen und deckt mehrere Themen ab:

  1. Gather Data Sampling (GDS)
  2. Cross-Process Covert Channel: Vergleich von GDS über mehrere CPU-Generationen hinweg hinsichtlich Performance
  3. Stealing Cryptographic Keys: cross-VM-Angriff um Kryptodaten zu stehlen (Beispiel OpenSSL AES-Keys)
  4. Stealing Arbitrary Data: Hier werden Daten aus den Registern gelesen, die von der CPU prefetched wurden, aber gar nicht aktiv vom Zielprogramm verwendet werden (Moghimi nennt es „data-at-rest“)
  5. Gather Value Injection (GVI)
  6. Breaking Intel SGX
  7. Mitigations: “Disabling SMT”, “Disallowing affected instructions”, “Disabling gather” und “Preventing transient forwarding”.

Da wir uns hier Intel-Prozessoren anschauen, ist auch der Hinweis auf Intel SGX wichtig zu beachten:

In addition to normal isolation boundaries e.g., virtual machines, processes, user-kernel isolation, Intel SGX is also affected. Intel SGX is a hardware security feature available on Intel CPUs to protect users’ data against all form of malicious software.

Sollte also in Cloud-Infrastrukturen Intel SGX im Einsatz sein, sollte hier genauer hingeschaut werden. Da SGX für gewöhnlich bei besonders sensiblen Programmen verwendet wird, sind Security-Bugs hier nochmals heikler.

Zusammengefasst lassen sich mit Downfall also wieder einmal sensible Daten fremder Prozesse auslesen, nur dass hier spezifisch auf Vektor-Register gezielt wird. Wie schon bei Zenbleed, ist auch Downfall über VM-Grenzen hinweg ausnutzbar – sofern die VMs sich einen physischen CPU-Kern teilen.

Referenzen:

div0 (AMD Zen 1)

Mehr oder weniger zufällig durch einen Commit von Borislav Petkov für den Linux-Kernel bekannt geworden, ist ein weiterer Bug in AMD-Prozessoren der Zen 1-Familie:

x86/CPU/AMD: Do not leak quotient data after a division by 0. Under certain circumstances, an integer division by 0 which faults, can leave stale quotient data from a previous division operation on Zen 1 microarchitectures. Do a dummy division 0/1 before returning from the #DE exception handler in order to avoid any leaks of potentially sensitive data.

Im Kern beschreibt der Kernel-Patch, dass in AMD Zen 1 eine Nulldivision dazu führen kann, dass Restbestände von Daten in der CPU verbleiben könnten. Diese können sensible Daten beinhalten.

Der erste Fix war das Auslösen einer Dummy-Division beim Auftreten eines faults nach einer Nulldivision. Diese Dummy-Operation löscht dann ggf. vorhandene Daten, bevor der Kernel die nächste Division auf die CPU schedulen würde.

Allerdings stellte sich dieser Patch als unzureichend heraus:

Initially, it was thought that doing an innocuous division in the #DE handler would take care to prevent any leaking of old data from the divider but by the time the fault is raised, the speculation has already advanced too far and such data could already have been used by younger operations.

Die Dummy-Division kam wohl zu spät, um das Auslesen von Überresten rechtzeitig zu verhindern.

Therefore, do the innocuous division on every exit to userspace so that userspace doesn’t see any potentially old data from integer divisions in kernel space. Do the same before VMRUN too, to protect host data from leaking into the guest too.

Der zweite Fix überarbeitete dementsprechend das Vorgehen. Um übrig gebliebene Daten aus einer Nulldivision zu löschen, wird die Dummy-Division nicht mehr im fault-handler, sondern bei den Übergängen zu Userspace- sowie zu VM-Prozessen ausgelöst. Dies geschieht unabhängig vom tatsächlichen Auftreten eines division faults.

Referenzen:

Collide+Power (alle CPUs)

Collide+Power beschreibt einen Side-Channel-Attack auf alle modernen CPUs. In diesem werden mit Hilfe von Differential Power Analysis (DPA) Daten von fremden Prozessen aus der geteilten CPU ausgelesen.

The root of the problem is that shared CPU components, like the internal memory system, combine attacker data and data from any other application, resulting in a combined leakage signal in the power consumption. Thus, knowing its own data, the attacker can determine the exact data values used in other applications. We present two attacks belonging to the Collide+Power attack family: The first attack breaks the isolation between CPU hyperthreads, leaking arbitrary data across programs. The second attack breaks the isolation between user programs and the operating system, leaking arbitrary data not just from the operating system but any security domain on the same computer.

Der Collide-Teil des Angriffs besteht daraus, dass beispielsweise der CPU-Cache mit eigenen Daten gefüllt wird und dann das Zielprogramm eigene Daten in dieselben Caches hineinschreibt. Beim „Umschreiben“ der Daten kollidieren diese mit den Bits des Angriffsprogramms in den Speichern, heißt, 010101 müsste bspw. zu 111100 umgeschrieben werden.

Nach Füllen der Speicher kommt dann Power zum Einsatz: Das Angreiferprogramm misst die Stromdifferenz beim Umschreiben der Daten. Der Trick ist, dass für die Umwandlung der Bits 010101 in 010101 kein Strom, hingehen von 010101 in z. B. 111100 wesentlich mehr Strom benötigt wird. Diese Differenz lässt sich über entsprechende Software-Interfaces auslesen:

These attacks can be conducted in software with any signal related to power consumption, e.g., power consumption interfaces or throttling-induced timing variations.

Der Angriff ist nur sehr langsam durchführbar, jedoch erfolgreich. Relevant sind hierbei auch die Angriffe aus PLATYPUS und Hertzbleed. Laut den Autoren ist vor allem die Kombination der Angriffsmethoden ausschlaggebend für einen größeren Security-Impact.

Auch hier zeigt sich wieder, dass der Angriffsvektor die geteilte Verwendung von CPU-Kernen ist. Eine Gegenmaßnahme ist dementsprechend, für sensible Applikationen dedizierte Kerne zu nutzen.

Referenzen:

💡
Der Artikel ist mit Stand 23. August 2023 vollständig veröffentlicht, wird auf Grund der Komplexität des Themas zukünftig noch weiter nachgeschärft und verbessert. Bei Feedback gerne schreiben an pataky@mindful-security.eu

Weitere Referenzen

Das Thema Security-Bugs in Hardware, insbesondere in CPUs, wird leider größer und größer. Zur besseren Einordnung in bereits bestehende Probleme und mehr Kontext, hier noch ein paar empfohlene Referenzen: