Sonntag, 12. Februar 2012 |
Von der Webanwendung gelieferte Werte wie Session-Tokens und Passwörter sollten zufällig gewählt werden und nicht vorhersagbar sein. Manchmal sieht das aber nur so aus. Diese Folge von About Security dreht sich daher um die Analyse solcher Werte.
Im folgenden wird immer von Session-Tokens oder kürzer Tokens ausgegangen, die entsprechenden Schritte gelten aber analog für die Analyse von von der Webanwendung erzeugten Passwörtern, die z.B. nach der Registrierung oder von der Passwort-Recovery-Funktion verschickt werden. Auch anderen von der Webanwendung verwendeten, auf den ersten Blick zufällig aussehenden Werten kommt man so evtl. auf die Schliche.
Session-Tokens, die nicht zufällig erzeugt wurden, sondern für die Webanwendung eine Bedeutung haben, enthalten i.A. mit dem Benutzer assoziierte Daten wie den Benutzernamen, eine Benutzer-ID, die E-Mail-Adresse, ..., die, evtl. mit weiteren Daten verbunden, kodiert oder getarnt werden, um nicht sofort erkannt zu werden. Zum Beispiel könnte das Token nach dem Muster
Benutzername;Status;AktuellesDatum
gebildet werden. Für den Administrator Max Mustermann, dessen
Benutzername maxmus ist, ergibt das dann für den 4.
März 2010 das Token
maxmus;admin;04.03.2010
Den Aufbau dieses Tokens erkennt man auf den ersten Blick. Aber wie sieht es mit folgendem Token aus:
6D61786D75733B61646D696E3B30342E30332E32303130
Das muss doch ein Zufallswert sein, oder? OK, natürlich ist es keiner, sonst wäre es ein schlechtes Beispiel. Aber was ist es dann? Vielleicht irgend eine raffinierte Verschlüsselung? Wenn man sich die verwendeten Zeichen anguckt, fällt auf, dass nur hexadezimale Zeichen vorkommen. Versuchen wird doch mal unser Glück und werfen das Token einem Hexadezimal-ASCII-Decoder vor. Der liefert
maxmus;admin;04.03.2010
Das war einfach, richtig? Und wie sieht es mit folgenden Werten aus:
6Q61786Q75733O61646Q696R3O30342R30332R32303130
und
7A6E6B7A68663B6E717A76613B30342E30332E32303130
Viel Spaß bei der Analyse! Die Lösung gibt es in About Security #246.
Im Prinzip kann ein Token alles enthalten, auch wirklich nur Zufallszahlen. Token, die eine Bedeutung haben, enthalten aber meist einen oder mehrere der folgenden Werte:
Jede Komponente eines strukturierten Tokens kann auf eine andere Weise kodiert sein. Nicht nur, um den Wert zu tarnen, sondern auch, um ihn im Fall binärer Daten oder Sonderzeichen überhaupt sicher über HTTP übertragen zu können. Die Zeichen können also z.B. mit Base64 oder Hexadezimal kodiert oder zur Tarnung XOR mit einem festen Wert verknüpft sein, und das womöglich sogar noch in verschiedenen Kombinationen.
Die Webanwendung wertet nicht zwingend immer das gesamte Token aus, je nach
Funktion werden evtl. nur Teile davon dekodiert und verwendet. Im ersten
Beispiel könnte z.B. nur der Benutzername wirklich verwendet werden,
der Status ist ja auch auf dem Webserver gespeichert, und das Datum ist
vielleicht sogar nur ein Füllwert, um das Token länger zu machen
und damit eine gar nicht vorhandene Komplexität vorzutäuschen.
In dem Fall würde es reichen, die Zeichen bis zum ersten
; auszutauschen, um die Identität eines anderen Benutzers
anzunehmen.
Als erster Schritt wird ein vorhandenes Token systematisch modifiziert, um fest zu stellen, ob es vollständig oder nur teilweise ausgewertet wird. Dazu wird das Token byteweise (evtl. auch bitweise) geändert und an die Webanwendung geschickt. Wird es weiterhin akzeptiert, dürfte das geänderte Byte (Bit) zumindest für die aktuelle Aktion bedeutungslos sein. Werden Teile des Tokens nicht verwendet, brauchen sie in den folgenden Schritten nicht mehr beachtet zu werden.
Als zweiter Schritt werden Token zur Analyse gesammelt. Dazu meldet man sich zu verschiedenen Zeiten und wenn möglich mit verschiedenen Benutzernamen an und speichert die gelieferten Token. Können die Benutzer sich selbst bei der Webanwendung registrieren und den Benutzernamen dabei frei wählen, wird eine Reihe von Benutzerkonten mit ähnlichen Benutzernamen angelegt, z.B. AAAA, AAAB, AAAC, ... . Ebenso wird für weitere bei der Registrierung abgefragte Daten wie z.B. den Namen oder der E-Mail-Adresse vorgegangen. Danach heißt es wieder: Fleißíg anmelden und Token sammeln.
Im dritten Schritt werden erkennbare Zusammenhänge zwischen den Benutzerkonten mit den angegebenen Daten und den Token gesucht. Tauchen Muster aus den Eingaben auch im Token auf? Gibt es Zusammenhänge zwischen der Länge der Eingaben und dem Token?
Als vierter Schritt geht es ans Dekodieren. Es kann nie schaden, ein Token einfach mal komplett verschiedenen Dekodierfunktionen (Hexadezimal, Base64, Rot13) vorzuwerfen und einen Blick aufs Ergebnis zu werden. Evtl. sieht das ganze ja dann schon viel einfacher aus. Ansonsten muss man systematisch nach Auffälligkeiten suchen. Enthält z.B. der Benutzername eine Reihe gleicher Zeichen, wird im Token nach einer Reihe gleicher Zeichen gesucht - vielleicht wurde ja der Benutzername zeichenweise XOR mit einem festen Zeichen verknüpft.
Wurden in den ersten vier Schritten irgend welche Informationen über die Token gesammelt, aus denen auf die Token anderer Benutzer geschlossen werden kann, wird im fünften Schritt ein Token so präpariert, dass damit die Session eines anderen Benutzer übernommen werden kann. Das Token muss an einer Seite der Webanwendung getestet werden, die eindeutig verrät, ob die Session gültig ist, z.B. indem sie bei einer ungültigen Session eine Fehlermeldung ausgibt oder den Benutzer auf z.B. die Startseite weiterleitet. Ggf. ist eine größere Anzahl präparierter Token notwendig, bis man mit einem davon Erfolg hat. Das ganze lässt sich recht einfach automatisieren, entweder mit einem selbst geschriebenem Skript oder z.B. mit dem Burp Intruder.
In der nächsten Woche gibt es einen Bericht über interessante Neuigkeiten von der CeBIT, in der nächsten regulären Folge geht es dann um die Analyse (mehr oder weniger) zufällig erzeugter Tokens.
Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!