Großer Hoster verliert 45 Mio. Nutzerdaten von tausend Foren

Große zentrale Dienste-Anbieter führen letztlich auch zu großen Problemen. Das zeigt sich nun auch am Beispiel eines großen Anbieters von Foren zu diversen Themenbereichen. Diesem ist quasi seine gesamte Nutzerdatenbank abhanden gekommen. mehr... Hacker, Tastatur, Maus Bildquelle: Davide Restivo / Flickr Hacker, Tastatur, Maus Hacker, Tastatur, Maus Davide Restivo / Flickr

Diese Nachricht vollständig anzeigen.

Jetzt einen Kommentar schreiben
 
Weil ich das immer wieder in Artikeln lese. Verschlüsseln und Hashen sind nicht das selbe. Verschlüsselte Daten lassen sich auch wieder entschlüsseln. Hashes sind eine Einbahnstraße.

Wie funktioniert das also? (kurz überrissen am Beispiel gesalzener Passwörter.

Man legt sein Passwort fest. Nennen wir es mal 12345.

Der Server fügt das Salz hinzu (welches dort vor Zugriff geschützt sein sollte), z.B. so:

HalloWelt12345HalloWelt

Von diesem Gebilde wird nun ein Hash errechnet und auf der Datenbank abgelegt.

Meldet man sich nun an, findet genau die gleiche Prozedur auf dem Server statt, mit dem Unterschied, das der generierte Hash nicht gespeichert, sondern mit dem gespeicherten Hash verglichen wird.

Der Server kennt das Passwort nicht. Der Server kann das Passwort auch nicht "Entschlüsseln", weil es überhaupt nicht gespeichert ist. Genau darin liegt der Sinn des Hashens.

Das einzige, was ein Angreifer machen kann, ist ein Passwort zu generieren, welches den gleichen Has erzeugt.

An dieser Stelle kommt das Salz ins Spiel. So lange das Salz in Sicherheit ist, ist es einem Angreifer nichz möglich, ein Passwort mit dem selben Hash zu generieren, weil durch das Hinzufügen des Salzes der Hash verändert wird.
 
@karstenschilder: Ein paar kleine Korrekturen und zusätzliche Details:

Zunächst einmal wird im allgemeinen Szenario davon ausgegangen, dass der Angreifer eine Datenbank in die Finger kriegt (wie in vielen Vorfällen) und daran interessiert ist die Passwörter der Nutzer zu erfahren. Es dürfte ihm (im Allgemeinen) nicht darum gehen ein Passwort zu finden, das lediglich den gleichen Hash erzeugt. Ferner wird im Allgemeinen davon ausgegangen, dass der Angreifer, der an die Datenbank kommt, auch an die Salts kommt, da diese stets zusammen mit den Passwörtern benötigt werden.

- Wenn die Passwörter im Klartext gespeichert sind, ist der Angreifer mit dem Erlangen der Datenbank fertig. Das ist die größte Blamage überhaupt für denjenigen, der für die Installation zuständig war.

- Wenn die Passwörter als einfacher MD5/SHA{1/2/...}/... Hash gespeichert werden, kann er folgendes tun:
Er nimmt die Hashs für eine lange Liste möglicher Passwörter (und vor allem wahrscheinlicher Passwörter) und muss hinterher für jeden Nutzer nur noch in seiner Liste nachschauen. Gleiche Nutzer haben den gleichen Hash, mit einer überraschend kurzen Liste vorberechneter Hashs (für die üblichen verdächtigen "password", "password1", "Password1", "123456",... ) wird er bereits erhebliche Teile der Datenbank geknackt haben.

- Wenn die Passwörter mit alle mit einem Salt gehasht sind, dann muss er so eine Hashliste selber berechnen und zwar nach den gleichen durchprobierten Passwörtern nach Häufigkeit und dem entsprechenden Salt angehängt.

- Wenn für jedes Passwort ein anderer Salt verwendet wird (kann z.B. in der Datenbank in den einzelnen Datensätzen zum jeweiligen Passwort abgelegt werden), dann hat der Angreifer ein Problem. Nutzer mit dem gleichen Hash (die dann kaum noch vorkommen werden, weil Hashkollisionen in diesem Szenario selten sein sollten) können unterschiedliche Passwörter haben. Eine vorberechnete Liste mit Hashes müsste nun für jedes mögliche Passwort und jeden möglichen Hash gemacht werden. Wenn der Salt kurz genug ist, könnte das immer noch ein lohnenswertes Unterfangen werden.. Da trotzdem die meisten User schwache Passwörter verwenden dürften, ist der Zeitraum zum Knacken des Durchschnittspassworts überschaubar, das Knacken der gesamten Datenbank wird aber teuer. Lohnenswert ist es vielleicht trotzdem, also auch bei vorbildlichem Sicherheitskonzept muss auf die Passwortdatenbank aufgepasst werden.

Da diese technischen Überlegungen seit über 30 Jahren bekannt sind, gilt jede Variante bis auf die letzte als grob fahrlässig.

EDIT: Asche auf mein Haupt, ich habe einen relativ wichtigen Zusatz vergessen: Das verwenden einer langsamen Hashfunktion. Wenn eine Hash-Funktion verwendet wird, die so langsam ist, dass eine moderne CPU "lange", zum Beispiel 0,2 Sekunden, braucht, dann werden selbst Brute-Force-Attacken gegen individuelle Hashs sehr teuer. Das erhöht die Sicherheit der Daten nochmal sehr deutlich ist allerdings auch die erste Variante, die den Betreiber der Webseite Geld kostet, denn auch sein Server muss nun mehr rechnen. Wie langsam man die Hashfunktion macht ist eine Abwägung. Möglichst so schnell, dass man selbst nicht zu sehr unter 1-2 Hashberechnungen pro Login leidet und möglichst so langsam, dass ein Angreifer mit einer Serverfarm deutlich unter 10000 Hashberechnungen pro angegriffenem Hash leidet.
 
@dpazra: Der Salt wurde mit allergrößter Sicherheit in der selben DB gespeichert. Ich kenne kaum eine Software, die es anders macht. Wer MD5 einsetzt, der hat sich DIE Mühe bestimmt nicht gemacht.
Auch wenn der Salt für jeden Hash anders ist, was bringt es dann noch? Wenn der Dump vorliegt, parse ich mir die Hashes + Salt zurecht, schaue womöglich, wie das Passwort mit dem Salt kombiniert wurde (evtl. vorher noch unhex'en) und los geht es.

Ich habe es einem Kunden mal vorgemacht. Dort haben wir die Hashes + individuellem Salt aus der DB gezogen, schnell in die Software geschaut, wie gesalzen wurde und dann mit Cuda + Nvidia GPU 500 Millionen Passwörter die Sekunde ausprobiert (sogar "nur" eine GTX 960).
Wir haben irgendeine Passwortliste ergooglet, um die 100MB. Den Salt hängen die Cracker an den String nach deinen Vorgaben an und unhexen sogar vorher.

Man darf nicht unterschätzen, wie einfach das heute alles geht... Wenn ich das nach ein paar Minuten googlen konnte, kann das jemand, der sich damit dauerhaft beschäftigt, bestimmt noch viel besser. :-)

PS: Wir konnten ihn umstimmen, die Authentifizierung zu verändern...
 
@andryyy: Der Salt kann auch gerne in der selben DB gespeichert werden. Es ist nicht der Sinn des Salts als Geheimnis zu fungieren. Du fragst "Auch wenn der Salt für jeden Hash anders ist, was bringt es dann noch?", allerdings hatte ich genau das in dem Kommentar erklärt, auf den du antwortest. Die Verwendung von unterschiedlichen genügend langen Salts für jedes Passwort führt dazu, dass du nicht das selbe Hash zu Passwort Wörterbuch zum Knacken der gesamten DB verwenden kannst.

Das führt aber dazu, dass der Angriff auf die Passwörter zu einem reinen Brute-Force Angriff (Anmerkung zur Bezeichnung: Ich bezeichne auch ein häufigkeitsgewichtetes Durchprobieren als Brute-Force) verkommt.

Damit ist jedoch bereits die optimale Sicherheit für das hier diskutierte Szenario erreicht, was sich auch leicht begründen lässt. Stell dir ein beliebiges
1. passwortbasiertes Login-Verfahren vor, bei dem
2. der Angreifer sowohl das Verfahren zu Passwortverifizierung als auch
3. die Datensätze anhand derer die Passwortverifizierung durchgeführt wird
kennt.

zu 1.: Für nicht-passwortbasierte Verfahren müssen wir nicht diskutieren, wie wir das Passwort vor dem Angreifer schützen.
zu 2.: Wenn wir das nicht annehmen, können wir einfach eine geheime Hashfunktion erfinden und unsere Datenbank wird unangreifbar. Abgesehen davon stellt sich die Frage, warum wir unseren Programmcode, nicht aber unsere Datensätze schützen können und warum wir die Datensätze nicht dort speichern, wo der Programmcode, der eh Zugriff darauf braucht, ja anscheinend sicher ist.
zu 3.: Wenn wir sicherstellen könnten, dass der Angreifer an notwendige Daten nicht herankommt, könnten wir ihn genauso gut nicht an die Passwort-Hashes oder an die Salts ranlassen oder unser Login-Verfahren ganz zu dem sicheren Ort outsourcen.

In einem Szenario mit 1, 2 und 3 kannst du aber offensichtlich immer einen Brute-Force Angriff starten. Von einer Sicherheitslücke kann man genau dann sprechen, wenn Angreife beschrieben werden können, die effizienter als Brute Force sind. (und den Schutz vor Brute-Force-Angriffen habe ich bereits im Edit angeschnitten).

Deshalb interessiert mich zu welcher Form der Authentifizierung ihr euren Kunden überredet habt. Was macht sie resistent gegen Brute-Force-Angriffe?
 
@dpazra: ? "Die Verwendung von unterschiedlichen genügend langen Salts für jedes Passwort führt dazu, dass du nicht das selbe Hash zu Passwort Wörterbuch zum Knacken der gesamten DB verwenden kannst."

Das stimmt nicht. Das ist total egal, das der Salt anders ist. Wenn der einmalige Salt NEBEN dem Passwort steht (MD5), dann dumpe ich mir den MD5 UND den Salt, merge die beiden zu einem String a la "MD5:SALT" und gebe den Cracker durch, dass der Salt jeweils rechts vom MD5 steht.
Der Cracker nimmt sich dann das Wörterbuch und hängt einfach (je nach Art, wie gesagt) den Salt rechts an. So wird anstatt "1234" eben "1234SALT" gebruteforced.

Ich frage mich, wie du das überhaupt in Frage stellen kannst, wenn ich doch schrieb, dass wir auf diese Art erfolgreich einige PWs knacken konnten. ^^
 
@andryyy: Ein Dictionary Hack greift nur EIN einzelnes Passwort an, NICHT die ganze Datenbank. Und um das zu machen brauchst du die Datenbank überhaupt nicht, sondern kannst im Prinzip auch die einfache Login Funktion des Servers angreifen.

Vorteil des DB-Zugriffs wäre, das es Schutzmöglichkeiten gegen Brute Force aushebelt (Sperrung des Kontos nach x Versuchen z.B.).
Aber bei gutem Salt (und zudem guter Hash-Funktion) muss ein Angreifer immer noch JEDES Passwort einzeln angreifen, was IMMER mit einem gewissen Aufwand verbunden ist und sich damit erstmal lohnen muss, was man idr. nicht einfach bei einem zufälligen User macht und erst recht nicht bei einer Datenbank mit tausenden oder gar millionen (45 Millionen im vorliegenden Fall) Usern.

Die Angriffsmethode, die mit dem individuellen Salt verhindert werden soll ist der Angriff mit einem Rainbow-Table.
In einem Rainbow-Table stehen zu allen Hashs die Klartext-Strings, die zu dem jeweiligen Hash führen. Idr. lässt sich das betreffende Passwort damit direkt oder mit sehr wenigen Versuchen knacken.

Wird dir Datenbank NUR gehasht, ist es mit einem Rainbow-Table für die betreffende Hashfunktion gelaufen. Damit sind ALLE Passwörter der Datenbank bekannt.

Bei einem einzelnen Salt für die ganze DB muss ein neuer Rainbow-Table speziell für diesen einen Salt erstellt werden, was immer noch etwas aufwändig ist, aber machbar. Grade mit guten GPU-Clustern, wie du schon richtig angemerkt hast.
Ist das erledigt, sind wir wieder beim letzten Ergebnis, ALLE Passwörter sind bekannt.

Wird nun jedes Salt INDIVIDUELL erstellt, müsste man für JEDEN Salt einen eingenen Rainbow-Table erstellen. Und ab da macht es keinen Unterschied mehr, ob man nun dies macht, oder eben das eine Passwort DIREKT angreift, ganz ohne Hashfunktion. Vermutlich ist sogar der direkte Brute Force, gewichtet und zusammen mit einem Wörterbuch, deutlich effizienter.
Aber um das nochmal ganz klar zu sagen, dann hat man EIN einzelnes Passwort und nicht gleich die ganze Datenbank voller User geknackt.

Ich hoffe das klärt das Thema...45 Millionen mal Brute Force ist DEUTLICH aufwändiger als einmal Brute Force auf ein einzelnes Salt.

Um mal noch ein paar Zahlen in den Raum zu werfen...

Selbst bei 500 Millionen PWs/sec liegen wir bei einem 8 stelligen Passwort bestehend aus a-z A-Z 0-9 bei etwa 156 STUNDEN für ein einzelnes Passwort.
Oder etwa 800.000 Jahre für die ganzen 45 Millionen.
Einen Rainbow-Table für ein einzelnes Salt erstellen, dürfte deutlich flotter sein ^^
 
@andryyy: Ich glaube du hast den zitierten Absatz nicht richtig verstanden (und abgesehen davon meine Kommentare nicht zu Ende gelesen): "... dass du nicht das selbe Hash zu Passwort Wörterbuch zum Knacken der gesamten DB verwenden kannst. " Du sagst, die Aussage stimme nicht und argumentierst, du könntest die Datenbank samt Salts in den Cracker schicken. Das widerspricht jedoch gar nicht der Aussage, Brute-Force ist etwas anderes als ein Angriff über ein Hash-zu-Passwort Wörterbuch. Ich erkläre den Unterschied an einem einfachen Beispiel.

Dein Cracker kann jedes Passwort einzeln per Bruteforce angreifen. Das ist prinzipbedingt bei dem Erlangen jeder Datenbank inkl. Passwortverifizierungsverfahren möglich. Diese Operation können wir beliebig teuer machen, indem wir eine teure (d.h.: langsame) Hashfunktion verwenden. Der Cracker muss für jeden Rateversuch das geratene Passwort+Salt hashen und gegen den Hash in der Datenbank testen. Der berechnete Hash kann nicht wiederverwendet werden, denn wenn wir für den nächsten Eintrag das gleiche Passwort raten wollen müssen wir einen neuen Hash berechnen, da der Salt das Ergebnis der Hashfunktion verändert.
Aufwand: Der Cracker muss (Anzahl Passwörter in Datenbank)*(durchschn. Anzahl Rateversuche) viele Hashes für diesen Angriff berechnen.
Wenn jeder Hash 0,1 oder 0,2 Sekunden braucht (wegen einer entsprechend teuren Hashfunktion) ist das je nach Anzahl der Passwörter für keine besonders hohe Anzahl an Rateversuchen noch machbar. MD5 ist keine teure Hashfunktion.

Wären die Hashes ungesalzen, würde sich nun aber folgendes Angriffsszenario ergeben. Wir berechnen für alle Rateversuche die Hashes und legen sie in einer Struktur ab, die sich schnell durchsuchen lässt (einfaches und lange nicht optimales Beispiel: eine sortierte, im Speicher zusammenhängende Liste). Das ist unser Hash-zu-Passwort Wörterbuch, dass wir oben nicht verwenden konnten. Nachdem wir damit fertig sind, können wir die Hashes direkt nachschlagen.
Aufwand: Der Cracker muss (Anzahl an Rateversuchen) viele Hashes für diesen Angriff berechnen. Das ist offensichtlich um Größenordnungen kleiner als der Rechenaufwand für den Bruteforceangriff oben. Danach kann der Cracker die Tabelle durchgehen und schlägt jeden Hash im Wörterbuch nach. Wenn das Wörterbuch sortiert ist, braucht er für einmal nachschlagen höchstens log(Wörterbuchlänge)/log(2) Versuche, bis er einen Eintrag findet. Wenn das Wörterbuch eine Länge von 1.000.000 Einträgen hat, sind das höchstens 20 Nachschlageschritte pro Eintrag, was auf einer SSD unter 2 Millisekunden dauert (kann man noch deutlich schneller implementieren als hier beschrieben, der Einfachheit halber erkläre ich es aber so). Das schöne an dem Wörterbuch ist, dass ich es für jede Datenbank mit der gleichen Hashfunktion wiederverwenden kann.

Wenn die Hashes gesalzen sind, aber für alle Passwörter der gleiche Salt verwendet wurde, kann ich immer noch ein Wörterbuch bauen, dass ich dann nur für diesen spezifischen Salt verwenden kann. Wenn die Hashes mit unterschiedlichen Salts gesalzen sind, es aber nur 100000 mögliche Werte für den Salt gibt (zu kurzer Salt), kann ich vielleicht noch eine Datenbank für jeden möglichen Salt-Wert aufbauen (Wenn die alte Datenbank 100 MB groß war, sind das dann 10 TB... machbar).

Wenn ich unterschiedliche zufällige Salts mit einer Länge von z.B. 40 Byte (überschaubarer Overhead pro User), müsste die Wörterbuchgröße von 100MB auf ca. 2,14*10^98 MB anwachsen. Soviel kann ich nichtmal speichern, wenn ich das gesamte Universum zu Festplatten verarbeite.
 
@dpazra: Ich glaube zusammen sollte klar werden, wieso individuelle Salts absolut notwendig sind :p
 
@dpazra: Eben, ein individueller Salt gehört zum Passwort und kann getrost in der DB abgelegt werden. Und seine einzige Aufgabe ist es den Aufwand für Bruteforcer zu erhöhen und die Verwendung von Rainbow-Tables einzuschränken, weil durch die Individualität die nötige Rechenleistung fürs Bruteforcing und/oder dem generieren individueller Rainbow-Tables auf Basis der Salts hochgetrieben wird. Zudem sind identische Passwörter verschiedener User nicht sofort ersichtlich.

Um es Angreifern noch ein bisschen schwerer zu machen, sollte man sich aber nicht nur auf die Salts verlassen. Am besten kombiniert man das ganze dann noch mit einen Pepper-String, der zusätzlich auf alle Passwort-Hashes angewandt wird. Im Gegensatz zum Salt wird ein Pepper-String aus Sicherheitsgründen grundsätzlich NIE in der DB gespeichert, sondern bestenfalls direkt im Login-Script (oder .cfg-File auf dem Server).

Wenn ein Angreifer durch SQL-Injections nur Zugriff auf die DB bekommt, aber nicht an die Scripts selbst, hat er zwar Passwort-Hashes und Salts, die ihm ohne den globalen Pepper-String des Login-Scripts aber auch nichts nützen, da die Hashes auch aus den für ihn unbekannten Pepper-String generiert wurden.

Ist das Passwort nur mit dem Salt kombiniert, kann der Angreifer leicht durchpropieren welches "<Passwort>+Salt" zum jeweiligen Hash führt und kennt hinterher das Passwort - das funktioniert bei leichten Passwörtern (password, 123456) relativ schnell zum Erfolg.

Bei einem Pepper-kombinierten Hash, funktioniert das aber nicht, da dem Angreifer so neben dem Passwort auch der Pepper-String fehlt. Bruteforcing wird damit ein fast aussichtsloser Aufwand, da der Angreifer so nicht einfach wahllos Standard-Passwörter mit den bekannten Salts kombinieren kann, um das Ergebnis mit dem Hash abzugleichen.
 
@andryyy: Als Ergänzung zu dpazra:
Ja mit dem Brute Force lässt sich EIN Passwort knacken, aber eben NICHT alle. Wenn das Salt für alle gleich ist, hat man mit einem Brute Force gleich die ganze Datenbank geknackt. Und DAS ist der bedeutende Unterschied.

Und EIN User ist den Aufwand einfach nicht wert, vor allem, wenn es sich um einen Forenaccount handelt.
Da müsste es eben schon ein User sein, der das Passwort ÜBERALL einsetzt, zum Beispiel auch bei seiner Bank oder ähnlich sensiblen Stellen. Aber das ist ohnehin grob fahrlässig und sollte sich langsam rumgesprochen haben.

Langer Rede kurzer Sinn, wer keinen individuellen Salt für jedes Passwort verwendet und dazu kein "besseres" Hashverfahren als MD5, handelt für all seine User fahrlässig.
 
@Draco2007: Ich dumpe mir den Datensatz mit PW (hashed) UND Salt des PWs. Also habe ich zum Beispiel "MD5:HASH" in einer Datei. Der Salt steht jetzt rechts vom Hash, verstehst du? Der Cracker (das Programm) kann den Salt für jedes einzelne Passwort aus der Datei lesen und entsprechend das Wörterbuch anpassen.

Ich kann dir eine solche DB einfach mal darstellen:

User, Password, Salt
------------------------
user1,22e5ab5743ea52caf34abcc02c0f161d,apodjgfajgfaga
user2,ffaaab57434a526888abc902c0f1121,olifhj0913jraf

Ich dumpe mir jetzt folgende Daten:

22e5ab5743ea52caf34abcc02c0f161d:apodjgfajgfaga
12aaab57434a526888abc902c0f1121:olifhj0913jraf

Dem Cracker sage ich "links ist der MD5-Hash, rechts der einmalige Salt". Das Programm testet jetzt anstatt "s3cret" zum Beispiel "s3cretapodjgfajgfaga". Das ist natürlich abhängig von der Anwendung, wie der Salt angefügt wird. Für Open-Source Software bedeutet das allerdings 10 Sekunden googlen. :-)
 
@andryyy: Ich hab dich falsch verstanden, Antwort oben...
 
Hier sind beispielweise die Technikseiten die VerticalScope hostet, falls es jemanden interessiert:
http://www.verticalscope.com/technology/site-list.html

Im Menü auf der Seite unter "OUR VERTICALS" können auch andere Kategorien eingesehen werden.
Kommentar abgeben Netiquette beachten!

Video-Empfehlungen