Segurança séria: GnuTLS segue OpenSSL, corrige bug de ataque de temporização

Segurança séria: GnuTLS segue OpenSSL, corrige bug de ataque de temporização

Nó Fonte: 1956368

Na semana passada, escrevemos sobre um monte de erros de gerenciamento de memória que foram corrigidos na última atualização de segurança da popular biblioteca de criptografia OpenSSL.

Junto com esses bugs de memória, também relatamos um bug chamado CVE-2022-4304: Timing Oracle na descriptografia RSA.

Nesse bug, disparar a mesma mensagem criptografada repetidamente em um servidor, mas modificar o preenchimento no final dos dados para torná-los inválidos e, assim, provocar algum tipo de comportamento imprevisível…

…não levaria um tempo consistente, supondo que você estivesse perto do alvo na rede que poderia adivinhar com segurança quanto tempo levaria a parte de transferência de dados do processo.

Nem todos os dados são processados ​​igualmente

Se você disparar uma solicitação, cronometrar quanto tempo a resposta leva e subtrair o tempo consumido no envio e recebimento de baixo nível dos dados da rede, você saberá quanto tempo o servidor levou para fazer sua computação interna para processar a solicitação .

Mesmo que você não tenha certeza de quanto tempo é usado na rede, você pode procurar variações nos tempos de ida e volta disparando várias solicitações e coletando várias amostras.

Se a rede for confiável o suficiente para assumir que a sobrecarga de rede é amplamente constante, você poderá usar métodos estatísticos para inferir que tipo de modificação de dados causa que tipo de atraso de processamento extra.

A partir disso, você pode inferir algo sobre a estrutura, ou mesmo o conteúdo, dos dados originais não criptografados que deveriam ser mantidos em segredo dentro de cada solicitação repetida.

Mesmo que você consiga extrair apenas um byte de texto simples, bem, isso não deveria acontecer.

Assim chamado ataques de tempo desse tipo são sempre problemáticos, mesmo que você precise enviar milhões de pacotes falsos e cronometrá-los para ter alguma chance de recuperar apenas um byte de dados de texto simples…

…porque as redes são mais rápidas, mais previsíveis e capazes de lidar com muito mais carga do que há alguns anos.

Você pode pensar que milhões de pacotes traiçoeiros enviados por spam para você, digamos, na próxima hora se destacariam como um polegar de classificação.

Mas “um milhão de pacotes por hora a mais ou a menos do que o normal” simplesmente não é mais uma variação particularmente grande.

Bug “oráculo” semelhante no GnuTLS

Bem, a mesma pessoa que relatou o bug de sincronização do bug corrigido no OpenSSL também relatou um bug semelhante no GnuTLS mais ou menos ao mesmo tempo.

Este tem o identificador de bug CVE-2023-0361.

Embora o GnuTLS não seja tão popular ou amplamente usado quanto o OpenSSL, você provavelmente tem vários programas em sua propriedade de TI, ou mesmo em seu próprio computador, que o utilizam ou incluem, possivelmente incluindo FFmpeg, GnuPG, Mplayer, QEMU , Rdesktop, Samba, Wget e Wireshark.

Ironicamente, a falha de tempo no GnuTLS apareceu no código que deveria registrar erros de ataque de tempo em primeiro lugar.

Como você pode ver na diferença de código (diff) abaixo, o programador estava ciente de que qualquer condicional (if ... then) usada para verificar e lidar com um erro de descriptografia pode produzir variações de tempo, porque as CPUs geralmente levam uma quantidade de tempo diferente, dependendo de como seu código segue após uma instrução de “ramificação”.

(Isso é especialmente verdadeiro para uma ramificação que geralmente vai para um lado e raramente para o outro, porque as CPUs tendem a lembrar, ou armazenar em cache, o código que é executado repetidamente para melhorar o desempenho, tornando o código executado com pouca frequência detectavelmente mais lento.)

Diferença de código de gnutls-3.7.8/lib/auth/rsa.c contra 3.7.9

Mas o programador ainda queria registrar que um ataque pode estar acontecendo, o que acontece se o if (ok) o teste acima falha e ramifica para o else { ... } seção.

Neste ponto, o código chama o _gnutls_debug_log() função, que pode demorar um pouco para fazer o seu trabalho.

Portanto, o codificador inseriu uma chamada deliberada para _gnutls_no_log() no then { ... } parte do código, que finge registrar um “ataque” quando não há um, para tentar igualar o tempo que o código gasta em qualquer direção que o if (ok) instrução de ramificação pode levar.

Aparentemente, no entanto, os dois caminhos de código não eram suficientemente semelhantes no tempo que usaram (ou talvez o _gnutls_debug_log() função por conta própria era insuficientemente consistente para lidar com diferentes tipos de erro), e um invasor poderia começar a distinguir indicadores de descriptografia após um milhão ou mais de tentativas.

O que fazer?

Se você é um programador: a correção do bug aqui foi simples e seguiu o princípio “menos é mais”.

O código em rosa acima, que foi considerado não fornecer dados de detecção de ataque terrivelmente úteis de qualquer maneira, foi simplesmente excluído, com base no fato de que o código que não está lá não pode ser compilado por engano, independentemente de suas configurações de compilação…

…e o código que não é compilado nunca pode ser executado, seja por acidente ou projeto.

Se você for um usuário GnuTLS: a versão lançada recentemente 3.7.9 e o “novo sabor do produto” 3.8.0 tem esta correção, juntamente com várias outras, incluídas.

Se você estiver executando uma distribuição Linux, verifique se há atualizações para qualquer versão de biblioteca compartilhada gerenciada centralmente do GnuTLS que você possui, bem como para aplicativos que trazem sua própria versão.

No Linux, procure por arquivos com o nome libgnutls*.so para encontrar quaisquer bibliotecas compartilhadas por aí e procure por gnutls-cli para localizar quaisquer cópias do utilitário de linha de comando que geralmente está incluído na biblioteca.

Você pode correr gnutls-cli -vv para descobrir qual versão do libgnutls está dinamicamente vinculado a:

 $ gnutls-cli -vv gnutls-cli 3.7.9 <-- minha distro Linux recebeu a atualização na última sexta-feira (2023-02-10)

Carimbo de hora:

Mais de Segurança nua