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
ch55x_firmware_extractor — Firmware-Extraktor für CH55x-Mikroprozessoren | Kitploit
Tools/GitHubGitHub/finngineering/ch55x_firmware_extractor
Embedded-System-SicherheitExploitationReverse EngineeringHardware-HackingHardware-SicherheitHardware- & IoT-SicherheitFirmware-Analyse
GitHubfinngineering/ch55x_firmware_extractor

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

ch55x_firmware_extractor

Firmware-Extraktor für CH55x-Mikroprozessoren

Repository anzeigen
12vor 8 MonatenNoch nicht geprüft

CH55x Firmware-Extraktor

Der CH55x Firmware-Extraktor wird verwendet, um Firmware aus CH55x-Integrierten Schaltkreisen auszulesen. Die Geräte bieten keine eingebaute Unterstützung, um die Firmware direkt über den Bootloader auszulesen. Es gibt jedoch eine Funktion, um den Firmware-Inhalt jeweils 8 Bytes auf einmal gegen bereitgestellte Daten zu verifizieren. Diese Funktion ist anfällig für einen Lehrbuch-Timing-Angriff und wird hier ausgenutzt, um die Firmware-Extraktion von diesen Geräten zu ermöglichen. Der Bootloader kann entweder über USB oder UART angesprochen werden. Dieser Firmware-Extraktor funktioniert nur über UART, da die höhere Latenz von USB diesen Angriff erschweren würde. Getestete Chips sind CH552 und CH554, sowie Bootloader-Version 2.4 und 2.5. Die Hardware-Lösung für den Firmware-Extraktor basiert auf einem STM32 Blue Pill, da diese leicht verfügbar, günstig sind und die erforderliche Leistung bieten.

Anatomie des Exploits

Der Bootloader wurde zuvor aus dem Gerät ausgelesen und sein Kommunikationsprotokoll wurde per Reverse Engineering rekonstruiert. Unten sind ein ungefähr korrekter Verify-Befehl und die im Bootloader verwendete Verify-Funktion aufgeführt. Es gibt einige Schutzmechanismen, die verlangen, dass die Länge ein Vielfaches von 8 ist, die Adresse an einer 8-Byte-Grenze ausgerichtet ist, die Adresse unter 0x3800 liegt und dass keine früheren Verify-Fehler aufgetreten sind. Der letzte Schutzmechanismus bedeutet, dass nach jeder fehlgeschlagenen Verifikation ein Neustart des CH55x erforderlich ist.

Wir können sehen, dass die Verifikationsfunktion sofort zurückkehrt, wenn ein Byte der Verifikation fehlschlägt. Das bedeutet, je mehr Bytes korrekt sind, desto länger dauert die Verifikationsfunktion. Dies ist das Lehrbuchbeispiel eines Timing-Angriffs, der ausgenutzt werden kann.

root@kitploit:~
unsigned char verifycmd[] = {
//  0x57, 0xab, // UART magic not included to verify function
    0xa6,       // Verify command
    5 + len,    // Constant 5 plus length of data to verify
    0,          // Unused
    addr_low,   // Low byte of address
    addr_high,  // High byte of address
    0, 0, 0,    // Unused
    0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, // Data to verify against
    checksum
}

unsigned char verify(unsignec char *cmdbuffer)
{
    static char prev_verify_error;

    unsigned char len = cmdbuffer[1]-5
    unsigned short addr = cmdbuffer[3] + cmdbuffer[4] << 8;
    if (len & 0x07 || addr & 0x07 || addr > 0x3800 || prev_verify_error) {
        return 0xfe;
    }

    for (int i=0; i < len; i++) {
        // Key can be set through bootloader, and CBYTE[] means code memory
        if(key[i & 0x07] ^ cmdbuffer[8+i] ^ CBYTE[addr+i]) {
            prev_verify_error = 1;
            return 0xf5;
        }
    }
    return 0;
}

Durch Versuch und Irrtum haben wir herausgefunden, dass jedes korrekte Byte die Ausführungszeit der Verify-Funktion um ungefähr 4,2 µs verlängert. Die vom Bootloader für die UART-Kommunikation verwendete Baudrate beträgt 57600 (egal was anderswo steht), was bedeutet, dass die Übertragung eines Bits ungefähr 17,4 µs dauert. Die Beziehung zwischen diesen beiden Zeiten ist wichtig, denn es scheint, dass die Antwort mit einem Jitter von ebenfalls ~17 µs gesendet wird. Wir versuchen also, Antworten zu unterscheiden, die sich in der Antwortzeit der Verify-Funktion um 4,2 µs unterscheiden, die sich aber aufgrund des UART-Jitters (Taktung) um bis zu 17 µs unterscheiden können. Das scheint eine schwierige Aufgabe zu sein, ist aber mit statistischen Mitteln möglich.

Wir können feststellen, ob ein Byte korrekt war oder nicht, indem wir versuchen, es mehrmals zu verifizieren und die Ergebnisse aufzuzeichnen. Sagen wir zum Beispiel, die kürzest mögliche Zeit für den Empfang einer Antwort, wenn das erste Byte falsch ist, beträgt 30 µs. Dann können wir bei einem ungültigen ersten Byte mit einem UART-Jitter eine maximale Antwortzeit von 30 µs + 17,4 µs = 47,4 µs erwarten. Gleichzeitig würde ein gültiges erstes Byte und ein ungültiges zweites Byte diesen „Bereich“ auf 34,2 µs bis 51,6 µs verschieben. Mit etwas Spielraum können wir schließen, dass das erste Byte ungültig war, falls die Antwortzeit kürzer als ~33 µs ist. Ähnlich können wir sagen, dass das erste Byte gültig war, falls die Antwortzeit höher als 48 µs ist. Dies ist die Grundlage des Timing-Angriffs, der zur Extraktion der Firmware verwendet wird.

Verwendung des Firmware-Extraktors

Dies ist kein vollautomatisches Werkzeug zur Firmware-Extraktion – eine Änderung des Quellcodes und eine Neukompilierung sind erforderlich (mit VS Code und PlatformIO). Der Hauptgrund dafür ist, dass die genauen Zeitmerkmale für jedes Byte je nach Aufbau unterschiedlich sind und angepasst werden müssen. Der Anpassungsprozess könnte automatisiert werden, aber das war nicht das Ziel dieses Projekts. Die Hauptanpassung erfolgt über die Variable prober_limits. Zum Beispiel enthält prober_limits[0] die Grenzen für Byte 0 in den 8 zu verifizierenden Bytes. Wenn die Antwortzeit unter .invalid_under_time liegt, wissen wir, dass das Byte ungültig war. Wenn sie über .valid_over_time liegt, wissen wir, dass das Byte korrekt war. Es gibt auch ein .min_delta, das es erlaubt, zum nächsten Byte überzugehen, bevor wir sicher wissen, ob das Byte korrekt ist oder nicht.

root@kitploit:~
struct ProberByteLimits prober_limits[8] = {
    {
        // Byte 0
        .invalid_under_time = 33,
        .valid_over_time = 50,
        .min_delta = 30
    }, // ...

Um die richtigen Werte zu finden, wird empfohlen, .invalid_under_time auf 0, .valid_over_time auf z.B. 100 zu setzen und .min_delta bei 30 zu belassen. Das bedeutet, dass der Prober das erste korrekte Byte nicht finden wird, aber der Fortschritt wird an den UART des Host-PCs ausgegeben. Sie werden etwas Ähnliches sehen:

root@kitploit:~
[0x0000]=0x01? min=31 max=47 tries=63
               min=31 max=48 tries=127
               min=31 max=48 tries=191
               min=30 max=48 tries=255
               min=30 max=48 tries=319

Vorausgesetzt, dass das erste getestete Byte ungültig ist, können wir diese Min/Max-Werte mit einem Offset von 1 oder 2 verwenden, um die richtigen Grenzwerte zu bestimmen. Im obigen Beispiel könnten wir .invalid_under_time auf 33 und .valid_over_time auf 50 setzen. Der Prober sollte dann verschiedene Werte ausprobieren, bis er einen gültigen findet, was wie folgt aussehen würde:

root@kitploit:~
...
[0x0000]=0x7d? min=31 max=39 tries= 7
[0x0000]=0x02? min=40 max=56 tries= 7
[0x0001]=0x01? min=35 max=52 tries=34

Wir sehen, dass der letzte Versuch an Adresse 0x0000 eine maximale Antwortzeit von 56 µs hatte, was bedeutet, dass dies das korrekte Byte war. Der Prober rückt dann zum nächsten Byte vor und setzt den Prozess fort. Beachten Sie, dass alle 8 Byte-Grenzen separat angepasst werden müssen, aber wenn das erledigt ist, funktioniert es für den gesamten Speicher. Wenn 8 korrekte Bytes gefunden wurden, wird es im ihex-Format ausgegeben:

root@kitploit:~
:0800000002002932ffffffff9f

Wenn Sie die UART-Ausgabe in eine Textdatei protokollieren, können Sie mit grep nach ^: suchen, um den vollständigen Speicherinhalt im ihex-Format zu extrahieren.

Schaltplan

Ein Beispielschaltplan für die Firmware-Extraktion ist unten dargestellt. Zwei Transistoren ermöglichen es, die Stromversorgung des CH55x vom Blue Pill aus zu unterbrechen. Dies wird gegenüber einem reinen Software-Reset empfohlen, da ein Software-Reset nur funktioniert, wenn sich der CH55x im Bootloader-Modus befindet (und der Bootloader einen Timeout hat, nach dem er den Anwendungscode startet). Die Widerstände an der UART-Leitung zum CH55x sind enthalten, weil ich den Verdacht habe, dass interne Pull-ups am CH55x Strom über UART zurückspeisen könnten, selbst wenn die Stromversorgung abgeschaltet ist. Der 10k-Widerstand zwischen V33 und P3.6 ist erforderlich, um den CH55x in den Bootloader-Modus zu versetzen. Auf dem Blue Pill ist PA11 mit dem UART-RX-Pin verbunden, um die Antwort mit Timer 1 zeitlich messen zu können.

CH55x-Firmware-Extraktor-Schaltplan

Fazit

Durch Anpassung und Verwendung dieses Tools kann die Firmware von CH55X-Geräten extrahiert werden. Der Extraktionsprozess ist nicht schnell, aber er extrahiert die 14 kb in ein oder zwei Tagen. Es hängt ein wenig von der Anpassung ab und davon, wie gut die verwendete Häufigkeitstabelle mit dem tatsächlichen Assembler-Code der Firmware übereinstimmt. Leider ist der Quellcode ein ziemliches Durcheinander. Ich habe dieses Tool erstellt, weil ich die Firmware eines CH554-Geräts benötigte, und jetzt, wo ich sie erhalten habe, gibt es keinen wirklichen Grund, weiter am Tool selbst zu arbeiten. Trotzdem sollte es sich als nützlich erweisen, falls jemand Firmware aus CH55x-Geräten extrahieren muss.

Tool herunterladen