Hash in der /etc/shadow: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 10: Zeile 10:
  
 
<pre>
 
<pre>
$y$j9T$GThSkReZ3cOQQojV/asp00$vkzM8oX6944ruaPuQ9EJT1CEZiQ1d/WA1MXOkp1ULtB
+
xinux:$y$j9T$GThSkReZ3cOQQojV/asp00$vkzM8oX6944ruaPuQ9EJT1CEZiQ1d/WA1MXOkp1ULtB
 
</pre>
 
</pre>
  
Zeile 60: Zeile 60:
 
'''Was <code>crypt($ARGV[0], $ARGV[1])</code> mit den Parametern macht:'''
 
'''Was <code>crypt($ARGV[0], $ARGV[1])</code> mit den Parametern macht:'''
  
* <code>$ARGV[0]</code> (das Passwort, z. B. <code>zinch</code>) und <code>$ARGV[1]</code> (der komplette <code>$HASH</code>-String) werden an Perls <code>crypt()</code>-Funktion übergeben, die direkt die System-''libcrypt'' (glibc) aufruft.
+
* <code>$ARGV[0]</code> (das Passwort) und <code>$ARGV[1]</code> (der komplette <code>$HASH</code>-String) werden an Perls <code>crypt()</code>-Funktion übergeben, die direkt die System-''libcrypt'' (glibc) aufruft.
 
* <code>crypt()</code> liest aus dem zweiten Argument automatisch nur den vorderen Teil bis zum dritten <code>$</code> aus (<code>$y$j9T$GThSkReZ3cOQQojV/asp00</code>) – Algorithmus-ID, Cost-Parameter und Salt. Der Rest (der eigentliche Hash-Teil hinter dem letzten <code>$</code>) wird ignoriert.
 
* <code>crypt()</code> liest aus dem zweiten Argument automatisch nur den vorderen Teil bis zum dritten <code>$</code> aus (<code>$y$j9T$GThSkReZ3cOQQojV/asp00</code>) – Algorithmus-ID, Cost-Parameter und Salt. Der Rest (der eigentliche Hash-Teil hinter dem letzten <code>$</code>) wird ignoriert.
 
* Mit diesen ausgelesenen Werten hasht <code>crypt()</code> das übergebene Passwort '''neu''', exakt nach demselben Verfahren (gleicher Algorithmus, gleicher Cost-Faktor, gleiches Salt) wie beim Original.
 
* Mit diesen ausgelesenen Werten hasht <code>crypt()</code> das übergebene Passwort '''neu''', exakt nach demselben Verfahren (gleicher Algorithmus, gleicher Cost-Faktor, gleiches Salt) wie beim Original.
 
* Zurückgegeben wird der komplette neue Hash-String im selben Format – der wird dann mit dem Original-Hash verglichen.
 
* Zurückgegeben wird der komplette neue Hash-String im selben Format – der wird dann mit dem Original-Hash verglichen.
 +
===Mit John testen===
 +
*sudo apt install john
 +
*echo 'xinux:$y$j9T$GThSkReZ3cOQQojV/asp00$vkzM8oX6944ruaPuQ9EJT1CEZiQ1d/WA1MXOkp1ULtB' > xinux-hash.txt
 +
*john --format=crypt --wordlist=bad-passwords xinux-hash.txt
 +
*john --show --format=crypt xinux-hash.txt
 +
xinux:zinch

Aktuelle Version vom 12. August 2026, 06:57 Uhr

Der crypt-Hash im Detail

Ein Passwort-Hash in /etc/shadow ist kein einzelner Wert, sondern setzt sich aus mehreren Teilen zusammen, getrennt durch $-Zeichen:

$id$param$salt$hash

Beispiel:

xinux:$y$j9T$GThSkReZ3cOQQojV/asp00$vkzM8oX6944ruaPuQ9EJT1CEZiQ1d/WA1MXOkp1ULtB

Algorithmus-ID

Das erste Feld (y) gibt an, welcher Hash-Algorithmus verwendet wurde. yescrypt ist auf aktuellen Linux-Systemen (z. B. Debian, Fedora, Rocky Linux) der Standard.

ID Algorithmus
$1$ MD5 (veraltet, unsicher)
$5$ SHA-256
$6$ SHA-512
$2b$ bcrypt
$y$ yescrypt (aktueller Standard)

Parameter (Cost-Faktor)

Das zweite Feld (j9T) kodiert die Kostenparameter des Algorithmus – u. a. wie viel Speicher und Rechenzeit pro Hash-Berechnung nötig sind. Ein höherer Cost-Faktor macht das Verfahren absichtlich langsamer, um Bruteforce-Angriffe zu erschweren.

Salt

Das dritte Feld (GThSkReZ3cOQQojV/asp00) ist das Salt – eine zufällige Zeichenfolge, die bei jedem passwd-Aufruf neu erzeugt wird.

  • Wird zusammen mit dem Passwort gehasht
  • Steht offen sichtbar im Hash (ist kein Geheimnis)
  • Sorgt dafür, dass zwei User mit identischem Passwort unterschiedliche Hashes erhalten
  • Verhindert Angriffe mit vorberechneten Rainbow-Tables

Hash

Das letzte Feld (vkzM8oX6944ruaPuQ9EJT1CEZiQ1d/WA1MXOkp1ULtB) ist das eigentliche Ergebnis der Hash-Funktion, berechnet aus Passwort, Salt und Parametern. Der Vorgang ist eine Einwegfunktion – aus dem Hash lässt sich das Passwort nicht direkt zurückrechnen.

Mit Perl testen

HASH='$y$j9T$GThSkReZ3cOQQojV/asp00$vkzM8oX6944ruaPuQ9EJT1CEZiQ1d/WA1MXOkp1ULtB'
for PW in supper trottel zinch; do
    echo -n "$PW: "
    perl -e 'print crypt($ARGV[0], $ARGV[1]), "\n"' "$PW" "$HASH"
done

Was crypt($ARGV[0], $ARGV[1]) mit den Parametern macht:

  • $ARGV[0] (das Passwort) und $ARGV[1] (der komplette $HASH-String) werden an Perls crypt()-Funktion übergeben, die direkt die System-libcrypt (glibc) aufruft.
  • crypt() liest aus dem zweiten Argument automatisch nur den vorderen Teil bis zum dritten $ aus ($y$j9T$GThSkReZ3cOQQojV/asp00) – Algorithmus-ID, Cost-Parameter und Salt. Der Rest (der eigentliche Hash-Teil hinter dem letzten $) wird ignoriert.
  • Mit diesen ausgelesenen Werten hasht crypt() das übergebene Passwort neu, exakt nach demselben Verfahren (gleicher Algorithmus, gleicher Cost-Faktor, gleiches Salt) wie beim Original.
  • Zurückgegeben wird der komplette neue Hash-String im selben Format – der wird dann mit dem Original-Hash verglichen.

Mit John testen

  • sudo apt install john
  • echo 'xinux:$y$j9T$GThSkReZ3cOQQojV/asp00$vkzM8oX6944ruaPuQ9EJT1CEZiQ1d/WA1MXOkp1ULtB' > xinux-hash.txt
  • john --format=crypt --wordlist=bad-passwords xinux-hash.txt
  • john --show --format=crypt xinux-hash.txt
xinux:zinch