Woher weiß Linux, dass das neue Passwort dem vorherigen ähnlich ist?

145

Einige Male habe ich versucht, ein Benutzerkennwort auf verschiedenen Linux-Rechnern zu ändern, und als das neue Kennwort dem alten ähnlich war, beklagte sich das Betriebssystem, dass sie zu ähnlich waren.

Ich habe mich immer gefragt, woher das System das weiß. Ich dachte, dass das Passwort als Hash gespeichert wird. Bedeutet dies, dass das alte Passwort tatsächlich als Klartext gespeichert wird, wenn das System das neue Passwort auf Ähnlichkeit vergleichen kann?

Arkonix
quelle
30
1. off: Klartext? Nein. Wenn (!) Gespeichert, speichern Sie den Hash und vergleichen die Hashes. Unter Linux wird das aktuelle Passwort mit einem neuen Passwort überprüft. BEIDE werden vom Benutzer beim Ändern von Passwörtern angegeben.
Rinzwind
42
@Rinzwind Aber das Vergleichen von Hashes funktioniert nicht, da ein Unterschied von einem Zeichen zu einem völlig anderen Hash führen sollte
slhck
17
Siehe auch Speichert Facebook Klartext-Passwörter? Über Informationssicherheit für andere Möglichkeiten, Ähnlichkeiten zu erkennen, wird nur der Hash des alten Passworts und der Klartext des neuen Passworts angegeben (kein Klartext für altes Passwort).
Bob
21
Sie können tatsächlich die Ähnlichkeit zwischen einem gehashten alten und einem neuen Klartext-Passwort testen. Generieren Sie einfach eine Liste von Passwörtern, die der neuen ähnlich sind, hacken Sie sie alle und vergleichen Sie die resultierenden Hashes mit dem alten Passwort-Hash. Wenn es eine Übereinstimmung gibt, ist es ähnlich.
BWG
2
@BWG: Das ist eine leichte Vereinfachung - die aktuellen Hashing-Schemata salzen den Hash, also müssen Sie zuerst das Salz aus dem alten Passwort-Hash extrahieren und sicherstellen, dass Sie dieses Salz für Ihre neuen Passwörter verwenden. (Ich weise darauf hin, weil es möglich ist, dass die API keine Möglichkeit bietet, ein bestimmtes Salz zu erzwingen.)
Ulrich Schwarz

Antworten:

156

Da Sie bei der Verwendung sowohl das alte als auch das neue Kennwort eingeben müssen passwd, können diese problemlos im Klartext und im Speicher verglichen werden, ohne dass sie irgendwo auf das Laufwerk geschrieben werden müssen.

Ihr Passwort wird zwar gehasht, wenn es endgültig gespeichert ist, aber bis dahin kann das Tool, in das Sie Ihr Passwort eingeben, natürlich genauso direkt darauf zugreifen wie jedes andere Programm auf Dinge, die Sie beim Lesen von STDIN über Ihre Tastatur eingegeben haben.

Dies ist eine Funktion des PAM-Systems, die im Hintergrund des passwdTools verwendet wird. PAM wird von modernen Linux-Distributionen verwendet.

Genauer gesagt pam_cracklibhandelt es sich um ein Modul für PAM, mit dem Kennwörter abgelehnt werden können, die auf mehreren Schwachstellen beruhen, die sie sehr anfällig machen würden.

Nicht nur zu ähnliche Passwörter können als unsicher eingestuft werden. Der Quellcode enthält verschiedene Beispiele dafür, was überprüft werden kann, z. B. ob ein Passwort ein Palindrom ist oder wie groß der Bearbeitungsabstand zwischen zwei Wörtern ist. Die Idee ist, Passwörter widerstandsfähiger gegen Wörterbuchangriffe zu machen.

Siehe auch die pam_cracklibManpage.

slhck
quelle
Haben Sie Ideen, wie Ihre Erklärung mit den Argumenten in meiner Antwort übereinstimmt? Gibt es zwei verschiedene Ansätze, die von der "passwd" -Anwendung verwendet werden, wenn der Host nicht PAM-fähig ist? PS: Überhaupt keine Kritiker. Ich frage mich nur (als PAM, übrigens, war meine erste Vermutung ... kurz bevor ich den Quellcode griff).
Damiano Verzulli
27
Beunruhigender sind die Firmenkennwortregeln, die Sie benachrichtigen, wenn Sie unter den letzten vier das gleiche oder ein ähnliches Kennwort verwendet haben.
Nick T
4
@NickT Wie ist das (notwendigerweise) störend - konnten sie nicht einfach Ihre letzten 4 Hashes speichern und dann jeden mit Ihrem vorgeschlagenen neuen auf die gleiche Weise wie in dieser Frage vergleichen?
Neminem
1
@neminem "... oder ähnlich"
Nick T
1
@NickT Ah, fair genug, weil Sie in diesem speziellen Fall mit dem "alten Passwort" vergleichen, das der Benutzer eingibt, um das Passwort zu ändern, und nicht mit einem gespeicherten Hash. Sie können jedoch die in einem Kommentar veröffentlichte BWG-Methode verwenden, um zumindest wirklich einfache Änderungen zu überprüfen (Ersetzung eines Zeichens, Hinzufügen / Entfernen eines Zeichens usw.).
Neminem
46

Zumindest in meinem Ubuntu kommt die "zu ähnliche" Nachricht raus wenn: "... mehr als die Hälfte der Zeichen sind verschiedene ..." (Einzelheiten siehe unten). Dank der PAM-Unterstützung, wie in der @ slhck-Antwort deutlich erklärt.

Für andere Plattformen, auf denen PAM nicht verwendet wird, werden die "zu ähnlichen" Meldungen ausgegeben, wenn: "... mehr als die Hälfte der Zeichen unterschiedliche sind ...." (Einzelheiten siehe unten)

Um diese Aussage selbst weiter zu überprüfen, können Sie den Quellcode überprüfen. Hier ist, wie.

Das "passwd" -Programm ist im passwd-Paket enthalten:

verzulli@iMac:~$ which passwd
/usr/bin/passwd
verzulli@iMac:~$ dpkg -S /usr/bin/passwd
passwd: /usr/bin/passwd

Da es sich um Open Source-Technologien handelt, haben wir uneingeschränkten Zugriff auf Quellcode. Es zu bekommen ist so einfach wie:

verzulli@iMac:/usr/local/src/passwd$ apt-get source passwd

Danach ist es einfach, das entsprechende Codefragment zu finden:

verzulli@iMac:/usr/local/src/passwd$ grep -i -r 'too similar' .
[...]
./shadow-4.1.5.1/NEWS:- new password is not "too similar" if it is long enough
./shadow-4.1.5.1/libmisc/obscure.c:     msg = _("too similar");

Eine schnelle Überprüfung der "obscure.c" ergibt dies (ich schneide nur den relevanten Teil des Codes aus und füge ihn ein):

static const char *password_check (
    const char *old,
    const char *new,
    const struct passwd *pwdp)
{
    const char *msg = NULL;
    char *oldmono, *newmono, *wrapped;

    if (strcmp (new, old) == 0) {
            return _("no change");
    }
    [...]
    if (palindrome (oldmono, newmono)) {
            msg = _("a palindrome");
    } else if (strcmp (oldmono, newmono) == 0) {
            msg = _("case changes only");
    } else if (similar (oldmono, newmono)) {
            msg = _("too similar");
    } else if (simple (old, new)) {
            msg = _("too simple");
    } else if (strstr (wrapped, newmono) != NULL) {
            msg = _("rotated");
    } else {
    }
    [...]
    return msg;
}

Jetzt wissen wir also, dass es eine "ähnliche" Funktion gibt, die auf der alten und der neuen basiert und prüft, ob beide ähnlich sind. Hier ist der Ausschnitt:

/*
 * more than half of the characters are different ones.
 */
static bool similar (const char *old, const char *new)
{
    int i, j;

    /*
     * XXX - sometimes this fails when changing from a simple password
     * to a really long one (MD5).  For now, I just return success if
     * the new password is long enough.  Please feel free to suggest
     * something better...  --marekm
     */
    if (strlen (new) >= 8) {
            return false;
    }

    for (i = j = 0; ('\0' != new[i]) && ('\0' != old[i]); i++) {
            if (strchr (new, old[i]) != NULL) {
                    j++;
            }
    }

    if (i >= j * 2) {
            return false;
    }

    return true;
}

Ich habe den C-Code nicht überprüft. Ich habe mich darauf beschränkt, dem Kommentar kurz vor der Funktionsdefinition zu vertrauen :-)


Die Unterscheidung zwischen PAM- und NON-PAM-fähigen Plattformen wird in der Datei "obscure.c" definiert, die wie folgt aufgebaut ist:

#include <config.h>
#ifndef USE_PAM
[...lots of things, including all the above...]
#else                           /* !USE_PAM */
extern int errno;               /* warning: ANSI C forbids an empty source file */
#endif                          /* !USE_PAM */
Damiano Verzulli
quelle
9
Dies ist eine lange Antwort, die nicht direkt die Frage zu beantworten scheint, wie sie mit dem alten Passwort verglichen werden kann, wenn Passwörter als gehasht eingestuft werden.
Jamesdlin
10
@jamesdlin: Wie im Kommentar von Rinzwind zur ursprünglichen Frage angegeben, spielen Hashes in dieser Angelegenheit KEINE Rolle: Wenn Sie den Befehl "passwd" zum Ändern des Kennworts eingeben, müssen Sie sowohl das "alte" als auch das "neue" Kennwort eingeben. Der Code "passwd" hat also überhaupt kein Problem damit, beide Passwörter auf einmal zu vergleichen / zu überprüfen (in übersichtlichen Formen; überhaupt nicht gehasht).
Damiano Verzulli
3
@DamianoVerzulli Trotzdem geht dies nicht wirklich auf die Frage ein. Die Frage lautete nicht "Welchen C-Code verwenden Sie, um festzustellen, ob zwei Zeichenfolgen ähnlich sind?". Das ist genau das gleiche für Passwörter wie für alles andere. Das Interessante an Passwörtern ist, dass sie nie im Klartext gespeichert werden und darum geht es in der Frage. Dies beantwortet "welche Kriterien verwendet werden und wie es in C gemacht wird", aber es ist viel zu lang für "welche Kriterien" und "wie würde ich das in C machen" ist eine SO-Frage, keine SU-Frage.
cpast
7
@DamianoVerzulli Und die Tatsache, dass passwdnach alten und neuen Passwörtern gefragt wird, ist die Antwort . Der Rest dieser Antwort ist irrelevant.
Jamesdlin
3
+1 für und äußerst relevante und interessante Antwort! Es ist schön zu sehen, dass der eigentliche Code, der das Passwort vergleicht, im Klartext und, wie erwartet, nicht im Hash funktioniert.
nico
36

Die Antwort ist viel einfacher als Sie denken. Tatsächlich ist es fast wie Zauberei, denn sobald Sie den Trick erklärt haben, ist er weg:

$ passwd
Current Password:
New Password:
Repeat New Password:

Password changed successfully

Es weiß, dass Ihr neues Passwort ähnlich ist ... Weil Sie das alte in einem Moment zuvor eingegeben haben.

Cort Ammon
quelle
2
"... oder Süßigkeiten."
Nick T
1
Dumme Kaninchen, Trix sind für Kinder!
iAdjunct
1
Was es nicht erklärt, ist, wenn es Ihre letzten n Passwörter kennt :) "Passwort wurde zu kürzlich verwendet", wodurch verhindert wird, dass dieselben wenigen Passwörter in einer Unternehmensumgebung ausgetauscht werden.
Juha Untinen
3
@Juha Untinen: Das stimmt, aber das geht, indem man sich einfach die letzten N Hashes merkt. Es ist einfach, "dasselbe wie das N-te Passwort" zu finden, es ist das " ähnlich wie das N-te Passwort", das schwierig ist. Soweit mir bekannt ist, prüfen diese Systeme nur mit dem letzten Kennwort auf Ähnlichkeit und mit dem letzten N auf Gleichheit. Wenn sie mit dem letzten N auf Ähnlichkeit prüfen, ist das jetzt ein wirklich interessanter Trick, nicht wahr? Ich habe keine Ahnung, wie sie das machen würden.
Cort Ammon
7

Obwohl die anderen Antworten richtig sind, kann es erwähnenswert sein, dass Sie nicht das alte Passwort eingeben müssen, damit dies funktioniert!

Tatsächlich kann man eine Reihe von Passwörtern erstellen, die dem von Ihnen eingegebenen neuen Passwort ähneln, sie hacken und dann prüfen, ob einer dieser Hashes mit dem alten übereinstimmt. Ist dies der Fall, wird das neue Passwort ähnlich wie das alte beurteilt! :)

Ameise
quelle
2
Dies ist in der Tat ein Mittel, um dieses Kunststück zu erreichen (und wird von vielen Websites verwendet), aber das ist in diesem Fall nicht der Fall.
Brian S
Das ist ein toller Trick! Ein bisschen rechenintensiver, aber clever!
Cort Ammon
Sie sollten zumindest eine Schätzung darüber abgeben, wie viele ähnliche Kennwörter generiert werden müssten, um eine aussagekräftige Prüfung durchzuführen, oder eine Verknüpfung zu einer externen Ressource herstellen zu können. Ansonsten ist dies nur eine Idee einer möglichen Alternative, keine begründete Antwort.
Hyde
@hyde das hängt von den Kriterien ab, an die jemand denken kann. Für mich sind Passwörter ähnlich, wenn maximal 3 Zeichen hinzugefügt / entfernt / geändert wurden. Das sind also 62 Hashes für jedes Zeichen (und das ist, wenn wir nur alphanumerische Zeichen verwenden) mal 3 aus der Länge des Passworts ( n), was 62 * (n!)/(6 * (n - 3)!)13540 für ein 12 Zeichen langes Passwort entspricht. Aber wenn jemand über etwas anderes nachdenkt, ist die Gleichung unbrauchbar. Warum also die Mühe machen?
Killah
Dumme Antwort, aber trotzdem eine Einsicht. Warum dumm? 1. Sie müssten eine unvorstellbare Anzahl von Hashes generieren. 2. Ein solches Setup würde die Sicherheit des ursprünglichen Passworts beeinträchtigen. Wenn jemand Hashes aller ähnlichen Passwörter anstatt nur eines Hashes erhalten hätte, hätte er viel einfacher Zeit, sie zu knacken.
Rok Kralj,
5

Ein Aspekt wurde nicht behandelt: Kennwortverlauf. Einige Systeme unterstützen dies. Zu diesem Zweck werden Kennwörter im Verlauf gespeichert und mit dem aktuellen Kennwort verschlüsselt. Wenn Sie Ihr Passwort ändern, wird das "alte" Passwort verwendet, um die Liste zu entschlüsseln und zu überprüfen. Wenn ein neues Passwort festgelegt wird, wird die Liste (erneut) mit einem vom neuen Passwort abgeleiteten Schlüssel verschlüsselt gespeichert.

So remember=Nfunktioniert das in PAM (gespeichert in /etc/security/opasswd). Aber auch Windows und andere Unix-Anbieter bieten ähnliche Funktionen.

eckes
quelle