Skąd Linux wie, że nowe hasło jest podobne do poprzedniego?

145

Kilka razy próbowałem zmienić hasło użytkownika na różnych komputerach z systemem Linux, a gdy nowe hasło było podobne do starego, system operacyjny narzekał, że są one zbyt podobne.

Zawsze zastanawiałem się, skąd system to wie? Myślałem, że hasło jest zapisane jako skrót. Czy to oznacza, że ​​kiedy system jest w stanie porównać nowe hasło podobieństwa, stare jest faktycznie zapisywane jako zwykły tekst?

Arkonix
źródło
30
1st off: zwykły tekst? Nie. Jeśli (!) Uratowałeś, zapisujesz skrót i porównujesz skróty. W Linuksie sprawdza bieżące hasło za pomocą nowego hasła. ZARÓWNO są dostarczane przez użytkownika podczas zmiany hasła.
Rinzwind
42
@Rinzwind Ale porównywanie skrótów nie zadziała, ponieważ różnica jednej postaci powinna spowodować zupełnie inny skrót
slhck
17
Zobacz także Czy Facebook przechowuje hasła w postaci zwykłego tekstu? w sprawie bezpieczeństwa informacji dla innych sposobów wykrywania podobieństwa, biorąc pod uwagę tylko skrót starego hasła i tekst jawny nowego hasła (brak tekstu jawnego dla starego).
Bob
21
Możesz faktycznie przetestować podobieństwo między hashowanym starym hasłem a nowym hasłem w postaci zwykłego tekstu. Po prostu wygeneruj listę haseł podobnych do nowego, hasz je wszystkie i porównaj uzyskane hasze ze starym hasłem. Jeśli jakikolwiek pasuje, to jest podobny.
BWG
2
@BWG: To niewielkie uproszczenie - obecne schematy haszowania zasłaniają hash, więc najpierw musisz wyodrębnić sól ze starego hasha i upewnij się, że używasz tej soli do swoich podobnych do nowych haseł. (Zwracam na to uwagę, ponieważ możliwe jest, że API nie ujawniłoby sposobu na wymuszenie określonej soli.)
Ulrich Schwarz

Odpowiedzi:

156

Ponieważ podczas używania musisz podać zarówno stare, jak i nowe hasło passwd, można je łatwo porównać w postaci zwykłego tekstu, w pamięci, bez zapisywania ich gdzieś na dysku.

Rzeczywiście, twoje hasło jest zakodowane, kiedy w końcu jest przechowywane, ale dopóki tak się nie stanie, narzędzie, w którym wpisujesz hasło, może oczywiście po prostu uzyskać do niego bezpośredni dostęp, tak jak każdy inny program może uzyskać dostęp do rzeczy, które wprowadziłeś na klawiaturze podczas odczytu ze STDIN.

Jest to cecha systemu PAM, który jest wykorzystywany w tle passwdnarzędzia. PAM jest używany przez współczesne dystrybucje Linuksa.

Mówiąc dokładniej, pam_cracklibjest to moduł dla PAM, który pozwala na odrzucanie haseł na podstawie kilku słabości, które czyniłyby je bardzo podatnymi na atak.

Nie tylko hasła, które są zbyt podobne, można uznać za niepewne. Kod źródłowy ma różne przykłady tego, co można sprawdzić, na przykład, czy hasło jest palindrom lub jaka jest odległość między dwoma edycja słów. Chodzi o to, aby hasła były bardziej odporne na ataki słownikowe.

Zobacz także stronę pam_cracklibpodręcznika.

slhck
źródło
Czy masz pomysły na „jak” twoje wyjaśnienie pasuje do argumentów zgłoszonych w mojej odpowiedzi? Czy istnieją dwa różne podejścia przyjęte przez aplikację „passwd”, gdy host nie obsługuje PAM? PS: Brak krytyków. Zastanawiam się (jako że PAM, BTW, był moim pierwszym przypuszczeniem ... tuż przed grepowaniem kodu źródłowego).
Damiano Verzulli
27
Bardziej niepokojące są reguły haseł firmowych, które ostrzegają, jeśli użyjesz tego samego lub podobnego hasła w jednym z czterech ostatnich.
Nick T
4
@NickT Jak to (niekoniecznie) niepokojące - czy nie mogliby po prostu zapisać 4 ostatnich skrótów, a następnie porównać każdy z zaproponowanych nowych skrótów w taki sam sposób, jak to pytanie?
neminem
1
@neminem „... lub podobny”
Nick T
1
@NickT Ah, w porządku, ponieważ w tym konkretnym przypadku porównujesz z „starym hasłem” wprowadzonym przez użytkownika w celu zmiany hasła, a nie z zapisanym hashem. Mimo to mógłby hipotetycznie użyć metody BWG zamieszczonych w komentarzu, co najmniej sprawdzenie naprawdę prostych zmian (podstawienie jednej postaci, jedna postać dodane / usunięte, itp).
neminem
46

Przynajmniej w moim Ubuntu wychodzą „zbyt podobne” wiadomości kiedy: „... więcej niż połowa znaków to różne…” (szczegóły poniżej). dzięki wsparciu PAM, jak jasno wyjaśniono w odpowiedzi @slhck.

Na innej platformie, na której nie jest używany PAM, pojawiają się komunikaty „zbyt podobne”, gdy: „... więcej niż połowa znaków to różne ...” (szczegóły poniżej)

Aby dalej samodzielnie sprawdzić to oświadczenie, można sprawdzić kod źródłowy. Oto jak.

Program „passwd” znajduje się w pakiecie passwd:

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

Ponieważ mamy do czynienia z technologiami Open Source, mamy nieograniczony dostęp do kodu źródłowego. Uzyskanie jest tak proste, jak:

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

Następnie łatwo jest znaleźć odpowiedni fragment kodu:

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");

Szybka kontrola do „obscure.c” daje to (wycinam i wklejam tylko odpowiedni fragment kodu):

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;
}

Teraz wiemy, że istnieje „podobna” funkcja, która w oparciu o starą i nową sprawdza, czy oba są podobne. Oto fragment:

/*
 * 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;
}

Nie sprawdziłem kodu C. Ograniczałem się do zaufania komentarzowi tuż przed definicją funkcji :-)


Różnice między platformami PAM i NON-PAM są zdefiniowane w pliku „obscure.c”, który ma następującą strukturę:

#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
źródło
9
To długa odpowiedź, która nie wydaje się bezpośrednio odpowiadać na pytanie, jak można ją porównać ze starym hasłem, gdy hasła są zakodowane.
jamesdlin
10
@jamesdlin: jak stwierdzono w komentarzu Rinzwind do pierwotnego pytania, skróty NIE odgrywają żadnej roli w tej kwestii: po wydaniu polecenia „passwd” w celu zmiany hasła należy podać zarówno „stare”, jak i „nowe” hasło. Tak więc kod „passwd” nie ma żadnego problemu z porównywaniem / sprawdzaniem obu haseł naraz (w przejrzystych formach; w ogóle nie jest mieszany).
Damiano Verzulli
3
@DamianoVerzulli Niemniej jednak tak naprawdę nie dotyczy to pytania. Pytanie nie brzmiało: „jakiego kodu C używasz, aby stwierdzić, czy dwa ciągi są podobne;” to jest dokładnie to samo dla haseł, jak dla czegokolwiek innego. Rzecz o hasłach , które sprawia, że interesujące jest to, że nigdy nie są przechowywane w postaci zwykłego tekstu, a to, co pytanie pyta o. Odpowiada to „jakie kryteria są stosowane i jak to się robi w C”, ale dla „jakie kryteria” i „jak miałbym to zrobić w C” jest to zbyt długo, jest to pytanie SO, a nie SU.
cpast
7
@DamianoVerzulli A fakt, że passwdprosi o starych i nowych haseł jest odpowiedzią . Reszta tej odpowiedzi jest nieistotna.
jamesdlin
3
+1 za niezwykle trafną i interesującą odpowiedź! Miło jest widzieć, że rzeczywiste hasło porównujące kod faktycznie działa na zwykłym tekście i, zgodnie z oczekiwaniami, nie na haszu.
nico
36

Odpowiedź jest o wiele prostsza niż myślisz. W rzeczywistości prawie kwalifikuje się jako magia, ponieważ kiedy wyjaśnisz sztuczkę, zniknie:

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

Password changed successfully

Wie, że twoje nowe hasło jest podobne ... Ponieważ stary wpisałeś już przed chwilą.

Cort Ammon
źródło
2
„... lub cukierki”.
Nick T
1
Głupiutki królik, trix są dla dzieci!
iDodatkowy
1
To, czego nie tłumaczy, to to, że zna twoje poprzednie n haseł :) „Hasło zostało użyte zbyt niedawno”, co zapobiega zamianie tych samych haseł w środowisku korporacyjnym.
Juha Untinen,
3
@Juha Untinen: To prawda, ale można sobie z tym poradzić, zapamiętując ostatnie N skrótów. Złapanie „tego samego co N-te hasło” jest łatwe, jego „ podobne do N-tego hasła” jest trudne. O ile mi wiadomo, systemy te sprawdzają tylko podobieństwo z ostatnim hasłem i identyczność z ostatnim N. Jeśli sprawdzą podobieństwo z ostatnim N ... to naprawdę ciekawa sztuczka, prawda! Nie mam pojęcia, jak by to zrobili.
Cort Ammon
7

Chociaż pozostałe odpowiedzi są prawidłowe, warto wspomnieć, że nie trzeba podawać starego hasła, aby to zadziałało!

W rzeczywistości można wygenerować kilka haseł podobnych do nowego hasła, które podałeś, haszować je, a następnie sprawdzić, czy któryś z tych skrótów pasuje do starego. W takim przypadku nowe hasło zostanie uznane za podobne do starego! :)

Mrówka
źródło
2
Chociaż jest to rzeczywiście sposób na osiągnięcie tego wyczynu (i jest wykorzystywany przez wiele stron internetowych), nie o to chodzi w tym przypadku.
Brian S
To fajna sztuczka! Trochę bardziej obliczeniowo, ale sprytnie!
Cort Ammon
Powinieneś przynajmniej oszacować, ile podobnych haseł musiałoby zostać wygenerowanych, aby uzyskać znaczącą kontrolę, lub link do zewnętrznego źródła. W przeciwnym razie jest to tylko pomysł możliwej alternatywy, a nie uzasadniona odpowiedź.
hyde
@hyde, który zależy od kryteriów, które ktoś może pomyśleć. Dla mnie hasła są podobne, jeśli dodano / usunięto / zmodyfikowano maksymalnie 3 znaki. To 62 skróty dla każdego znaku (i jeśli używamy tylko alfanumerycznych) razy kombinacja 3 z długości hasła ( n) 62 * (n!)/(6 * (n - 3)!), co równa się 13540 dla hasła o długości 12 znaków. Ale jeśli ktoś myśli o czymś innym, równanie jest bezużyteczne, więc po co się tym przejmować?
Killah
Głupia odpowiedź, ale jednak wgląd. Dlaczego głupi? 1. Musisz wygenerować niewyobrażalną liczbę skrótów. 2. Taka konfiguracja osłabiłaby bezpieczeństwo oryginalnego hasła. Gdyby ktoś uzyskał skróty wszystkich podobnych haseł zamiast jednego skrótu, miałby znacznie łatwiejszy czas na jego złamanie.
Rok Kralj
5

Nie uwzględniono jednego aspektu: historii haseł. Niektóre systemy to obsługują. W tym celu przechowuje historię haseł i szyfruje je przy użyciu bieżącego hasła. Po zmianie hasła używane jest „stare” hasło do odszyfrowania listy i weryfikacji. A kiedy ustawia nowe hasło, zapisuje listę (ponownie) zaszyfrowaną kluczem pochodzącym z nowego hasła.

Tak remember=Ndziała PAM (przechowywane w /etc/security/opasswd). Ale także Windows i inni dostawcy Uniksa oferują podobne funkcje.

eckes
źródło