Os autores deste artigo argumentam contra os mecanismos de criptografia de chave padrão no OpenSSH.Os atacantes usaram recentemente o pacote npm eslint-scope para roubar tokens npm dos diretórios pessoais do usuário. À luz desse evento, começamos a verificar outras vulnerabilidades semelhantes e pensamos em como reduzir os riscos e as consequências de tais incidentes.
A maioria de nós tem uma chave RSA SSH à mão. Essa chave oferece ao proprietário uma variedade de privilégios: como regra, é usada para acessar o ambiente de produção ou no GitHub. Diferentemente dos tokens nmp, as chaves SSH são criptografadas e, portanto, geralmente é aceito que nada de ruim acontecerá, mesmo que caiam nas mãos erradas. Mas é mesmo assim? Vamos descobrir.
user@work /tmp $ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): mykey
...
user@work /tmp $ head -n 5 mykey
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,CB973D5520E952B8D5A6B86716C6223F
+5ZVNE65kl8kwZ808e4+Y7Pr8IFstgoArpZJ/bkOs7rB9eAfYrx2CLBqLATk1RT/
Essa chave é criptografada, conforme indicado por uma das primeiras linhas do arquivo. Além disso, no início, não há chave de codificação MII - base64 usada no RSA. E, claro, a AES chama sua atenção! Está bom né? E CBC, à primeira vista, com um vetor de inicialização aleatória. Não há código de autenticação (MAC). Bem, então, não haverá ataque de preenchimento de oráculo, certo?
Descobrir o que realmente significa o conteúdo do DEK-Info não é tão simples. Uma pesquisa pela palavra-chave “DEK-Info” no repositório openssh-portable mostra apenas exemplos de chaves. Mas o ponto aqui é que a chave AES nada mais é do que um simples hash MD5 (senha || vetor de inicialização [: 8]). E isso é ruim, porque as práticas recomendadas para armazenar senhas dizem que as senhas em sua forma pura, devido à baixa entropia, são um material de criptografia ruim. E para torná-lo melhor, você precisa de uma função cara como o Argon2. Mas o MD5, ao contrário do último, é fácil de calcular.
O único ponto positivo nesse esquema é que o salt é colocado após a senha, portanto, não funcionará para calcular o estado intermediário MD5 (IV [8:]) e encontrar as senhas com base nele. Mas isso é pouco consolador, especialmente em uma época em que máquinas que fazem bilhões de chamadas MD5 por segundo estão disponíveis para nós - mais do que as senhas podem oferecer.
Você pode se perguntar como o OpenSSH viveu para ver isso. Infelizmente, a resposta é simples: a ferramenta de linha de comando do OpenSSL inicialmente usou esse esquema por padrão e simplesmente se tornou a norma.
No final, torna-se verdade que as chaves criptografadas com senha padrão não são melhores que as chaves não criptografadas comuns, simplesmente porque o mecanismo de criptografia é ineficaz. No entanto, falaríamos ainda mais ousadamente - eles são piores. E é fácil argumentar.
É improvável que muitas pessoas usem um gerenciador de senhas para armazenar a senha da chave SSH. Em vez disso, o usuário simplesmente se lembrará. E, como essa é uma das combinações memorizadas, é provável que o usuário já a tenha usado em outro lugar. Talvez até corresponda à senha do usuário do dispositivo. É bem possível adivinhar (sua função formativa é muito confiável) e, se a senha se tornar conhecida, você provavelmente poderá verificá-la com a chave pública.
Não há reclamações sobre o par de chaves RSA em si: a única questão é os métodos de criptografia simétrica da chave privada. É impossível realizar o ataque descrito acima, conhecendo apenas a chave pública.
Como posso resolver a situação?
O OpenSSH fornece um novo formato de chave para usar. Por novo entende-se introduzido em 2013. Esse formato usa bcrypt_pbkdf, que é essencialmente um bcrypt de complexidade fixa implementado sob o padrão PBKDF2.
Convenientemente, você recebe automaticamente uma chave em um novo formato ao gerar chaves Ed25519, porque o antigo formato de chave SSH não suporta tipos mais novos de chaves. Isso é bastante estranho, porque, na verdade, não precisamos do formato da chave para determinar como a serialização do Ed25519 funciona, pois o próprio Ed25519 define o trabalho de serialização. Mas se você realmente precisa de uma boa função formativa, não pode se incomodar com essas ninharias. Como resultado, uma das respostas é
ssh-keygen -t ed25519 .
Se, por motivos de compatibilidade, você precisar seguir o RSA, poderá usar ssh-keygen -o. Assim, um novo formato pode ser obtido mesmo para tipos antigos de chaves. Você pode atualizar chaves antigas com o comando
ssh-keygen -p -o -f nome da chave . Se suas chaves residem no Yubikey ou nos cartões inteligentes, essas alterações já foram levadas em consideração.
De uma forma ou de outra, lutamos por uma saída mais ideal. Por um lado, há um bom exemplo de aws-vault, no qual as informações de credenciais foram movidas do disco para o chaveiro. Há outra abordagem: mover o desenvolvimento para ambientes compartilhados. Por fim, a maioria das startups deve considerar abandonar o armazenamento de longo prazo de chaves SSH e mudar para um centro de certificação SSH com um tempo limitado de armazenamento de chaves juntamente com um sistema de logon único. Infelizmente, no caso do GitHub, essa abordagem não é possível.
PS É difícil verificar essas informações em uma fonte autorizada, mas se a memória nos servir bem, o parâmetro versionado nas chaves privadas do formato OpenSSH PEM afeta apenas o método de criptografia. No entanto, isso não tem nenhum papel: o problema é a função de formação de chave, e achamos que esse é outro argumento contra discutir os protocolos em partes. Haverá um post separado sobre esse tópico em nosso blog.
E finalmente - um
link para a chave completa. Este é o caso de você estar pronto para hackear qualquer coisa hoje.
