
Von UART zu Root: Einbruch in die Xiaomi C200 über U-Boot
In diesem Repository zeige ich, wie ich Zugang zur UART-Schnittstelle erhalten habe, selbst ohne die üblichen freiliegenden Pins/Testpads. Dabei nutze ich U-Boot und Tricks, um frühzeitig Root-Zugriff zu erlangen und schließlich die Firmware zu dumpen.
Einige wichtige Dinge sind auf der Platine erkennbar:
Zuerst suchte ich nach den offensichtlichen Kandidaten für einen direkten UART-Zugriff – es gibt 4 Testpads in einer Reihe, die Tx, Rx, Ground und Strom zu sein scheinen. Beim Testen mit einem Multimeter ergaben sich jedoch falsche Messwerte, wie auf dem Bild zu sehen. Ich probierte die meisten anderen Testpads aus und konnte dennoch keine korrekte Messung finden, also musste ich die Strategie wechseln.
Da auf der Platine keine Anschlüsse mehr vorhanden waren und auch keine Testpads halfen, entschied ich mich, über die Quelle zu gehen – die Prozessor-Pins anzuschließen und so eine UART-Shell zu erhalten. Ich zog das Datenblatt für diesen Prozessor heran und identifizierte die Pins des UART-Protokolls.

Jetzt musste ich nur noch Ground auf der Platine finden und Folgendes verbinden:
Für diesen Aufbau verwendete ich einige PCBite-Sonden und einen USB-2-TTL-Adapter.

Jetzt können wir mit picocom die gewünschte UART-Shell erhalten:
sudo picocom -b 115200 /dev/ttyUSB0
Wenn nichts unternommen wird, erhalte ich nur die Boot-Logs und nach dem Bootvorgang keine Shell. Also musste ich U-Boot durch sofortiges Drücken der Eingabetaste unterbrechen.
Als ich eine U-Boot-Shell hatte, habe ich zuerst die Umgebungsargumente ausgedruckt.
Die für uns wichtigen Dinge sind:
bootargs – zeigt den init-Befehl (Ausführen der linuxrc-Binärdatei) und das Firmware-Layout (Partitionen und deren Zweck/Größe/Slots)bootcmd – der Befehl zum Laden des Speichers vom Flash in den RAM und zum Booten des GerätsUm schnell Root-Zugriff zu erhalten, kann ich den Trick anwenden, den init-Befehl mit setenv zu ändern, sodass ich eine Shell erhalte, anstatt die linuxrc-Binärdatei auszuführen. Dann kann ich den Speicher manuell laden und das Gerät booten (im Wesentlichen den bootcmd-Befehl kopieren).
Wenn der Bootvorgang abgeschlossen ist, werde ich in eine frühe Shell geworfen, auf der praktisch nichts läuft. Also führe ich die ursprüngliche linuxrc-Binärdatei im Hintergrund aus und überprüfe, ob auf diesem System offene Ports vorhanden sind.
Kein Glück! Die Kamera kommuniziert nur mit ihrer Cloud unter „47.237.75.249« – es gibt keine freigelegte Weboberfläche zum Herumexperimentieren.
Da das Reverse Engineering der Cloud-Kommunikations-Binärdatei außerhalb des Rahmens meiner Forschung liegt, habe ich hier beschlossen, meine Forschung zu beenden :)
Eine kleine Zugabe für alle, die Interesse daran haben, mit der Firmware zu spielen – hier ist, wie man sie bekommt.
Der gleiche Aufbau wie zuvor mit dem UART, aber dieses Mal wird nur der Speicher vom Flash in den RAM sondiert und geladen, ohne hineinzubooten. Dann kann man die Daten aus dem RAM-Speicher ausgeben und die Terminalausgabe aufzeichnen (dieses Mal mit minicom), um sie in einer Datei zu speichern, mit Python ein wenig zu bereinigen und die Firmware zu erhalten. Der Abgleich mit binwalk und bootargs hilft, jeden Abschnitt zu benennen.
