Zenbleed: Wie das Streben nach CPU-Leistung Ihre Passwörter gefährden könnte

Zenbleed: Wie das Streben nach CPU-Leistung Ihre Passwörter gefährden könnte

Zenbleed: Wie das Streben nach CPU-Leistung Ihre Passwörter gefährden könnte PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.

Erinnern Sie sich an Heartbleed?

Das war der Fehler im Jahr 2014, der das Suffix einführte -bluten für Schwachstellen, die Daten aufs Geratewohl durchsickern lassen Weise, die weder der Angreifer noch das Opfer zuverlässig kontrollieren können.

Mit anderen Worten: Ein Betrüger kann einen Fehler im Blutungsstil nicht für einen Präzisionsangriff verwenden, wie zum Beispiel „Finden Sie die Shadow-Passwortdatei im.“ /etc Verzeichnis und lade es zu mir hoch“ oder „Suche rückwärts im Speicher bis zum ersten Lauf von 16 aufeinanderfolgenden ASCII-Ziffern; Das ist eine Kreditkartennummer, also bewahren Sie sie für später auf.“

In Heartbleed konnte man beispielsweise einen ungepatchten Server dazu verleiten, eine Nachricht zu senden, die maximal 16 Byte lang sein sollte, am Ende aber fälschlicherweise bis zu etwa 64,000 zusätzliche Bytes angehängt hatte.

Sie konnten sich nicht aussuchen, was sich in diesen 64,000 geplünderten Bytes befand; Sie haben gerade das bekommen, was in Ihrer Erinnerung der echten Botschaft, die Sie eigentlich erhalten sollten, am nächsten kommt.

Manchmal erhielten Sie Brocken voller Nullen oder unbekannte verschlüsselte Daten, für die Sie nicht über den Entschlüsselungsschlüssel verfügten …

…Aber hin und wieder bekam man übriggebliebene Klartextfragmente einer Webseite, die der vorherige Besucher heruntergeladen hatte, oder Teile einer E-Mail, die gerade jemand anderes gesendet hatte, oder sogar Speicherblöcke mit den eigenen privaten kryptografischen Schlüsseln des Servers.

Reichlich Nadeln in endlosen Heuhaufen

Angreifer nutzen in der Regel blutungsbasierte Fehler aus, indem sie sie immer wieder automatisch auslösen, einen riesigen Stapel nicht autorisierter Daten sammeln und ihn später nach Belieben durchsuchen.

Nadeln sind überraschend einfach aus Heuhaufen zu ziehen, wenn (a) Sie die Suche automatisieren können, indem Sie Software verwenden, die die harte Arbeit für Sie erledigt, (b) Sie nicht sofort Antworten benötigen und (c) Sie viele und viele haben Es gibt viele Heuhaufen, so dass Sie es sich leisten können, viele oder sogar die meisten Nadeln zu übersehen und am Ende trotzdem einen beträchtlichen Vorrat zu haben.

Zu den weiteren Bugs mit Blutungsnamen gehören: Gewandert, was absichtlich temporäre Speicherfehler provozierte, um zu erraten, was in benachbarten Teilen eines RAM-Chips gespeichert war, und Optionenbluten, bei dem Sie einen Webserver immer wieder fragen könnten, welche HTTP-Optionen er unterstützt, bis er Ihnen versehentlich eine Antwort mit den Daten einer anderen Person sendet.

In Analogie dazu ist ein Bleed-Style-Bug ein bisschen wie eine unauffällige Lotterie, bei der es keine garantierten Mega-Jackpot-Preise gibt, bei der man aber die Chance hat, 1,000,000 Lose zum Preis von einem zu kaufen.

Nun, der berühmte Google-Fehlerjäger Tavis Ormandy hat es gerade getan hat einen neuen Fehler gemeldet von dieser Art, die er synchronisiert hat Zenbleed, da der Fehler bei der neuesten Version von AMD auftritt Zen 2 Palette an Hochleistungsprozessoren.

Leider können Sie den Fehler von fast jedem Prozess oder Thread auf einem Computer ausnutzen und pseudozufällig Daten von fast überall im Speicher ausbluten lassen.

Beispielsweise könnte ein Programm, das als unprivilegierter Benutzer in einer virtuellen Gastmaschine (VM) ausgeführt wird, die vom Rest des Systems abgeschottet sein soll, am Ende Daten von anderen Benutzern in derselben VM oder von anderen VMs auf derselben erhalten Computer, oder vom Host-Programm, das die VMs steuern soll, oder sogar vom Kernel des Host-Betriebssystems selbst.

Ormandy konnte es erstellen Proof-of-Concept-Code, der pro Sekunde und Prozessorkern etwa 30,000 Bytes fremder Daten preisgab, jeweils 16 Bytes.

Das klingt vielleicht nicht nach viel, aber 30 KB/Sek. reichen aus, um im Laufe eines Tages satte 3 GB freizugeben, wobei möglicherweise Daten auftauchen, auf die regelmäßiger zugegriffen wird (einschließlich Passwörter, Authentifizierungstokens und andere Daten, die geheim gehalten werden sollen). wiederholt.

Und da die Daten in 16-Byte-Blöcken offengelegt werden, ist es wahrscheinlich, dass Angreifer viele erkennbare Fragmente in den erfassten Informationen finden, die ihnen helfen, die Heuhaufen zu sichten und zu sortieren und sich auf die Nadeln zu konzentrieren.

Der Preis der Leistung

Wir werden hier nicht versuchen, den Zenbleed-Fehler zu erklären (siehe Tavis Ormandys). eigener Artikel für Details), aber wir werden uns auf den Grund konzentrieren, warum der Fehler überhaupt aufgetreten ist.

Wie Sie wahrscheinlich vermutet haben, ist dieser Fehler ein Nebeneffekt der internen „Funktionen“, die moderne Prozessoren enthalten, um die Leistung so weit wie möglich zu verbessern, da wir bereits auf Prozesse, Threads, Kerne und Speicherverwaltung hingewiesen haben , einschließlich eines netten, aber fehleranfälligen Tricks, der in der Fachwelt als bekannt ist spekulative Ausführung.

Grob gesagt besteht die Idee hinter der spekulativen Ausführung darin, dass ein Prozessorkern, der andernfalls im Leerlauf wäre, möglicherweise darauf wartet, herauszufinden, ob er ausfallen soll THEN oder im ELSE Pfad einer Wenn-dann-sonst-Entscheidung in Ihrem Programm oder Warten auf eine Hardware-Zugriffskontrollprüfung, um festzustellen, ob der Datenwert, der an einer bestimmten Speicheradresse gespeichert ist, wirklich verwendet werden darf oder nicht ...

…dann lohnt es sich trotzdem, weiterzumachen und im Voraus zu rechnen (das ist der Teil „spekulative Ausführung“), für den Fall, dass sich die Antwort als nützlich erweist.

Wenn sich herausstellt, dass die spekulative Antwort unnötig ist (weil sie funktioniert hat). THEN Ergebnis, als der Code herunterging ELSE (Stattdessen den Pfad eingeben) oder für den aktuellen Prozess gesperrt wird (im Falle einer fehlgeschlagenen Zugriffsprüfung), kann er einfach verworfen werden.

Sie können sich eine spekulative Ausführung wie einen Quizshow-Moderator vorstellen, der einen Blick auf die Antwort unten auf der Karte wirft, während er die aktuelle Frage stellt, und davon ausgeht, dass der Teilnehmer versuchen wird zu antworten und er sich direkt auf die Antwort beziehen muss weg.

In einigen Quizshows kann der Teilnehmer jedoch „Bestanden“ sagen und die Frage überspringen, um später darauf zurückzukommen.

Wenn das passiert, muss der Gastgeber die ungenutzte Antwort aus seinem Gedächtnis verbannen und mit der nächsten Frage und der nächsten usw. fortfahren.

Aber wenn die „Bestanden“-Frage erneut gestellt wird, wie sehr wird sich die Tatsache, dass sie die Antwort jetzt im Voraus kennen, darauf auswirken, wie sie sie beim zweiten Mal stellen?

Was passiert, wenn sie die Frage versehentlich anders lesen oder einen anderen Tonfall verwenden, der dem Teilnehmer möglicherweise einen unbeabsichtigten Hinweis gibt?

Denn der einzig wahre Weg, etwas völlig zu „vergessen“, besteht darin, es überhaupt nicht gewusst zu haben.

Das Problem mit Vektoren

In Ormandys Zenbleed-Bug, jetzt offiziell bekannt als CVE-2023-20593Das Problem tritt auf, wenn ein AMD Zen 2-Prozessor eine spezielle Anweisung ausführt, die zum Festlegen mehrerer sogenannter vorhanden ist Vektorregister gleichzeitig auf Null.

Vektorregister werden zum Speichern von Daten verwendet, die von speziellen leistungsstarken numerischen und Datenverarbeitungsanweisungen verwendet werden, und in den meisten modernen Intel- und AMD-Prozessoren sind sie stattliche 256 Bit breit, im Gegensatz zu den 64 Bit der Allzweckregister der CPU, die für herkömmliche Programmierzwecke verwendet werden .

Diese speziellen Vektorregister können typischerweise entweder mit 256 Bits (32 Bytes) gleichzeitig oder nur mit 128 Bits (16 Bytes) gleichzeitig betrieben werden.

Tatsächlich verfügen heutige CPUs aus historischen Gründen über zwei völlig unterschiedliche Sätze von Maschinencodeanweisungen im Vektorstil: einen neueren Satz namens AVX (Erweiterte Vektorerweiterungen), die mit 128 oder 256 Bit arbeiten kann, und einer älteren, weniger leistungsstarken Befehlsgruppe namens SSE (Streaming von SIMD-Erweiterungen, wobei SIMD wiederum für steht Einzelanweisung/mehrere Daten), die jeweils nur mit 128 Bit arbeiten kann.

Ärgerlicherweise bringen die SSE-Anweisungen in der Mitte die oberen 128 Bits der neuen 256-Bit-AVX-Register durcheinander, wenn Sie einen AVX-Code im neuen Stil, dann einen SSE-Code im alten Stil und dann noch mehr AVX-Code ausführen. obwohl die SSE-Anweisungen, zumindest auf dem Papier, ihre Berechnungen nur auf den unteren 128 Bits durchführen.

Daher speichert der Prozessor stillschweigend die oberen 128 Bits der AVX-Register, bevor er in den abwärtskompatiblen SSE-Modus wechselt, und stellt diese gespeicherten Werte dann wieder her, wenn Sie das nächste Mal mit der Verwendung von AVX-Anweisungen beginnen, wodurch unerwartete Nebenwirkungen durch die Vermischung von altem und neuem Vektorcode vermieden werden .

Dieser Speicher- und Wiederherstellungsprozess beeinträchtigt jedoch die Leistung, was beides betrifft Intels und AMDs Programmierhandbücher warnen Sie dringend.

AMD sagt:

Das Mischen von SSE- und AVX-Befehlen führt zu erheblichen Nachteilen, wenn die oberen 128 Bits der [256 Bit breiten] YMM-Register Daten ungleich Null enthalten.

Ein Übergang in eine der beiden Richtungen führt dazu, dass ein Mikrofehler ausläuft oder die oberen 128 Bits aller sechzehn YMM-Register füllt.

Für die Meldung und Behebung dieses Fehlers wird eine Strafe von etwa 100 Zyklen verhängt.

Und Intel sagt etwas Ähnliches:

Die Hardware speichert den Inhalt der oberen 128 Bits der [256 Bit breiten] YMM-Register beim Übergang von AVX zu SSE und stellt diese Werte dann beim Übergang zurück wieder her.

Sowohl die Speicher- als auch die Wiederherstellungsoperation verursachen eine Strafe, die sich auf mehrere zehn Taktzyklen pro Operation beläuft.

Um die Situation zu retten, gibt es eine spezielle Vektoranweisung namens VZEROUPPER Dadurch werden die obersten 128 Bits jedes Vektorregisters auf einmal auf Null gesetzt.

Durch Anrufen VZEROUPPERSelbst wenn Ihr eigener Code dies nicht wirklich benötigt, signalisieren Sie dem Prozessor, dass Sie sich nicht mehr um die oberen 128 Bits dieser 256-Bit-Register kümmern, sodass diese nicht gespeichert werden müssen, wenn ein SSE-Befehl der alten Schule eintrifft als nächstes mit.

Dies trägt dazu bei, Ihren Code zu beschleunigen, oder verhindert zumindest, dass Sie den Code anderer verlangsamen.

Und wenn das nach einer kleinen Flickschusterei klingt …

…Nun, es ist.

Wenn Sie so wollen, handelt es sich um einen Hack auf Prozessorebene, nur um sicherzustellen, dass Sie die Leistung nicht durch den Versuch, sie zu verbessern, verringern.

Wo kommt CVE-2023-20593 ins Spiel?

All diese Fixierung auf die Leistung führte Ormandy zu seiner Zenbleed-Datenlecklücke, denn:

  • AVX-Code wird äußerst häufig für nichtmathematische Zwecke verwendet, beispielsweise für die Arbeit mit Text. Zum Beispiel die beliebte Linux-Programmierbibliothek glibc verwendet AVX-Anweisungen und -Register, um die Funktion zu beschleunigen strlen() das wird verwendet, um die Länge von Textzeichenfolgen in C zu ermitteln. strlen() Durch die Verwendung von AVX-Code können Sie 16 Bytes einer Zeichenfolge gleichzeitig durchsuchen und nach dem Nullbyte suchen, das angibt, wo sie endet, anstatt eine herkömmliche Schleife zu verwenden, die Byte für Byte prüft.)
  • AMDs Zen-2-Prozessoren machen das nicht zuverlässig rückgängig VZEROUPPER wenn ein spekulativer Ausführungscodepfad fehlschlägt. Beim „Entnullen“ der obersten 128 Bits eines 256-Vektor-Registers, weil der Prozessor falsch geraten hat und die VZEROUPPER Wenn der Vorgang umgekehrt werden muss, werden im Register manchmal 128 Bits (16 Bytes) aus dem AVX-Code einer anderen Person „wiederhergestellt“ und nicht die Daten, die zuvor tatsächlich vorhanden waren.

Im wirklichen Leben scheint es, dass Programmierer es selten verwenden VZEROUPPER auf eine Art und Weise, die behoben werden muss, sonst wäre dieser Fehler möglicherweise schon vor Jahren entdeckt worden, vielleicht sogar während der Entwicklung und Tests bei AMD selbst.

Doch durch sorgfältiges Experimentieren fand Ormandy heraus, wie man AVX-Codeschleifen erstellt, die nicht nur wiederholt die spekulative Ausführung von a auslösten VZEROUPPER Anweisung, erzwang aber auch regelmäßig ein Rollback dieser Anweisung und die AVX-Register wurden „auf Null gesetzt“.

Leider verwenden viele andere herkömmliche Programme häufig AVX-Anweisungen, auch wenn es sich nicht um die Art von Anwendungen wie Spiele, Bildwiedergabetools, Passwort-Cracker oder Kryptominer handelt, von denen man erwarten würde, dass sie Hochgeschwindigkeitscode im Vektorstil benötigen.

Ihr Betriebssystem, Ihr E-Mail-Client, Ihr Webbrowser, Ihr Webserver, Ihr Quellcode-Editor, Ihr Terminalfenster – so ziemlich jedes Programm, das Sie routinemäßig verwenden – verwendet mit ziemlicher Sicherheit einen angemessenen Anteil an AVX-Code, um die Leistung zu verbessern.

Selbst unter sehr typischen Bedingungen hatte Ormandy manchmal die geisterhaften Überreste der Daten anderer Programme in seinen eigenen AVX-Daten vermischt, die er erkennen und verfolgen konnte.

Wenn Sie schließlich wissen, was nach einem Jahr in den AVX-Registern stehen soll VZEROUPPER Wenn der Vorgang zurückgesetzt wird, ist es leicht zu erkennen, wenn die Werte in diesen Registern falsch sind.

In Ormandys eigenen Worten:

[Grundlegende] einfache Operationen wie strlen(), memcpy() und strcmp() [Textzeichenfolgenlänge ermitteln, Speicher kopieren, Textzeichenfolgen vergleichen] verwendet die Vektorregister – so können wir diese Vorgänge, die irgendwo im System stattfinden, effektiv ausspionieren!

Es spielt keine Rolle, ob sie in anderen virtuellen Maschinen, Sandboxes, Containern, Prozessen oder was auch immer passieren.

Wie bereits erwähnt: Wenn Sie über einen täglichen Pool von 3 GB unstrukturierter, pseudozufällig ausgewählter Geisterdaten pro CPU-Kern verfügen, knacken Sie möglicherweise nicht den Lotterieäquivalent eines Jackpots in Höhe von mehreren Millionen Dollar.

Aber Sie werden mit ziemlicher Sicherheit den Gegenwert von Tausenden von 1000-Dollar-Preisen gewinnen, ohne riskant in die Prozesse und Speicherseiten anderer Leute einzudringen, wie es bei herkömmlicher „RAM-Snooping“-Malware der Fall ist.

Was ist zu tun?

CVE-2023-20593 wurde verantwortungsbewusst offengelegt und AMD hat bereits eine erstellt Mikrocode-Patch um den Fehler abzumildern.

Wenn Sie über eine CPU der Zen 2-Familie verfügen und über diesen Fehler besorgt sind, wenden Sie sich an Ihren Motherboard-Anbieter, um weitere Informationen darüber zu erhalten, wie Sie relevante Korrekturen erhalten und anwenden können.

Auf Betriebssystemen mit Softwaretools, die das Optimieren der sogenannten MSRs unterstützen (modellspezifische Register) in Ihrem Prozessor, die seine Low-Level-Konfiguration steuern, gibt es ein undokumentiertes Flag (Bit 9), das Sie in einem schlecht dokumentierten Modellregister (MSR 0xC0011029) setzen können, das offenbar das Verhalten abschaltet, das den Fehler verursacht.

Auf MSR 0xC0011029 wird in der Linux-Kernel-Mailingliste verwiesen Archiv wie die DE_CFG registrieren, anscheinend die Abkürzung für Konfiguration dekodieren, und andere bekannte Bits in diesem Register werden verwendet, um andere Aspekte der spekulativen Ausführung zu regeln.

Wir gehen also davon aus DE_CFG[9], die Kurzform für „Bit 9 von MSR 0xC0011029“, entscheidet, ob Anweisungen mit komplexen Nebenwirkungen wie z. B. zulässig sind VZEROUPPER überhaupt spekulativ ausprobiert werden.

Wenn Sie dem Prozessor niemals erlauben, die Vektorregister auf Null zu setzen, es sei denn, Sie wissen bereits sicher, dass Sie diese Register nie auf Null setzen und die Änderungen rückgängig machen müssen, kann dieser Fehler natürlich nie ausgelöst werden.

Die Tatsache, dass dieser Fehler bisher nicht entdeckt wurde, lässt darauf schließen, dass es sich um eine spekulative Ausführung in der realen Welt handelt VZEROUPPER kommt nicht sehr oft vor und daher ist es unwahrscheinlich, dass dieser Hack/Fix auf niedriger Ebene spürbare Auswirkungen auf die Leistung hat.

Ormandys Artikel enthält eine Beschreibung, wie Sie das relevante MSR-Bit in Ihrem Zen 2-Prozessor unter Linux und FreeBSD neu konfigurieren.

(Du wirst sehen DE_CFG[9] beschrieben als Hühnchenstück, Fachjargon für eine Konfigurationseinstellung, die Sie aktivieren on drehen WOW! eine Funktion, vor der Sie Angst haben.)

OpenBSD, so hören wir, wird erzwingend sein DE_CFG[9] automatisch auf allen Zen 2-Prozessoren aktiviert, wodurch dieser Fehler standardmäßig unterdrückt wird, da Sicherheit wichtiger ist als Leistung; An Linux und andere BSDs, Sie können dies mit Befehlszeilentools (Root erforderlich) tun, z wrmsr und cpucontrol.

Mac Benutzer können sich entspannen, denn soweit wir wissen, verfügen alle Nicht-ARM-Macs über Intel-Chips und nicht über AMD-Chips, und Intel-Prozessoren sind bekanntermaßen nicht anfällig für diesen speziellen Fehler.

Windows Benutzer müssen möglicherweise auf inoffizielle Kernel-Treiber-Hacks zurückgreifen (vermeiden Sie diese, es sei denn, Sie wissen wirklich, was Sie tun, da das Hochfahren im Modus „Alle alten Treiber zulassen“ Sicherheitsrisiken birgt) oder den offiziellen WinDbg-Debugger installieren. Aktivieren Sie das lokale Kernel-Debugging und verwenden Sie ein WinDbg-Skript, um den relevanten MSR zu optimieren.

(Wir geben zu, dass wir keine dieser Abhilfemaßnahmen ausprobiert haben, da wir im Moment keinen AMD-basierten Computer zur Hand haben; teilen Sie uns bitte mit, wie es Ihnen geht, wenn Sie einen haben!)


Zeitstempel:

Mehr von Nackte Sicherheit