Foi identificada uma vulnerabilidade crítica (CVE-2021-43527) no conjunto de bibliotecas criptográficas NSS (Network Security Services), desenvolvidas pela Mozilla, que pode permitir a execução de código por um invasor ao processar assinaturas digitais DSA ou RSA-PSS codificadas usando o método DER (Distinguished Encoding Rules). A questão, codinome BigSig, foi corrigida nas versões NSS 3.73 e NSS ESR 3.68.1. Atualizações de pacotes estão disponíveis para distribuições como Debian, RHEL, Ubuntu, SUSE, Arch Linux, Gentoo e FreeBSD. Atualizações para Fedora ainda não estão disponíveis.
O problema se manifesta em aplicativos que utilizam o NSS para processar assinaturas digitais CMS, S/MIME, PKCS #7 e PKCS #12, ou ao verificar certificados em implementações TLS, X.509, OCSP e CRL. A vulnerabilidade pode surgir em diversos aplicativos cliente e servidor que suportam TLS, DTLS e S/MIME, bem como em clientes de e-mail e visualizadores de PDF que utilizam a chamada NSS CERT_VerifyCertificate() para verificar assinaturas digitais.
Como exemplo de aplicativos vulneráveis, citam-se LibreOffice, Evolution e Evince. Potencialmente, o problema também pode afetar projetos como Pidgin, Apache OpenOffice, Suricata, Curl, Chrony, Red Hat Directory Server, Red Hat Certificate System, mod_nss para o servidor http Apache, Oracle Communications Messaging Server e Oracle Directory Server Enterprise Edition. A vulnerabilidade, no entanto, não se manifesta em Firefox, Thunderbird e Tor Browser, que utilizam uma biblioteca separada, mozilla::pkix, para verificação, também incluída no NSS. Navegadores baseados em Chromium não estão vulneráveis, a menos que tenham sido especificamente compilados com NSS; eles usaram NSS até 2015, mas foram então migrados para BoringSSL.
A vulnerabilidade é causada por um erro no código de verificação de certificados na função vfy_CreateContext no arquivo secvfy.c. O erro se manifesta tanto ao ler o certificado do cliente do servidor quanto ao processar servidor certificados de clientes. Durante a verificação da assinatura digital, que é codificada pelo método DER, o NSS decode a assinatura em um buffer de tamanho fixo, e passa esse buffer para o módulo PKCS #11. Durante o processamento adicional, para assinaturas DSA e RSA-PSS, o tamanho não é verificado corretamente, o que resulta em um estouro de buffer reservado para a estrutura VFYContextStr, se o tamanho da assinatura digital exceder 16384 bits (o buffer destina-se a 2048 bytes, mas não há verificação de que a assinatura pode ser maior).
O código contendo a vulnerabilidade é rastreado desde 2003, mas não representava uma ameaça até a refatoração realizada em 2012. Em 2017, durante a implementação do suporte a RSA-PSS, foi cometida a mesma falha. Para realizar o ataque, não é necessária a geração intensiva de certas chaves para obter os dados necessários, pois o estouro ocorre na fase anterior à verificação da validade da assinatura digital. A parte dos dados que ultrapassa os limites é gravada em uma área de memória que contém ponteiros para funções, facilitando a criação de exploits funcionais.
A vulnerabilidade foi descoberta por pesquisadores do Google Project Zero durante experimentos com novos métodos de fuzzing e é uma boa demonstração de como vulnerabilidades triviais podem permanecer despercebidas por longos períodos em um projeto amplamente testado e conhecido:
- O código NSS é mantido por uma equipe experiente responsável pela segurança, que utiliza métodos modernos de teste e análise de erros. Existem vários programas que oferecem recompensas substanciais por descobrir vulnerabilidades no NSS.
- O NSS foi um dos primeiros projetos a se unir à iniciativa Google oss-fuzz e também foi testado no sistema de fuzzing da Mozilla, desenvolvido com base no libFuzzer.
- O código da biblioteca foi verificado várias vezes em diferentes analisadores estáticos, incluindo a partir de 2008, quando foi rastreado pelo serviço Coverity.
- Até 2015, o NSS era usado no Google Chrome e, independentemente da Mozilla, era verificado pela equipe do Google (a partir de 2015, o Chrome mudou para BoringSSL, mas o suporte ao port baseado no NSS permanece).
Os principais problemas que mantiveram a questão não detectada por tanto tempo foram:
- A biblioteca NSS é modular e o fuzzing não foi realizado como um todo, mas em nível de componentes individuais. Por exemplo, o código de decodificação DER e o processamento de certificados foram testados separadamente — durante o fuzzing, um certificado que poderia levar à manifestação da vulnerabilidade em questão poderia ser gerado, mas sua verificação não chegava ao código de verificação e o problema não se tornava evidente.
- Nos testes de fuzzing, foram impostos restrições rigorosas ao tamanho da saída (10000 bytes), enquanto não havia tais limitações no NSS (muitas estruturas normalmente podiam ter mais de 10000 bytes, portanto, era necessário um maior volume de dados de entrada para identificar problemas). Para uma verificação completa, o limite deveria ser de 224-1 bytes (16 MB), correspondente ao tamanho máximo de um certificado permitido no TLS.
- Representação incorreta da cobertura de código pelos testes de fuzzing. O código vulnerável foi testado ativamente, mas utilizando fuzzer que não conseguiam gerar os dados de entrada necessários. Por exemplo, o fuzzer tls_server_target utilizou um conjunto predefinido de certificados prontos, limitando a verificação do código de verificação do certificado apenas a mensagens TLS e mudanças de estado do protocolo.
Fonte: opennet.ru
