
CVE-2020-16899 - Logique de détection et règle de vulnérabilité TCP/IP de Microsoft Windows
Le 13 octobre, Microsoft a annoncé une vulnérabilité critique dans la pile IPv6 de Windows, qui permet à un attaquant d'envoyer des paquets malveillants entraînant un BSOD (Blue Screen of Death) immédiat sur les versions les plus récentes de Windows 10 et Windows Server 2019. Bien que cette vulnérabilité ne semble pas permettre l'exécution de code par un attaquant, elle pourrait être utilisée pour mener des attaques de déni de service massives contre les versions vulnérables de Windows. La logique de détection pour la version RCE plus impactante de cette vulnérabilité peut être trouvée dans CVE-2020-16898 : "Bad Neighbor".
Ce document a été préparé par McAfee Advanced Threat Research. Il vise à fournir des informations précieuses aux administrateurs réseau et au personnel de sécurité souhaitant mieux comprendre cette vulnérabilité et se défendre contre son exploitation. La signature produite ici doit être soigneusement examinée et testée dans des environnements de préproduction avant d'être utilisée en production et pourrait bénéficier d'un réglage spécifique à l'environnement cible.
Les informations fournies ici sont sujettes à modification sans préavis et sont fournies « EN L'ÉTAT », avec toutes leurs imperfections, sans garantie quant à leur exactitude ou applicabilité à une situation ou circonstance particulière, et leur utilisation se fait à vos propres risques. De plus, nous ne pouvons garantir aucun indicateur de performance ou d'efficacité pour les signatures.
Cette vulnérabilité résulte d'une lecture hors limites pouvant se produire lorsque la pile IPv6 de Windows traite des paquets ICMPv6 Router Advertisement (Type = 134) contenant un ou plusieurs enregistrements d'option DNSSL (Type d'option = 31). Le but de l'enregistrement DNSSL est de fournir une liste de recherche de suffixes de noms DNS, qui sont contenus dans son dernier champ. Comme cette liste de recherche peut contenir plusieurs noms DNS terminés par null les uns à la suite des autres, le champ (et donc l'enregistrement entier) peut varier considérablement en taille. Pour y remédier, l'enregistrement d'option DNSSL contient son propre champ Longueur. Cependant, comme la longueur est comptée par incréments de 8 octets, au moins un des noms de domaine de la liste de recherche peut avoir un remplissage nul supplémentaire pour préserver l'alignement sur 8 octets de l'enregistrement. C'est lors du traitement de ces nuls que la vulnérabilité peut être exploitée.
Pour chaque nom de domaine dans la liste de recherche, la pile IPv6 de Windows alloue un tampon de 256 octets. Comme RFC 1035 limite les noms de domaine à 255 octets, cela serait normalement suffisant pour contenir un nom de domaine plus son terminateur nul. Cependant, le code responsable de la consommation des nuls de fin à la fin de chaque nom de domaine a une limite supérieure égale au nombre d'octets restants dans l'option, qui peut dépasser 256 octets. Il en résulte que le code de consommation des nuls peut incorrectement consommer plus d'octets que ce qui a été alloué pour le tampon, entraînant une lecture hors limites. Dans le cas où le tampon se trouve à la fin d'une page mémoire, cette lecture hors limites peut provoquer un BSOD.
La signature Suricata pour cette vulnérabilité se trouve dans cve-2020-16899.rules et contient la logique suivante :
alert icmp any any -> any any (msg:"Potential CVE-2020-16899 Exploit"; lua:cve-2020-16899.lua; sid:202016899; rev:1;)
Le script Lua correspondant se trouve dans cve-2020-16899.lua. Il contient la logique nécessaire pour analyser correctement la couche ICMPv6 et identifier une potentielle exploitation de CVE-2020-16899, comme suit :
Une fois que nous avons localisé le début de la couche ICMPv6, nous testons le premier octet de la couche pour vérifier qu'il s'agit d'un paquet ICMPv6 Router Advertisement - si ce n'est pas le cas, nous quittons.
Étant donné que les primitives de Suricata n'ont pas été mises à jour pour analyser les options ICMPv6, nous sautons simplement au 17e octet de la couche ICMPv6, car c'est là que les options devraient commencer, si elles sont présentes (les 16 premiers octets sont des champs de longueur fixe, selon RFC 4443). De là, nous parcourons chaque option jusqu'à épuisement des octets dans le paquet. Pour chaque option, nous commençons par inspecter le premier octet, qui correspond au champ Type d'option. Bien que nous ignorions toutes les options qui ne sont pas DNSSL, pour le type d'option = 31 (DNSSL), nous vérifions si la longueur (deuxième octet de l'option) est supérieure ou égale à 35, la longueur minimale nécessaire pour déclencher la vulnérabilité :