English

Hack a Bike

Schon mal nachts ohne Transportmöglichkeit in einem fremden Bezirk aufgewacht? "Mal schnell" ein Fahrrad benötigt? In Berlin und anderen Großstädten Deutschlands bietet die Deutsche Bahn mit dem Call-A-Bike-Service Abhilfe.

Kurzeinführung in das Call-a-Bike-System

Als Kunde ruft man die CallABike-Zentrale und gibt per DTMF-Wahl die vierstellige Radnummer durch. Von der Zentrale erhält man dann den vierstelligen Code, mit dem man das CallABike-Fahrad öffnen kann. Zur Sicherheit wird man nach dem Anruf von der Zentrale zurückgerufen. Die letzten vier Ziffern des Rückrufes enthalten nochmal den Code - annehmen muss man den Anruf deswegen nicht.

Jetzt läuft die Uhr und der Kunde muss pro Minute 6 Cent bezahlen (mit Bahncard nur 4 Cent). Wenn der Kunde das CallABike einfach mal schnell abstellen will (z.B. für einen kurzen Einkauf), kann man das CallABike abschließen und im Display auf ‘Nicht Abgeben’ tippen. Es ist sozusagen kurz geparkt. Danach kann man das CallABike mit dem gleichen Code wie beim ersten Mal öffnen. Das kann man so oft wiederholen, wie man möchte. Die Zeit, die man bezahlen muss, läuft natürlich weiter.

Wenn der Kunde das CallABike dann endgültig abgeben will, muss er beim Schließen auf ‘Abgeben’ tippen; das CallABike gibt einem dann den Rückgabecode. Mit diesem Code kann man gegenüber der Zentrale ‘beweisen’, dass man das CallABike wirklich wieder abgeschlossen hat. Man ruft jetzt einfach wieder die Zentrale an und gibt den Rückgabecode durch. Danach muss man noch die Straßenecke auf Band sprechen, an der man das CallABike abgestellt hat. Die Mietzeit wird damit dann auch beendet. Es ist auch möglich, zwei Räder mit einem Anruf auszuleihen oder abzugeben. Wenn der Kunde in seiner Nähe kein CallABike-Rad findet, kann er auch die Zentrale anrufen und fragen, wo das nächste CallABike- Rad steht. Ein Servicemitarbeiter der Bahn schaut dann in der Datenbank nach und gibt den Standort des nächstgelegenen CallABike-Rads durch.
Offizielle CallABike Webseite

Kurzer Auszug eines Interviews mit einem Call A Bike Techniker im Magazin Mobil der Deutschen Bahn:

..."Es gibt natürlich auch andere Zeitgenossen, die haben, schon aus sportiven Gründen, allerlei versucht, um die Standfestigkeit der Hardware oder das elektronische Prinzip der eingebauten Mikrochips und Prozessoren zu ergründen. Sie rückten dem Schloss mit Schraubenziehern und gängigen Imbusschlüsseln zu Leibe. Sie versuchten ihr Glück mit Brechstange, Vorschlaghammer, sogar mit der Motorflex. Oder, ganz Smart, mit Laptop, mit Dechiffrierprogrammen, auch mit Fangfragen an das Wartungspersonal. Doch vergebens! Wieder lächelt Reth, der einst erste Ausflüge auf einem grünen Puky-Rad unternahm, sich heutzutage aber als “postmoderner Urbaniker”, denn als “Fahrradfreak” versteht. Er lächelt und sagt: “Erst diese Technik macht uns zum weltweit einzigen stationsunabhängigen Stadtradsystem. Der Code ist nicht zu knacken und darauf sind wir richtig stolz."...

Artikel:

Im November 2003 wurde uns ein CallABike ‘zugetragen’, das nicht richtig abgeschlossen wurde. Dieses musste erstmal als Testobjekt herhalten. Die meisten dachten, dass in dem Schlosskasten GPS oder sonstiger Funk enthalten sei, nach dem öffnen war hiervon jedoch nix zu sehen. Um die Schrauben der Schlosskästen zu öffnen, benötigt man nur ein Torx TR (Tamper Resistant). In dem Kasten ohne Display ist die Stromversorgung durch Batterien sichergestellt (3x 1.5V Mono). Die beiden Kästen sind durch eine Art Bügel miteinander verbunden. In diesem Bügel befindet sich ein sechspoliges Kabel für den Strom und zwei Spulen. Damit kann geprüft werden, ob das Schloss wirklich geschlossen ist, oder einfach kein oder nur irgendein anderer Bolzen zum Verschließen genommen wurde.

Der Kasten mit dem Display enthält den Exzentermotor zum öffnen des Schlosses, zwei Taster (Mikroschalter) und ein kapazitives 5x2-Touchpad. Die Hauptlogik sitzt unter dem Display. Sie ist nochmal durch eine Metallplatte abgesichert, welche nur die Kabel zum Display/Touchpad durchlässt. Damit wird der Motor und der Verschlussmechanismus vor einer Attacke durchs Display geschützt.

Die gesamte Platine ist mit schwarzem Silikon übergossen, das man erstmal runterkratzen muss. Das geht prima mit einer Mess-Spitze. Außer einer streichholzschachtelgroßen Platine (Rückseite Datenschleuder 82), auf der ein Atmel AT90S8535 (8-Bit-Risc-Prozessor, 4x8-IO-Pins, 8KB Flash, 512-Bytes-EEProm und 512-Bytes-RAM) [1], ein paar LEDs (rot, grün und IR) und IR-Receiver aufgebracht sind, enthält der Kasten noch ein paar andere elektrische Bauteile (Motor, Schalter und ein Beeper). Es ist auch ein Neigungssensor vorhanden, aber im Code wird er nicht benutzt. Daher bestand keine Gefahr, uns zu orten. Es wurden ein paar Bilder von der Aktion gemacht, aber dann lag die Technik erstmal zwei Monate einsam in einer Kiste, weil wir es nicht geschafft haben, das CallABike zu booten. Es dauerte eine Weile, bis wir merkten, dass das System nach dem Booten durch ein Infrarot-Signal aktiviert werden muss. Das war mehr oder weniger Zufall.

Wenn man eine normale Glühlampe benutzt, um besser sehen zu können, piepte die Elektronik gelegentlich scheinbar unmotiviert. Wie sich später herausstellte, reichte der durch die Glühlampe emittierte IR-Anteil aus, um den IR-Receiver zu triggern und den Bootvorgang fortzusetzen. Beim Booten testet sich das System selbst, und der Empfang eines Infrarot-Signals gehört eben dazu. Im Zuge fortschreitender Professionalisierung™ wurde in der Folgezeit die Glühlampe durch ein Infrarot-Photon-Micro-Light ersetzt. Bei unserer weiteren Analyse des Systems begannen wir damit, alle Anschlüsse des Atmel durchzumessen, um uns einen ungefähren Schaltplan zu erstellen (siehe Bild). Die Datenblätter für den Atmel und das verwendete Display haben wir uns aus dem Web besorgt.

Im Januar hatte einer der Beteiligten dann endlich eine Idee, wie weiter vorzugehen sei. Auf der Platine war uns eine unbenutzte 6-polige Steckerleiste aufgefallen, und wie sich herausstellte, handelt es sich dabei um den ISP-Connector (In System Programming) des Atmel. Daran schlossen wir dann ein Atmel-Developer-Board STK500 an. Zum Auslesen wurde hauptsächlich das freie UISP (“Uisp is a tool for AVR microcontrollers which can interface to many hardware in-system programmers”) benutzt. Die auf dem Atmel vorhandenen „Intellectual-Property“-Bits waren in einem undefinierten Zustand, deswegen konnten wir das Flash des Atmels mit der acht KB großen Firmware auslesen.

In den nächsten Wochen waren mehrere Hacker damit beschäftigt, den ausgelesenen Assemblercode zu verstehen und zu dokumentieren. Dazu verwendeten wir AVR-Studio und Ida Pro. Den Scramble Code (zum Berechnen der Ausleih- und Abgabecodes) fanden wir relativ schnell, da sich dort eine Menge rotate-und-shift-Befehle befanden. Den Initialisierungscode erkannten wir wieder, da wir wußten, daß sich der Motor beim Einschalten zweimal herumdreht. So konnten wir das Gelernte immer wieder an unserem Prototyp auf Richtigkeit überprüfen.

Die Ausleih- und Abgabecodes werden durch einen Scrambler generiert, der mit einem 16-Bit-Counter des Call-a-Bikes und einem Zustandswert aufgerufen wird. Ein gerader Counterwert erzeugt Ausleihcodes und ein ungerader erzeugt die Abgabecodes. Der Scrambler nutzt den Counter und das Zustandsbyte, um ein Offset auf ein 1024 Bit großes Feld zu errechnen. Dieses Feld ist ein für jedes Call-a-Bike eindeutiger binärer String, der als der (wahrscheinlich) eindeutige Key des Call-a-Bikes bezeichnet werden könnte. Von diesem Offset aus werden dann 4x4 Bit genutzt, welche die vier Ziffern für die Ausleih- und Abgabecodes repräsentieren. Die 16 Bit des Counters werden aber schlecht genutzt, denn schon nach 1024 Iterationen wiederholen sich die Ausleih- und Abgabecodes. Das bedeutet auch, daß es nur 512 Ausleihcodes je Call-a-Bike gibt, da es nur 512 gerade Offsets gibt, die auf den Key (1024 Bit) zeigen können. Call-a-Bikes, die wir geöffnet haben und die wir wegen der Lockbits nicht auslesen konnten, haben wir mit einem Script 511 mal resetten lassen (bei einem Reset erhöht sich der Counter immer um zwei). Damit haben wir den ursprünglichen Zustand wiederhergestellt, und das Call-a-Bike war wieder ‘in sync’ mit der Zentrale.

Wer sich das Display mal genauer angeschaut hat, wird festgestellt haben, daß der Zeichensatz ein proportionaler ist. Dazu gibt es im Code eine Tabelle, in der die Länge des Zeichens und die Position im Flash gespeichert sind. Ein ‘i’ und ein ‘!’ belegen nur ein Byte, wogegen z. B. ein ‘w’ sieben Bytes belegt. Die großen Logos und das Zahleneingabefeld liegen als 400 Byte große Bitmaps vor. Die lange schwarze Linie im Call-a-Bike-Logo zeigt die Stärke der Spule im Schloß an. Das haben wir nur durch das Code-Auditing herausgefunden.

Unser erstes Ziel war es, den aus unserem Disassembler erhaltenen Sourcecode so anzupassen, dass nach dem Assemblieren mit dem Commandline Tool Avra (“Assembler for the Atmel AVR microcontrollers”) ein EXAKT identisches Binary herauskam. Auf der Grundlage dieses Referenzcodes konnten wir dann endlich änderungen vornehmen.

Nachdem wir uns diese Grundlage geschaffen hatten, konnten wir das CallABike mit unserem eigenen Code flashen. Da wir keine Vulnerabilities oder Backdoors fanden (jedes CallABike hat einen eigenen Key, der im EEPROM gespeichert ist), mit denen man ein CallABike exploiten könnte, ohne es aufzuschrauben, kamen wir auf die Idee, uns eine eigene Backdoor in den Code zu programmieren. Hört sich eigentlich ganz leicht an, ist es aber nicht. Erstmal mussten wir den Code der BAHN optimieren, um uns den entsprechenden Platz zu schaffen. Schließlich sollte ja auch noch ein Logo mit 400 Bytes von uns in das 8KB große Flash. Den Datenmüll, den man über unserem HackABike Logo sehen kann, ist der Backdoor Code. Das sparte nochmal ca. 150 Bytes. Außerdem wollten wir nicht, dass man mit dem Backdoor Code normalen Kunden, die das Rad nur geparkt (verschlossen, aber nicht abgegeben) haben, das ausgeliehene HackABike wegschnappen konnte. Das erforderte noch ein paar Zeilen mehr im Code. Auch kann man mit unserem Backdoor Code das HackABike nicht ‘parken’, da ja der öffner nichts bezahlen muss und deswegen nicht motiviert ist, sich weiter um das Rad zu kümmern, und es aber auch niemand anders aufmachen könnte. Um das HackABike auch auf größere Entfernung noch von seinen unbehandelten Verwandten unterscheiden zu können, haben wir ihm eine leicht veränderte Blink-Sequenz beigebracht.

Im Verlauf der weiteren Analyse des Codes ist uns aufgefallen, dass das CallABike im Abgabecode integriert Statusinformationen an die Zentrale durchgeben kann. Je nachdem, in welchem technischen Zustand sich das CallABike befindet, kann es unterschiedliche Rückgabecodes - abhängig vom bereits erwähnten Zustandsbyte - angeben. Das CallABike kann z.B. melden, dass die Batterie nicht mehr lange hält, oder der Motor für das Schloss nicht mehr in der richtigen Stellung ist. Wenn man z.B. den Schließknopf sieben mal ohne eingeführten Bolzen drückt, liefert der Scrambler einen entsprechenden Rückgabecode, der gültig ist, diesen Zustand aber für die Zentrale erkennbar anzeigt. Von diesen Codes gibt es 52 (eine Matrix aus 4x13).

Die Backdoor erlaubt, das HackABike mit einem von uns festgelegten Ausleihcode einfach zu öffnen. Wenn man das HackABike dann wieder abgibt, ist es ganz normal wieder ausleihbar. Es steht auch wieder der Ausleihcode des vorherigen Kunden im Display. Die Zentrale merkt von diesem eingeschobenen Ausleihvorgang nichts - außer, dass es an einem anderem Ort steht, als es in der Datenbank vermerkt ist. Wenn es dann aber wieder normal ausgeliehen und abgestellt wird, ist auch in der Zentrale alles wieder in Ordnung.

Um ein CallABike in ein HackABike zu verwandeln, mussten wir sechs Schrauben auf der Innenseite des Schlosskastens mit dem Display öffnen und das Kabel des STK500 an den ISP-Anschluss der Platine stecken. Danach haben wir ein Script gestartet, dass das Flash und den EEPROM Bereich ausliest. Das EEPROM wird danach mit zurückgesetztem Counter und dem Flash mit unserer Backdoor wieder zurückgeschrieben. Damit niemand unsere Backdoor auslesen kann, haben wir natürlich noch die Lockbits gesetzt. Ein geschulter Hacker brauchte ca. 12 Minuten, um zwei CallABikes parallel in HackABikes zu verwandeln. Insgesamt wurden knappe 10% der in Berlin verteilten CallABikes in ein HackABike umgebaut indem ihnen eine neue firmware verpasst wurde. Da UISP das Setzen der Lockbits nicht korrekt unterstützte, mussten wir das erstmal einbauen. Dazu haben wir den Output von AVR-Studio mit einem serial sniffer mitgelesen und uns die entsprechenden Kommandos für das STK500 rausgesucht und in UISP eingebaut.

Abschließend ist festzustellen, dass das technische Design des CallABike in unseren Augen sehr gut ist. Jedes CallABike hat vermutlich einen eigenen 1024 Bit Key, der benötigt wird, um die Abgabe- und Ausleihcodes berechnen zu können. Dazu muss vermutlich das CallABike geöffnet und ausgelesen werden. Es wurde nur versäumt, die Lockbits zu setzen, um die Firmware vor dem Auslesen zu schützen. Unsere Attacke ist von den verbrauchten Mannstunden wohl mehr Wert als ein paar Dutzend CallABikes.

 

EEPROM Content:

0x0000 - 0x0001 unused
0x0002          lock_sensor_calibration
0x0003 - 0x0019 unused
0x001A - 0x001B 16bit counter (scrambler)
0x001C          unused
0x001D - 0x001F CallABike Number
0x0020 - 0x009F 128 Byte Random (Key)
0x00A0 - 0x00A2 first three bytes of key again
0x00A3 - 0x00AF unused
0x00B0 - 0x01FF textmessages for display

bikecounter: 0x015E
EEPROM belongs to bike 3856

Counter 0x0162:  3042 9843 5360      <-- rentcode

-00- -01- -02- -03- -04- -05- -06- -07- -08- -09- -10- -11- -12- -13-
00: 8584 7572 6970 4597 9119 4285 2144 0277 3197 0072 5545 6487 6341 9664
01: 5244 2345 5463 6065 9493 2971 9352 5402 5519 4579 8355 9533 9245 4926
10: 6615 7508 8159 7355 8125 3632 2920 4348 0484 7784 0084 6154 8905 6742
11: 6234 7953 4741 7386 8181 2930 6280 8658 6805 5432 4092 7161 2070 8554

Counter 0x0164:  7240 7043 9766      <-- rentcode

-00- -01- -02- -03- -04- -05- -06- -07- -08- -09- -10- -11- -12- -13-
00: 1542 5463 4821 7206 8181 5293 5100 8370 7662 7831 6561 1071 9350 7554
01: 8480 7640 5094 4420 7470 5025 6472 0596 9260 5499 4274 0341 7092 7363
10: 6369 3545 6991 9042 0121 7702 7931 5600 6755 8264 9063 9596 6918 8761
11: 4254 0960 8294 7529 9793 4954 5455 9345 0183 3995 4992 5949 4392 9538

//Here you see the open and close pins of the bike 3856 with
the counter at 0x0162
At first the Customer gets the open pin 3042. When the customer
closes the lock and everything is ok he gets the return code 8584.
When for example the battery (-01-) is exhausted he gets the return code
7572.

//The following commands are possible via infrared:
0x5B read bikenumber
0xCE calibrate coil
0xC5 read RAM from 0x00AD

//after transmit of the first 32 bytes of the key
0xCA enable watchdog (reboot)
0xC8 write and read the key of the EEPROM
0xCD write and read other parts of the EEPROM

//Code zum Generieren der Abgabe/Ausleihcodes bei gegebenem Key aus dem eeprom

unsigned char g_key[4];

void scrambler(uchar param, long counter)
{
     long bitoffset;
     uchar r21 = param, r28 = 1;
     short r27_26 = counter, short r31_30;
     r28 <<= r27_26 & 7;
     r27_26 += r21;
     r27_26 &= 0x3ff;
     r31_30 = r27_26;
     r27_26 <<= 5;
     r27_26 -= r31_30;
     r27_26 &= 0x3ff;
     r27_26 += r28;
     r27_26 &= 0x3ff;
     bitoffset = r27_26 & 7;
     r27_26 >>= 3;
     r27_26 += 0x20;
     r27_26 &= 0xff;
     fillkey(r27_26,bitoffset);
}

void fillkey(long address, long bitoffset)
{
     uchar r16;
     long fullkey;
     fullkey = eeprom[address++] << 16;
     fullkey += eeprom[address++] << 8;
     fullkey += eeprom[address++];
     fullkey >>= bitoffset;
     r16 = fullkey          & 0xf;
     if(r16 >= 10) r16 -= 10;
     g_key[3] = r16;
     r16 = (fullkey >> 4 ) & 0xf;
     if(r16 >= 10) r16 -= 6;
     g_key[2] = r16;
     r16 = (fullkey >> 8 ) & 0xf;
     if(r16 >= 10) r16 -= 10;
     g_key[1] = r16;
     r16 = (fullkey >> 12) & 0xf;
     if(r16 >= 10) r16 -= 6;
     g_key[0] = r16;
}

//Fürs CallABike mit der Nummer 2883 z.B.:
unsigned char eeprom[ ] =
{
    0x5A,0xD5,0xAD,0x6B,0xFD,0xD7,0x34,0x78,
    0xB3,0x03,0x22,0x13,0x61,0x23,0xAD,0xFE,
    0x51,0x6E,0xAA,0xA2,0xD4,0xB7,0xBA,0xC0,
    0x78,0x9A,0x84,0x55,0x2A,0xB9,0x6E,0xBC,
    0x33,0x15,0x2C,0x97,0x33,0x98,0x4B,0x78,
    0x43,0xE5,0x20,0xD5,0x1C,0x1C,0x75,0x12,
    0x2A,0x91,0x17,0xFC,0x0C,0x61,0x31,0x31,
    0x50,0x6D,0xFD,0x5C,0xC5,0x60,0x8D,0xE0,
    0x0A,0xF2,0x85,0xF1,0x3B,0xA3,0xBD,0x74,
    0xF3,0xD4,0x9E,0xBB,0x45,0x95,0x69,0x24,
    0x79,0x36,0x9A,0xA6,0x66,0x96,0xFB,0xE8,
    0x5D,0x38,0x34,0x28,0xC0,0x51,0x3B,0x18,
    0x46,0xCA,0xD9,0xE3,0xD7,0xC8,0x86,0x01,
    0x11,0x60,0xF2,0xF0,0xA4,0xA4,0xEF,0x16,
    0x3E,0xBE,0xB9,0x1F,0xA8,0xF9,0x61,0x0B,
    0xD6,0x7F,0x75,0xE7,0xF4,0x31,0x3F,0x6B
};