John the Ripper und Passwort-Salting

Kali LinuxBeginner
Jetzt üben

Einleitung

Im Bereich der Cybersicherheit ist der Schutz von Benutzeranmeldeinformationen von größter Bedeutung. Passwörter werden, wenn sie gespeichert werden, selten im Klartext aufbewahrt. Stattdessen werden sie typischerweise gehasht, d. h. sie werden mithilfe einer kryptografischen Einwegfunktion in eine Zeichenkette fester Größe umgewandelt. Dies verhindert, dass Angreifer direkt auf Passwörter zugreifen können, selbst wenn sie Zugriff auf die Datenbank erhalten. Ein einfacher Hash reicht jedoch nicht aus. Angreifer können vordefinierte Tabellen von Hashes (Rainbow Tables) oder Brute-Force-Angriffe verwenden, um Passwörter zu knacken.

Hier kommt das "Salting" ins Spiel. Salting ist eine Technik, bei der eine eindeutige, zufällige Zeichenkette (das "Salt") zu einem Passwort hinzugefügt wird, bevor es gehasht wird. Dieses Salt wird dann zusammen mit dem Hash gespeichert. Wenn ein Benutzer versucht, sich anzumelden, wird dasselbe Salt abgerufen und vor dem Hashing mit dem eingegebenen Passwort kombiniert, und der resultierende Hash wird mit dem gespeicherten Hash verglichen.

In diesem Lab werden Sie das Konzept des Passwort-Saltings untersuchen, seine Bedeutung für die Verbesserung der Sicherheit verstehen und beobachten, wie ein leistungsstarkes Passwort-Cracking-Tool wie John the Ripper mit gesalzenen Hashes interagiert. Sie lernen, gesalzene Hashes zu identifizieren, zu sehen, wie John the Ripper damit umgeht, und den erheblichen Einfluss zu verstehen, den Salting auf die Schwierigkeit des Passwort-Crackings hat. Schließlich erhalten Sie einen Einblick, wie Salting in der realen Passwortspeicherung implementiert wird.

Das Konzept des Saltings verstehen

In diesem Schritt lernen Sie das grundlegende Konzept des Passwort-Saltings und warum es für die Verbesserung der Passwortsicherheit unerlässlich ist.

Wenn ein Passwort "gesalzen" wird, wird eine eindeutige, zufällige Zeichenkette (das Salt) zum Passwort hinzugefügt, bevor es gehasht wird. Das bedeutet, dass selbst wenn zwei Benutzer exakt dasselbe Passwort haben, ihre gespeicherten Hashes unterschiedlich sein werden, da für jeden ein anderes Salt verwendet wurde. Dies macht vordefinierte Rainbow Tables, die auf einem festen Hash für ein bestimmtes Passwort basieren, effektiv nutzlos. Es erschwert auch Brute-Force-Angriffe, da ein Angreifer einen Hash für jedes mögliche Passwort und jedes mögliche Salt berechnen müsste, anstatt nur für jedes mögliche Passwort.

Betrachten wir ein Beispiel für einen gesalzenen Hash. Öffnen Sie die Datei salted_passwords.txt, die in Ihrem Verzeichnis ~/project erstellt wurde.

cat ~/project/salted_passwords.txt

Sie sehen eine Ausgabe, die dieser ähnelt:

user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
user2:5f4dcc3b5aa765d61d8327deb882cf99
user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword
user4:$6$short$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:shortpass

Beachten Sie die Zeilen für user1, user3 und user4. Sie enthalten einen Abschnitt wie $6$salt12345$ oder $6$another_salt$. Das $6$ gibt den verwendeten Hashing-Algorithmus an (in diesem Fall SHA-512), und die Zeichenkette zwischen dem zweiten und dritten $-Zeichen (salt12345 oder another_salt) ist das Salt. Der Rest der Zeichenkette nach dem dritten $ ist der eigentliche Hash des Passworts in Kombination mit dem Salt. Die Zeile für user2 ist ein ungesalzener MD5-Hash, den wir später zum Vergleich verwenden werden.

Die wichtigste Erkenntnis ist, dass jeder gesalzene Hash ein eindeutiges Salt hat, was es schwieriger macht, mehrere Passwörter gleichzeitig mit denselben vordefinierten Tabellen zu knacken.

Gesalzene Hashes identifizieren

In diesem Schritt lernen Sie, wie Sie gesalzene Hashes anhand ihrer gängigen Formate identifizieren können. Das Erkennen dieser Formate ist der erste Schritt, um zu verstehen, wie man Passwort-Cracking oder -Schutz angeht.

Verschiedene Hashing-Algorithmen und Systeme verwenden unterschiedliche Formate zur Speicherung gesalzener Hashes. Viele gängige Formate, insbesondere solche, die in Linux-Systemen verwendet werden, folgen jedoch einem Muster, bei dem das Salt direkt in die Hash-Zeichenkette eingebettet ist, oft durch Sonderzeichen wie $ getrennt.

Betrachten wir noch einmal die Datei salted_passwords.txt und suchen gezielt nach Mustern, die auf Salting hinweisen.

cat ~/project/salted_passwords.txt

Wie Sie im vorherigen Schritt beobachtet haben:

  • user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
  • user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword
  • user4:$6$short$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:shortpass

Diese Zeilen zeigen deutlich das Präfix $6$ (das auf SHA-512 crypt hinweist), gefolgt von der Salt-Zeichenkette (z. B. salt12345, another_salt, short) und dann dem eigentlichen Hash. Diese Struktur ist ein starker Indikator für einen gesalzenen Hash.

Im Gegensatz dazu die Zeile für user2:

  • user2:5f4dcc3b5aa765d61d8327deb882cf99

Dies ist ein einfacher MD5-Hash. Er enthält keine Trennzeichen oder eingebettetes Salt, wodurch er leicht als ungesalzener Hash identifiziert werden kann.

Die Fähigkeit, schnell zwischen gesalzenen und ungesalzenen Hashes zu unterscheiden, ist für Sicherheitsexperten und Penetrationstester von entscheidender Bedeutung, da sie die anzuwendenden Cracking-Strategien bestimmt.

John the Ripper im Umgang mit gesalzenen Hashes beobachten

In diesem Schritt verwenden Sie John the Ripper, ein beliebtes Tool zum Knacken von Passwörtern, um zu beobachten, wie es sowohl mit gesalzenen als auch mit ungesalzenen Hashes umgeht. Dies wird die praktischen Auswirkungen des Saltings demonstrieren.

Zuerst versuchen wir, die Passwörter in salted_passwords.txt mit einer einfachen Wortliste zu knacken. Für diese Demonstration verwenden wir eine kleine, benutzerdefinierte Wortliste.

Erstellen Sie eine Wortlistendatei namens wordlist.txt in Ihrem Verzeichnis ~/project mit einigen gängigen Passwörtern:

echo "password" > ~/project/wordlist.txt
echo "user1password" >> ~/project/wordlist.txt
echo "anotherpassword" >> ~/project/wordlist.txt
echo "shortpass" >> ~/project/wordlist.txt
echo "123456" >> ~/project/wordlist.txt

Führen Sie nun John the Ripper mit dieser Wortliste gegen Ihre Datei salted_passwords.txt aus:

john --wordlist=~/project/wordlist.txt ~/project/salted_passwords.txt

John the Ripper analysiert die Hashes. Sie sollten eine Ausgabe sehen, die anzeigt, dass es versucht, die Passwörter zu knacken. Es wird wahrscheinlich das Passwort von user2 schnell finden, da es sich um einen ungesalzenen MD5-Hash handelt und "password" in der Wortliste enthalten ist. Es wird auch die gesalzenen Passwörter finden, wenn ihre entsprechenden Klartexte in der Wortliste vorhanden sind.

Die Beispielausgabe könnte wie folgt aussehen:

Using default input encoding: UTF-8
Loaded 4 password hashes with no different salts to crack (crypt, generic crypt(3) [MD5/Blowfish/SHA1/SHA256/SHA512/XSHAa/XSHAab/bcrypt/scrypt])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password         (user2)
user1password    (user1)
anotherpassword  (user3)
shortpass        (user4)
4g 0:00:00:00 DONE (2023-10-27 10:30) ...
Session completed.

Nachdem John fertig ist, können Sie die geknackten Passwörter mit der Option --show anzeigen:

john --show ~/project/salted_passwords.txt

Dieser Befehl zeigt alle Passwörter an, die John erfolgreich geknackt hat.

user2:password (user2)
user1:user1password (user1)
user3:anotherpassword (user3)
user4:shortpass (user4)

4 password hashes cracked, 0 left

John the Ripper ist darauf ausgelegt, verschiedene Hash-Formate zu verarbeiten, einschließlich solcher mit eingebetteten Salts. Es extrahiert automatisch das Salt und verwendet es während des Knackvorgangs. Die Anwesenheit eindeutiger Salts für jedes Passwort erhöht jedoch den erforderlichen Rechenaufwand für das Knacken erheblich, insbesondere bei groß angelegten Angriffen.

Die Auswirkungen des Saltings auf das Knacken verstehen

In diesem Schritt festigen Sie Ihr Verständnis dafür, warum das Salten das Knacken von Passwörtern erheblich erschwert, insbesondere bei groß angelegten Angriffen.

Betrachten Sie den Eintrag user2 aus unserer Datei salted_passwords.txt: user2:5f4dcc3b5aa765d61d8327deb882cf99. Dies ist ein ungesalzener MD5-Hash für das Passwort "password". Wenn ein Angreifer eine Datenbank mit ungesalzenen MD5-Hashes erhält, kann er:

  1. Rainbow Tables verwenden: Vorkompilierte Tabellen von Hashes für gängige Passwörter. Wenn "password" in der Tabelle enthalten ist, wird sein Hash 5f4dcc3b5aa765d61d8327deb882cf99 dort vorhanden sein, und der Klartext kann sofort abgerufen werden.
  2. Mehrere Passwörter gleichzeitig knacken: Wenn viele Benutzer dasselbe schwache Passwort haben (z. B. "123456"), sind ihre ungesalzenen Hashes identisch. Ein Angreifer muss nur eine Instanz dieses Hashes knacken, um das Passwort für alle Benutzer zu kennen, die es gemeinsam nutzen.

Betrachten wir nun die gesalzenen Hashes:

  • user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
  • user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword

Selbst wenn user1 und user3 dasselbe Passwort hätten, wären ihre Hashes unterschiedlich, da ihre Salts (salt12345 und another_salt) unterschiedlich sind. Dies hat mehrere kritische Auswirkungen für Angreifer:

  • Rainbow Tables sind nutzlos: Da jeder Hash aufgrund seines Salts eindeutig ist, werden vorkompilierte Rainbow Tables unwirksam. Ein Angreifer würde eine Rainbow Table für jedes mögliche Salt benötigen, was rechnerisch nicht machbar ist.
  • Hash-spezifisches Knacken: Ein Angreifer muss jeden gesalzenen Hash einzeln knacken. Wenn 100 Benutzer dasselbe Passwort haben, aber jeder ein eindeutiges Salt besitzt, muss der Angreifer 100 separate Knackvorgänge durchführen, einen für jedes eindeutige Hash-Salt-Paar. Dies erhöht die Zeit und die benötigten Ressourcen für einen erfolgreichen Angriff drastisch.
  • Schwierigkeit bei Brute-Force-Angriffen: Bei einem Brute-Force-Angriff muss der Angreifer jedes mögliche Passwort mit seinem spezifischen Salt kombinieren, bevor er es hasht und vergleicht. Dies fügt eine zusätzliche Komplexitätsebene hinzu und verlangsamt den Knackvorgang im Vergleich zu ungesalzenen Hashes erheblich.

Im Wesentlichen verwandelt das Salten ein einzelnes Knackproblem in viele unabhängige Knackprobleme, was groß angelegte Passwortverletzungen für Angreifer wesentlich schwieriger und zeitaufwändiger macht.

Salting bei der Passwortspeicherung implementieren

In diesem Schritt erhalten Sie ein konzeptionelles Verständnis dafür, wie Salting in realen Passwortspeichersystemen implementiert wird. Obwohl wir kein vollständiges System erstellen werden, sehen Sie die Kernkomponenten.

Wenn ein Benutzer sein Passwort festlegt oder ändert, führt ein sicheres System typischerweise die folgenden Schritte aus:

  1. Generieren eines zufälligen Salts: Ein kryptografisch sicherer zufälliger Salt wird generiert. Dieser Salt sollte für jeden Benutzer und jede Passwortänderung eindeutig sein.
  2. Kombinieren von Passwort und Salt: Das Klartextpasswort des Benutzers wird mit dem generierten Salt verkettet.
  3. Hashen der kombinierten Zeichenkette: Die kombinierte Zeichenkette aus Passwort und Salt wird dann durch einen starken, langsamen Hashing-Algorithmus geleitet (z. B. bcrypt, scrypt, Argon2 oder SHA-512 crypt, wie in unseren Beispielen gezeigt). Langsame Hashing-Algorithmen werden bevorzugt, da sie Brute-Force-Angriffe noch zeitaufwändiger machen.
  4. Speichern von Hash und Salt: Der resultierende Hash und der Salt werden zusammen in der Datenbank gespeichert. Der Salt muss nicht geheim sein; sein Zweck ist es, die Eindeutigkeit des Hashes zu gewährleisten.

Wenn ein Benutzer versucht, sich anzumelden:

  1. Abrufen des gespeicherten Salts: Das System ruft den Salt, der mit dem Konto des Benutzers verknüpft ist, aus der Datenbank ab.
  2. Kombinieren des eingegebenen Passworts und des gespeicherten Salts: Das vom Benutzer eingegebene Passwort wird mit dem abgerufenen Salt kombiniert.
  3. Hashen der kombinierten Zeichenkette: Diese kombinierte Zeichenkette wird dann mit demselben Hashing-Algorithmus gehasht, der während der Registrierung verwendet wurde.
  4. Vergleichen der Hashes: Der neu berechnete Hash wird mit dem gespeicherten Hash verglichen. Wenn sie übereinstimmen, ist das Passwort korrekt.

Lassen Sie uns das Generieren eines gesalzenen Hashes mit dem Befehl mkpasswd simulieren, der Teil des Pakets whois ist und Hashes im crypt(3)-Stil generieren kann.

Stellen Sie zunächst sicher, dass whois installiert ist:

sudo apt install -y whois

Generieren Sie nun einen SHA-512 gesalzenen Hash für das Passwort "mysecretpassword" mit einem benutzerdefinierten Salt "mysalt":

mkpasswd -m sha-512 "mysecretpassword" -s "mysalt"

Sie sehen eine Ausgabe, die dieser ähnelt:

$6$mysalt$some_long_hash_string_here

Die Ausgabe $6$mysalt$some_long_hash_string_here ist der gesalzene Hash. $6$ zeigt SHA-512 an, mysalt ist der von Ihnen bereitgestellte Salt, und der Rest ist der eigentliche Hash. In einem realen System würde der Salt zufällig generiert und nicht manuell bereitgestellt.

Dies demonstriert den grundlegenden Prozess. Moderne Anwendungen verwenden Bibliotheken und Frameworks, die diese Details abstrahieren, aber das zugrunde liegende Prinzip der Generierung eines eindeutigen Salts, der Kombination mit dem Passwort, des Hashings und der Speicherung beider bleibt der Eckpfeiler einer sicheren Passwortspeicherung.

Zusammenfassung

In diesem Labor haben Sie ein umfassendes Verständnis für das Salting von Passwörtern und seine entscheidende Rolle bei der Verbesserung der Passwortsicherheit gewonnen. Sie haben gelernt, dass das Salting das Hinzufügen einer eindeutigen, zufälligen Zeichenkette (des Salts) zu einem Passwort vor dessen Hashing beinhaltet, wodurch jeder Hash selbst für identische Passwörter eindeutig wird.

Sie haben erfolgreich gesalzene Hashes anhand ihrer charakteristischen Formate identifiziert, die oft Trennzeichen wie $ und eine eingebettete Salt-Zeichenkette enthalten. Durch praktische Beobachtung mit John the Ripper haben Sie gesehen, wie dieses leistungsstarke Werkzeug sowohl gesalzene als auch ungesalzene Hashes verarbeitet und entscheidend, wie das Salting den Knackprozess auf eine Pro-Hash-Basis zwingt, was den Rechenaufwand für Angreifer erheblich erhöht.

Schließlich haben Sie die konzeptionelle Implementierung des Saltings in Passwortspeichersystemen untersucht und die Schritte zum Generieren, Kombinieren, Hashing und Speichern von Salts und Passwörtern verstanden. Dieses Wissen ist für jeden, der sich mit Cybersicherheit beschäftigt, sei es zur Verteidigung von Systemen oder zum Verständnis von Angriffsmethoden, von grundlegender Bedeutung.

Indem jeder Passwort-Hash eindeutig gemacht wird, mindert das Salting effektiv die Bedrohung durch Rainbow-Table-Angriffe und verlangsamt Brute-Force-Versuche drastisch, was es zu einer unverzichtbaren Technik für eine robuste Passwortsicherheit macht.