
CVE-2020-16899 - Lógica e Regra de Detecção de Vulnerabilidade TCP/IP do Microsoft Windows
Em 13 de outubro, a Microsoft anunciou uma vulnerabilidade crítica na pilha IPv6 do Windows, que permite que um invasor envie pacotes maliciosamente criados que resultam em um BSOD imediato (Tela Azul da Morte) nas versões mais recentes do Windows 10 e do Windows Server 2019. Embora esta vulnerabilidade não pareça conceder execução de código a um invasor, ela poderia ser usada para realizar ataques de negação de serviço em massa contra versões vulneráveis do Windows. A lógica de detecção para a versão RCE de maior impacto desta vulnerabilidade pode ser encontrada em CVE-2020-16898: "Bad Neighbor".
Este documento foi preparado pela McAfee Advanced Threat Research. Ele tem como objetivo fornecer percepções valiosas para administradores de rede e equipes de segurança que buscam entender melhor esta vulnerabilidade e se defender contra sua exploração. A assinatura aqui produzida deve ser cuidadosamente considerada e validada em ambientes de staging antes de ser usada em produção e pode se beneficiar de ajustes específicos para a implantação alvo.
As informações aqui fornecidas estão sujeitas a alterações sem aviso prévio e são fornecidas "NO ESTADO EM QUE SE ENCONTRAM", com todas as falhas, sem garantia ou asseguração quanto à precisão ou aplicabilidade das informações a qualquer situação ou circunstância específica e para uso por sua conta e risco. Além disso, não podemos garantir nenhum desempenho ou índice de eficácia para quaisquer assinaturas.
A vulnerabilidade é o resultado de uma leitura fora dos limites que pode ocorrer quando a pilha IPv6 do Windows processa pacotes ICMPv6 Router Advertisement (Tipo = 134) contendo um ou mais registros de Opção DNSSL (Tipo de Opção = 31). O propósito do registro DNSSL é fornecer uma lista de pesquisa de sufixos de nomes DNS, que estão contidos em seu último campo. Como esta Lista de Pesquisa pode conter vários nomes DNS terminados em nulo, um após o outro, o campo (e, portanto, o registro inteiro) pode variar amplamente em tamanho. Para acomodar isso, o registro de Opção DNSSL contém seu próprio campo Length (Comprimento). No entanto, como o Length é contado em incrementos de 8 bytes, pelo menos um dos nomes de domínio na Lista de Pesquisa pode ter preenchimento nulo adicional para preservar o alinhamento de 8 bytes do registro. É no processamento desses nulos que a vulnerabilidade pode ser encontrada.
Para cada nome de domínio na Lista de Pesquisa, a pilha IPv6 do Windows aloca um buffer de 256 bytes. Como a RFC 1035 limita os nomes de domínio a 255 bytes, isso normalmente seria suficiente para conter um nome de domínio mais seu terminador nulo. No entanto, o código responsável por consumir os nulos finais no final de cada nome de domínio tem um limite superior igual aos bytes restantes na Opção, que pode exceder 256 bytes. O resultado é que o código de consumo de nulos pode consumir incorretamente mais bytes do que foram alocados para o buffer, resultando em uma leitura fora dos limites. No caso em que o buffer cai no final de uma página de memória, essa leitura fora dos limites pode resultar em um BSOD.
A assinatura Suricata para esta vulnerabilidade está localizada em cve-2020-16899.rules e contém a seguinte lógica:
alert icmp any any -> any any (msg:"Potential CVE-2020-16899 Exploit"; lua:cve-2020-16899.lua; sid:202016899; rev:1;)
O script Lua correspondente pode ser encontrado em cve-2020-16899.lua. Ele contém a lógica necessária para analisar corretamente a camada ICMPv6 e identificar uma potencial exploração do CVE-2020-16899, da seguinte forma:
Uma vez localizado o início da camada ICMPv6, testamos o primeiro byte da camada para garantir que seja um pacote ICMPv6 Router Advertisement — se não for, saímos.
Como as primitivas do Suricata não foram atualizadas para analisar as Opções ICMPv6, simplesmente saltamos para o 17º byte da camada ICMPv6, pois é onde as Opções devem começar, se presentes (os primeiros 16 bytes são campos de comprimento estático, conforme a RFC 4443). A partir daí, percorremos cada Opção até que os bytes do pacote se esgotem. Para cada Opção, começamos inspecionando o primeiro byte, que corresponde ao campo Tipo de Opção. Embora ignoremos todas as Opções que não sejam DNSSL, para o Tipo de Opção = 31 (DNSSL), verificamos se o Length (segundo byte da Opção) é maior ou igual a 35, o comprimento mínimo necessário para acionar a vulnerabilidade: