Como o Linux sabe que a nova senha é semelhante à anterior?

140

Algumas vezes tentei alterar uma senha de usuário em várias máquinas Linux e, quando a nova senha era semelhante à antiga, o sistema operacional reclamou que elas eram muito semelhantes.

Sempre me perguntei: como o sistema sabe disso? Eu pensei que a senha é salva como um hash. Isso significa que, quando o sistema é capaz de comparar a nova senha por semelhança, a antiga é realmente salva como texto simples?

    
por Arkonix 27.12.2014 / 18:22

5 respostas

155

Como você precisa fornecer a antiga e a nova senha ao usar passwd , eles podem ser facilmente comparados em texto simples, na memória, sem gravá-los em algum lugar da unidade.

Na verdade, sua senha é criptografada quando é finalmente armazenada, mas até que isso aconteça, a ferramenta onde você digita sua senha pode acessá-la diretamente, como qualquer outro programa pode acessar as coisas que você digitou no teclado enquanto lia de STDIN.

Este é um recurso do sistema PAM que é usado no plano de fundo da ferramenta passwd . O PAM é usado pelas distribuições modernas do Linux.

Mais especificamente, pam_cracklib é um módulo para o PAM que permite rejeitar senhas com base em vários pontos fracos que os tornariam muito vulneráveis.

Não são apenas senhas que são muito parecidas e podem ser consideradas inseguras. O código-fonte tem vários exemplos do que pode ser verificado, por exemplo se uma senha é um palíndromo ou qual a distância de edição entre duas palavras. A ideia é tornar as senhas mais resistentes aos ataques de dicionário.

Veja também a% man_de% manpage.

    
por 27.12.2014 / 20:27
46

Pelo menos no meu Ubuntu, as mensagens "muito semelhantes" saem de quando: "... mais da metade dos caracteres são diferentes ..." (veja abaixo para detalhes). graças ao suporte do PAM, como claramente explicado na resposta @slhck.

Para outra plataforma, onde o PAM não é usado, as mensagens "muito semelhantes" são exibidas quando: "... mais da metade dos caracteres são diferentes ..." abaixo para detalhes)

Para verificar essa declaração por conta própria, é possível verificar o código-fonte. Aqui está como.

O programa "passwd" está incluído no pacote passwd:

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

Como estamos lidando com tecnologias Open Source, temos acesso irrestrito ao código-fonte. Obtê-lo é tão simples como:

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

Depois, é fácil encontrar o fragmento relevante do código:

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

Uma verificação rápida para o "obscure.c" mostra isso (estou recortando e colando apenas a parte relevante do código):

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

Então, agora, sabemos que há uma função "similar" que, com base na antiga e na nova, verifica se ambas são semelhantes. Aqui está o trecho:

/*
 * 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; ('
#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 */
' != new[i]) && ('
verzulli@iMac:~$ which passwd
/usr/bin/passwd
verzulli@iMac:~$ dpkg -S /usr/bin/passwd
passwd: /usr/bin/passwd
' != old[i]); i++) { if (strchr (new, old[i]) != NULL) { j++; } } if (i >= j * 2) { return false; } return true; }

Eu não revi o código em C. Limitei-me a confiar no comentário pouco antes da definição da função: -)

A diferenciação entre as plataformas que reconhecem o PAM e o NÃO-PAM é definida no arquivo "obscure.c" que é estruturado como:

verzulli@iMac:/usr/local/src/passwd$ apt-get source passwd
    
por 27.12.2014 / 21:02
37

A resposta é muito mais simples do que você pensa. Na verdade, quase se qualifica como mágica, porque uma vez que você explique o truque, ele se foi:

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

Password changed successfully

Ele sabe que sua nova senha é semelhante ... Porque você digitou a antiga em apenas um momento antes.

    
por 28.12.2014 / 19:14
8

Embora as outras respostas estejam certas, pode valer a pena mencionar que você não precisa fornecer a senha antiga para que isso funcione!

Na verdade, é possível gerar um monte de senhas semelhantes à nova senha que você forneceu, agrupá-las e, em seguida, verificar se algum desses hashes corresponde ao antigo. Se este for o caso, então a nova senha é julgada semelhante à antiga! :)

    
por 29.12.2014 / 14:41
4

Um aspecto não foi coberto: histórico de senhas. Alguns sistemas suportam isso. Para isso, mantém um histórico de senhas e as criptografa com a senha atual. Quando você altera sua senha, ela usa a senha "antiga" para descriptografar a lista e verificar. E quando define uma nova senha, ela salva a lista (novamente) criptografada com uma chave derivada da nova senha.

É assim que remember=N funciona no PAM (armazenado em /etc/security/opasswd ). Mas também o Windows e outros fornecedores Unix oferecem funções semelhantes.

    
por 02.01.2015 / 12:06