Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2024-42642 | Kitploit
Tools/GitHubGitHub/vl4dr/cve-2024-42642
Embedded-System-SicherheitSchwachstellenanalyseExploitationReverse EngineeringHardware-HackingHardware-SicherheitBinäranalyseFirmware-Analyse
GitHubvl4dr/cve-2024-42642

CVE-2024-42642

Repository anzeigen
141vor 1 JahrNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2024-42642

Einleitung

Das betreffende Gerät ist jede SSD der MX500-Serie. Diese SSDs werden von einem Sillicon-Motion SM2259-Controller gesteuert (ältere Chargen hatten einen älteren Controller, Sillicon-Motion SM2258, aber der Hauptfokus dieses Dokuments liegt auf dem neueren). SM2259 ist ein 4-Kanal SATA 6 Gb/s Mikrocontroller mit einer 32-Bit Little-Endian CPU basierend auf der ARC-Architektur. Durch Beobachtung der aktuellsten Firmware zum Datum dieses Dokuments, nämlich M3CR046, wurden einige Probleme identifiziert und sowohl statisch als auch dynamisch bestätigt. Alle Probleme wurden im Firmware-Update-Mechanismus des Controllers identifiziert, der dem Mikrocontroller-Handler des ATA PIO DOWNLOAD-MICROCODE (0x92)-Befehls entspricht, insbesondere in der Logik, die die Firmware mittels der Offset-Methode herunterlädt, was den Unterbefehlen 0x03 und 0x0E entspricht. Alle in diesem Dokument behandelten Fehler wurden auf einer Crucial MX500 500 GB SSD (CT500MX500SSD1), SM2259H-AC-Controller mit M3CR046-FW und NY112-Flash-Chips, unter Verwendung eines PCs mit einer x86_64-CPU verifiziert.

Der FW-Code ist auf die Basisadresse 0x80020000 abgebildet, und der anfällige ATA-Handler befindet sich an Adresse 0x80024A9C. Eine dekompilierte Version der Funktion finden Sie unter resources/download_microcode_handler.c.

Für diejenigen, die sich lieber nicht mit den technischen Details befassen und stattdessen die Quintessenz verstehen möchten, verweise ich auf den FAQ-Abschnitt weiter unten.

Da M3CR046 mehrere Firmware-Images enthält, von denen das passende durch den Firmware-Update-Mechanismus ausgewählt wird (vielleicht abhängig von den tatsächlich verwendeten Flash-Chips oder anderen Hardwareeigenschaften), werden in diesem Dokument die Besonderheiten der ersten Firmware-Variante behandelt (da dies die Firmware ist, die auf unserem spezifischen Laufwerk unterstützt wird, und wir daher nur diese Firmware-Variante testen konnten). Die in diesem Dokument vorgestellten Fehler scheinen jedoch auf alle Firmware-Varianten zuzutreffen, aber bei der Reproduktion kann es zu einigen Unterschieden in den tatsächlichen Details kommen.

Fehler #1

Dieses Problem betrifft Fälle, in denen der erste gesendete Block größer als 0x200 Sektoren ist. Wenn wir einen Blick in den ATA-Befehlshandler werfen, insbesondere auf die Logik, die ausgeführt wird, wenn die Blockgröße größer als die Sektorgröße ist und der Block der erste gesendete ist:

Bildinfo

Dies setzt einige Variablen basierend auf dem nächsten Offset (der in unserem Fall, da wir bisher nur einen Block gesendet haben, der Länge des Blocks in Sektoren entspricht) und einer Variablen namens lower_bound_fw_offset, dem Block-Offset (d.h. Offset in Sektorgranularität) innerhalb des eingehenden Download-Images, an dem unser Firmware-Image erwartet wird. Dies ist ein hartcodierter Wert pro Firmware-Variante, der in unserem Fall (der ersten Variante) gleich 0 ist. In diesem Fall kommt es beim Berechnen des Subtraktionsergebnisses für some_index zu einem Unterlauf, wodurch some_index bis zu 0xFFFF beträgt. Dies ist ein unerwartetes Verhalten, da basierend auf der Logik, die die Daten in den Download-Puffer verschiebt:

Bildinfo

Beobachten wir, dass die Quelladresse, von der die Daten kopiert werden, angesichts des unerwarteten Werts für some_index möglicherweise nicht gültig ist. Beim dynamischen Testen durch Senden einer Firmware-Update-Anfrage mit dem ersten Block größer als 0x200 Sektoren, hängt der Controller und sendet nicht einmal eine Antwort auf die ursprüngliche Anfrage. Dies ist konsistent und leicht reproduzierbar. Es ist wahrscheinlich, dass dies auf einen ungültigen Verweis auf die berechnete Quelladresse zurückzuführen ist, der dann eine Ausnahme auslöst, die zum Hängen des Controllers führt. Dies wurde nicht bewiesen, sondern ist eher eine Vermutung, die das Hängen erklären könnte.

Fehler #2

Das eingehende Download-Image (für M3CR046) hat eine Größe von 0x242400 Bytes, und in diesem Image befinden sich 3 interne Firmware-Images, von denen nur eines nach einem Firmware-Update-Prozess in den Flash geschrieben wird. Jedes dieser Images hat eine Größe von 0xC0C00 Bytes (oder 0x606 Sektoren). Das bedeutet, dass der Firmware-Update-Mechanismus beim Extrahieren der korrekten Firmware-Kopie aus dem eingehenden Download-Image überprüfen muss, dass ihre Größe 0xC0C00 Bytes nicht überschreitet. Der Controller versucht dies auch, aber es gibt einige Randfälle, die zu unerwartetem Verhalten führen können. Betrachten wir das folgende Snippet (das einen Teil des Codes mit dem vorherigen Fehler gemeinsam hat):

Bildinfo

Wenn der aktuelle Block größer als 0x200 Sektoren ist und es nicht der erste Block in der Sequenz ist, werden 0x200 Sektoren (0x40000 Bytes) auf einmal kopiert. Dann gibt es eine Prüfung, deren Zweck es ist, die überschüssigen Bytes von der Anzahl der zu kopierenden Bytes abzuschneiden, wenn die Gesamtgröße des Firmware-Images higher_bound_fw_offset überschreitet (was in unserem Fall 0x606 Sektoren entspricht, da die Firmware-Größe genau dies sein sollte). Diese Logik ergibt insgesamt Sinn, hat aber einen Fehler – wenn der letzte gesendete Block dazu führt, dass der nächste Offset zu hoch wird, so dass die überschüssige Anzahl von Bytes 0x200 Sektoren (oder 0x40000 Bytes) überschreitet, erhält curr_bytes_to_copy einen „negativen“ Wert, der auf etwa ~4GB (~0xFFFFFFFF) unterläuft. Wie zuvor gesehen, wird diese Variable verwendet, um die Anzahl der in den Download-Puffer zu übertragenden Bytes zu bestimmen. Wenn wir einen Blick in r_maybe_some_efficient_data_transfer werfen, sehen wir das folgende Code-Stück:

Bildinfo

Das bedeutet, dass die Kopiergröße auf 32MB begrenzt wird (von der ursprünglichen ~4GB Kopiergröße), aber das ist immer noch eine große Zahl, die auch zu einem undefinierten Verhalten führen kann, wenn der Speicherbereich ab 0x40000000 kleiner als 32MB ist. Beim dynamischen Testen durch Senden von ATA-Blöcken, um einen Offset von 0x600 zu erreichen, und dann Senden eines großen Blocks der Größe 0x207 Sektoren, um den Unterlauf auszulösen, hängt der Controller erneut, wahrscheinlich aufgrund eines ungültigen Speicherzugriffs während des Kopiervorgangs. Dieser Fehler ist interessanter als der vorherige, denn obwohl wir keinen kontrollierten Überschreibvorgang haben (sondern einen großen Überschreibvorgang, der möglicherweise eine Ausnahme auslöst, die den Controller hängen lässt), könnte die Funktion, die die Daten in den Download-Puffer verschiebt, tatsächlich so viele Daten übertragen, bevor sie abstürzt (wobei der Speicherbereich überschrieben wird, der sich direkt nach dem Download-Puffer im Hauptspeicher befindet), dann könnte das Verhalten des Ausnahme-Handlers möglicherweise basierend auf den überschriebenen Daten verändert werden. Dies könnte möglicherweise passieren, wenn beispielsweise der Ausnahme-Handler einen Zeiger aus dem überschriebenen Bereich liest und dann dorthin springt (dieser spezifische Fall ist nicht besonders wahrscheinlich, aber mit etwas mehr Forschung könnte so etwas entdeckt werden).

Fehler #3

Wie bereits erwähnt, hat das Download-Image eine Größe von 0x242400 (oder 0x1212 Sektoren). Die Firmware überprüft, dass die Gesamtgröße des übertragenen Images diese Größe nicht überschreitet, indem sie überprüft, dass der nächste Offset nicht größer als 0x1212 Sektoren ist. Diese Prüfung ist sinnvoll, aber die Berechnung des nächsten Offsets ist fehlerhaft:

Bildinfo

Wenn der aktuelle Offset 0x600 Sektoren beträgt und der nächste zu verarbeitende ATA-Befehl groß genug ist (sagen wir 0xFC00 Sektoren, was vom ATA-Standard erlaubt ist), dann läuft der nächste Offset über, sodass die zuvor erwähnte Prüfung nicht richtig funktioniert:

Bildinfo

Oder mit anderen Worten, im Normalfall würde der Firmware-Update-Mechanismus seine Zustandsmaschine zurücksetzen und einen Fehler zurückgeben, aber wenn wir einen sehr großen Block senden, würden wir ihn weiterverarbeiten. Das folgende Code-Snippet zeigt, wie die Übertragung durchgeführt wird:

Bildinfo

An dieser Stelle erinnern wir uns: Wenn die Anzahl der zu übertragenden Sektoren größer als 0x200 Sektoren ist und der aktuelle Block nicht der erste ist, werden 0x200 Sektoren auf einmal in den Download-Puffer kopiert. Dies ist sehr interessant, denn das bedeutet, dass wir etwa 0x200 Sektoren (oder 0x40000 Bytes) über den Download-Puffer hinaus kopieren können, wodurch Daten im Hauptspeicher überschrieben werden. Wenn beispielsweise der aktuelle Offset 0x605 Sektoren beträgt und wir eine Blockgröße von 0xF9FB Sektoren liefern, erhält __next_offset aufgrund des Überlaufs den Wert 0. Der Quellindex, von dem aus der Kopiervorgang beginnt, ist 0, und curr_bytes_to_copy erhält den Wert 0x40000. Da wir uns derzeit bei Offset 0x605 Sektoren befinden, erhält g_blocks_copied den Wert 0x605. Da der aktuelle Offset gültig ist (und der nächste auch), wird der Kopiervorgang in den Download-Puffer ausgelöst, was zu einem massiven Überschreiben von knapp unter Bytes über das Ende des Download-Puffers hinaus führt. Dies ist ein starkes Primitiv, das einen viel kontrollierteren Controller-Pufferüberlauf ermöglicht (der den Controller nicht sofort zum Abstürzen bringt wie in den vorherigen Fällen) und mit viel höherer Sicherheit zu Codeausführung führen kann als der vorherige Fehler (allerdings muss noch mehr Forschung betrieben werden, um genau zu bestimmen, was nach dem Download-Puffer im Hauptspeicher platziert ist, um die Ausnutzungseigenschaften zu ermitteln).

Fehlerreproduktion und Kommentare

Alle diese Fehler wurden auf einem Ubuntu 22.04 64-Bit-Rechner mit dem standardmäßigen Linux-SCSI-Treiber über die SG_IO-Schnittstelle verifiziert. Es sollte darauf hingewiesen werden, dass zur Reproduktion von Fehler #3 mit diesem spezifischen Treiber „Huge Pages“ aktiviert und eine einzelne 1-GB-Seite für die große Anfrage allokiert werden muss. Der Grund dafür ist, dass dieser Treiber anscheinend die gesamte ATA-Anfrage in zusammenhängenden physischen Speicherblöcken erfordert. Da die Anfrage eine Größe von nahezu ~30MB hat, reichen 2MB-Seiten nicht aus, und daher sind 1GB-Seiten die nächste (und letzte) verfügbare Größe auf unserem Testsystem. Es sollte jedoch auch beachtet werden, dass dies nicht bedeutet, dass dies ein notwendiger Schritt zur Auslösung ist, da möglicherweise andere Workarounds existieren, die das Senden großer ATA-Anfragen ermöglichen, die wir noch nicht abgedeckt haben. Die Aktivierung von Huge Pages war einfach der schnellste Weg, um diesen Fehler zu bestätigen. Abgesehen davon ist die einzige Voraussetzung zur Auslösung aller dieser Fehler die erforderlichen Berechtigungen zum Senden von ATA-Paketen (typischerweise Root-Zugriff auf den PC, der mit dem Controller kommuniziert).

Der Quellcode, der alle oben genannten Fehler reproduziert, ist Teil dieses Repositorys. Für Fehler #1 und Fehler #2 ist das erwartete Verhalten, dass das Laufwerk bis zum nächsten Einschalten hängt. Für Fehler #3 lässt der bereitgestellte Quellcode den Controller nicht unbedingt abstürzen, führt aber einen großen Überschreibvorgang über den Download-Puffer hinaus durch.

Kompilieren und Ausführen

Wie bereits erwähnt, da die Fehler auf einem Ubuntu 22.04 64-Bit-Rechner verifiziert wurden, muss der Kompilierungsprozess auf einem ähnlichen Rechner durchgeführt werden. Es gibt keine Garantien für andere Distributionen oder Betriebssysteme.

Um zu bauen, führen Sie Folgendes im Stammverzeichnis des Projekts aus:

root@kitploit:~
cmake -B build && make

Der Build-Prozess erstellt 3 Binärdateien, die alle im build-Verzeichnis mit den Namen CVE_MX500_BUG_1, CVE_MX500_BUG_2 und CVE_MX500_BUG_3 verfügbar sein werden, die den Quelldateien entsprechen, die Fehler #1, Fehler #2 bzw. Fehler #3 auslösen.

Jede Binärdatei erwartet den Gerätepfad der MX500 SSD und muss mit Root-Rechten ausgeführt werden. Zum Beispiel:

root@kitploit:~
sudo ./build/CVE_MX500_BUG1 /dev/sda

FAQ

Wenn Administrator-/Root-Rechte erforderlich sind, warum sollte man sich dann überhaupt mit den hier genannten Schwachstellen befassen? Hat man dann nicht ohnehin die volle Kontrolle über das Laufwerk?

Das hängt vom Endziel eines potenziellen Angreifers ab. Wenn dieser nur vollen Lese-/Schreibzugriff auf den Speicher Ihres Laufwerks haben möchte, reicht es aus, sich in Ihrem PC zu befinden. Was aber, wenn dieser Angreifer noch einen Schritt weiter gehen möchte? Wenn die FW eines Laufwerks digital signiert ist, kann Fehler #3 es einem Angreifer ermöglichen, die Signaturüberprüfung der Firmware zu umgehen, sodass der Angreifer eine schädliche Nutzlast in die Firmware des Laufwerks einschleusen kann. Einmal im Inneren, ist eine solche Nutzlast sehr gut versteckt, überlebt Laufwerksformatierungen und kann sogar sicherstellen, dass sie Firmware-Updates des Controllers überlebt. Was eine solche Nutzlast tatsächlich tun könnte, geht über den Rahmen dieses Dokuments hinaus und wird daher nicht diskutiert.

Das klingt ernst! Sollte ich mir darüber Sorgen machen?

Wahrscheinlich ist die Antwort ein klares NEIN. Der Forschungs- und Entwicklungsaufwand, der für einen solchen Angriff nötig ist, ist sehr hoch und wäre (SEHR WAHRSCHEINLICH) nur sehr ernsthaften Bedrohungsakteuren möglich. Es ist äußerst unwahrscheinlich, dass Sie davon betroffen sein werden, es sei denn, Sie sind von Regierungen gesucht.

Warum haben Sie die Details dieser CVE veröffentlicht, bevor der Anbieter einen Patch dafür veröffentlicht hat?

Der Anbieter hat über mehrere Monate hinweg nicht auf mehrere E-Mails zu diesen Problemen geantwortet. Damit eine CVE tatsächlich veröffentlicht werden kann, muss der zuweisenden CNA ein öffentlicher Link bereitgestellt werden. Leider funktioniert das Übermitteln der Informationen auf privatem Wege so nicht.

Können Sie den Offenlegungszeitplan teilen?

Die in diesem Dokument genannten Fehler wurden ursprünglich im Mai 2024 entdeckt. Micron wurde seitdem mehrfach (über die offizielle Sicherheits-E-Mail) kontaktiert, und es gab keine Antwort von ihnen. MITRE wurde im Juli 2024 benachrichtigt, und eine CVE wurde im August 2024 zugewiesen. Ende August 2024 wurde dieses Repository öffentlich gemacht (einige Tage nachdem die CVE von MITRE genehmigt wurde).

Sind ältere Versionen betroffen?

Da M3CR04X-Firmwares älter als M3CR046 nicht mehr zum Download verfügbar sind, ist unklar, ob sie betroffen sind, aber wenn ich raten müsste, würde ich sagen ja. Was noch ältere Versionen betrifft, zum Beispiel M3CR033, dann scheint es basierend auf der statischen Analyse, dass dort sehr ähnliche Fehler existieren.

Was ist mit anderen Anbietern?

Der betreffende Controller, SM2259, ist auch in SSDs anderer Anbieter verbaut. Es ist möglich, dass Anbieter einen Teil des Firmware-Codes modifizieren, aber ich würde auch sagen, dass es definitiv möglich ist, dass diese Fehler (oder sehr ähnliche) auch in SSDs anderer Anbieter vorhanden sind.

Offenlegung

Diese CVE wurde von MITRE veröffentlicht. Sie wurde auch von NVD mit einem CVSS 3.0 Score von 6.7 (mittel) analysiert.

Abschließende Anmerkungen

Wenn Sie Ungenauigkeiten oder Fehler in der Beschreibung festgestellt haben oder Probleme haben, diese Fehler zu reproduzieren, kontaktieren Sie mich bitte unter log1kxd at gmail.com.

Tool herunterladen
0x40000