
O significado do item de teste é bastante simples. É fornecido um despejo de tráfego, que contém uma chave de criptografia, algum lixo e um sinalizador criptografado. Precisamos extraí-los e decifrar a bandeira. Também é mostrado o comando OpenSSL com o qual este sinalizador foi criptografado. O tráfego é bem interessante, mas depois de 10 linhas de código python, eu tinha uma chave de criptografia, lixo e uma bandeira criptografada na minha frente. Ao que parece, o que poderia dar errado?
A atribuição diz que o sinalizador foi criptografado com aproximadamente o seguinte comando (omiti alguns parâmetros insignificantes e alterei o algoritmo de criptografia).
echo "FLAG_xxxx…xxxxxx" | openssl enc -e -base64 -aes-256-cbc -nosalt -k $password
Inseri os parâmetros obtidos do tráfego no comando, iniciei e ... peguei o lixo! Eu tentei novamente. Lixo novamente. Tentei reconstruir o tráfego de maneiras diferentes. Não, aparentemente, o tráfego só pode ser coletado de forma inequívoca. Mas a saída da criptografia é lixo novamente !!! Ao mesmo tempo, o OpenSSL honestamente avisa que obter uma chave de uma senha em uma passagem é uma má ideia ...
echo "ENCRYPTED_FLAG" | openssl enc -d -base64 -aes-256-cbc -nosalt -k $key
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
O dia seguinte foi gasto tentando quebrar essa loucura. Eu razoavelmente raciocinei que aparentemente eu isolei incorretamente o "lixo" especificado nas condições e escrevi várias opções para dividir a string resultante em "senha" e "sinalizador criptografado" para "força bruta" subsequente. Não ajudou ... Comecei a entender profundamente cada um dos parâmetros.
Como sabemos, o AES requer uma chave de criptografia e IV (vetor de inicialização) para funcionar. O parâmetro -k nos permite usar uma frase de texto, da qual o próprio OpenSSL obtém a chave necessária e IV. Você pode vê-los usando o parâmetro -p.
echo "FLAG_123" | openssl enc -e -base64 -aes-256-cbc -nosalt -p -k "password"
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
key=5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8
iv =3B02902846FFD32E92FF168B3F5D16B0
C11kA+GcqkU4ocOvZAVr3g==
Esse conhecimento também não me deu nada. Mesmo assim, decidi voltar à ideia mais maluca que me ocorreu. Ou seja: o problema não é comigo, mas algo mudou no OpenSSL ... O
tráfego era de 2016, então peguei o Ubuntu 14.04 e, sem muita esperança de sucesso, apenas inseri os dados iniciais nele. E de repente, em vez de lixo, ganhei uma BANDEIRA! A noite deixou de ser lânguida ... Além disso, o mesmo comando com a mesma senha e o parâmetro -p produzia chaves de criptografia completamente diferentes e IV!
NOVO SISTEMA (openssl 1.1.1h)
echo "FLAG_123" | openssl enc -e -base64 -aes-256-cbc -nosalt -p -k "password"
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
key=5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8
iv =3B02902846FFD32E92FF168B3F5D16B0
C11kA+GcqkU4ocOvZAVr3g==
SISTEMA ANTIGO (openssl 1.0.1f)
echo "FLAG_123" | openssl enc -e -base64 -aes-256-cbc -nosalt -p -k "password"
key=5F4DCC3B5AA765D61D8327DEB882CF992B95990A9151374ABD8FF8C5A7A0FE08
iv =B7B4372CDFBCB3D16A2631B59B509E94
R3N+5v3zOz9QcNt08cwqcA==
Ficou claro que os temores se confirmaram. O algoritmo para gerar chave e IV a partir de uma frase-senha mudou, o que quebrou completamente a capacidade de resolver CTF de frente em versões modernas do OpenSSL. No processo de busca pelas nuances da implementação, encontrei um trabalho muito interessante " Análise de criptografia OpenSSL baseada em senha do protocolo de derivação de chave " e tudo se encaixou. Resumindo, a versão 1.1.0 adicionou um novo protocolo para gerar chaves a partir de uma senha PBKDF2, mas mais importante, o antigo algoritmo PBKDF1 mudou o algoritmo de hash padrão de MD5 para SHA-256! Portanto, a mesma senha produz Chave e IV diferentes. Para descriptografar criptografados anteriormente, em versões mais recentes, você precisa usar o parâmetro -md md5 .
“-Md messagedigest: especifica o resumo da mensagem usado para derivação da chave de md2, md5, sha ou sha1 ”
Depois de adicionar este parâmetro, tornou-se possível obter o sinalizador no novo OpenSSL. Não sei se essa "nuance" foi realmente levada em consideração pelos desenvolvedores da tarefa de teste ou eles simplesmente não a testaram em sistemas modernos, mas o fato é que tive que mergulhar profundamente em algumas das sutilezas do OpenSSL.
PS Através dos meus conhecidos, já informei os desenvolvedores do teste de teste sobre o problema que encontrei, caso contrário, eles ficam repentinamente muito surpresos que essas pessoas não os procurem ...