Firmware-Update durchs Schlüsselloch

Posted by mic on Thursday, June 14, 2018

Gestern haben wir uns daran begeben, zwei neue Router in Betrieb zu nehmen und standen vor einer Blockade. Aus der Ferne konnten wir nur per serieller Konsole auf die Geräte zugreifen, weil der Netzwerkanschluss noch nicht funktionierte. Dafür sollte zuerst ein Firmware-Update eingespielt werden. Doch wie soll das klappen, wenn man keine Dateien auf das Gerät herunterladen kann? Ohne eine funktionierende Netzwerkverbindung?

Es bleibt eine einzige Möglichkeit. Könnt ihr es erraten? Schließlich können wir ja Befehle eingeben und die Ausgaben lesen per Konsole. Kann man da nicht irgendwie die Datei quasi aus der Zwischenablage hinein kopieren? Ja, das geht!

Um Dateien per Konsole zu übertragen, muss man nur beachten, dass diese natürlich nur ASCII-Zeichen ohne weitere Interpretation überträgt. Jeder, der schon einmal cat ohne weiteres auf eine Binärdatei ausgeführt hat, kennt das Problem mit der zerschossenen Shell, die durch Interpretation von Bitmustern als Steuerzeichen in einen undefinierbaren Zustand gebracht wurde.

Dafür gibt es seit Urzeiten ein Verfahren: Mit uuencode lassen sich beliebige Binärdaten als Shell-sichere ASCII-Zeichen verpacken. Das Pendant dazu heißt uudecode und wandelt den Zeichensalat zuverlässig wieder in die ursprünglichen Binärdaten zurück.

Nun haben wir also uns auf dem Konsolen-Server per SSH eingeloggt und von dort aus weiter auf den seriellen Port des Routers. Um die Annahme der Datei vorzubereiten, muss die Shell dafür annahmebereit gemacht werden. Das geht recht simpel so:

uudecode > /tmp/foo

Alles, was nun hier eingegeben wird dekodiert und landet in der Zieldatei, bis das Steuerzeichen End-of-File kommt. Das können wir manuell mit CTRL+D in die Shell eingeben, worauf hin diese die Datei schließt und zum Prompt (zur Eingabeaufforderung) zurückkehrt.

Bevor wir das tun, möchten wir natürlich die Datei in die Konsole kippen. Das machen wir von unserem Arbeitsrechner aus über den Konsolenserver. In unserem Fall ist der Router an einem USB-Port angeschlossen.

uuencode firmware.tar /dev/stdout | ssh admin@console "cat > /dev/ttyUSB0"

Nun strömen die Daten sichtbar auf den Router hinein. Drückt jetzt bloß keine Taste in der noch offenen Shell, sonst geht die Datei kaputt weil zusätzliche Bits hinein geschrieben werden!

Da die serielle Konsole lange nicht so schnell ist wie ein Gigabit-Netzwerk, haben wir für die läppischen 85 MB der Firmware-Datei fast 4 Stunden gebraucht. Das erinnert an alte Zeiten, als wir noch Modems an unsere Telefonleitung angeschlossen haben und den Bildern beim Laden zugucken mussten.

Aber es hat geklappt. Das Upgrade konnte vom Router als valide erkannt und eingespielt werden. Nun steht dem Einrichten des Netzwerks nichts mehr im Wege.