
CVE-2019-0708 bluekeep détection de vulnérabilité
Ceci est un scanner rapide et sommaire pour la vulnérabilité CVE-2019-0708 dans Microsoft Remote Desktop. Actuellement, environ 700 000 machines sur Internet sont vulnérables à cette vulnérabilité, contre environ 2 000 000 de machines qui exposent Remote Desktop, mais qui sont corrigées/sûres contre l'exploitation. Beaucoup s'attendent à ce que dans les prochains mois, un ver Internet dévastateur apparaisse, similaire à WannaCry et NotPetya. Par conséquent, scannez vos réseaux et corrigez vos systèmes. Cet outil facilite le scan de vos réseaux pour trouver les machines vulnérables.
Pour utiliser cet outil, vous pouvez télécharger un « binaire » à exécuter en ligne de commande, ou télécharger les sources et les compiler. Pour Windows, un binaire précompilé est disponible.
Cet outil est entièrement basé sur le correctif rdesktop provenant de https://github.com/zerosum0x0/CVE-2019-0708.
J'ai simplement réduit le code afin de pouvoir le compiler facilement sur macOS et Windows,
et j'ai ajouté la possibilité de scanner plusieurs cibles.
Ce projet n'a que quelques jours et est expérimental. Cependant, je le teste en scannant
tout Internet (avec l'aide de masscan), donc je résous pas mal de problèmes
assez rapidement. Vous pouvez essayer de me contacter sur Twitter (@erratarob) pour de l'aide ou des commentaires.
Pour scanner un réseau, lancez-le comme suit :
rdpscan 192.168.1.1-192.168.1.1.255
Cela imprimera un résultat d'une ligne par adresse, indiquant VULNERABLE si elle est vulnérable au bug, SAFE si elle est (probablement) sûre, ou UNKNOWN si le programme n'a pas pu déterminer le statut, par exemple s'il n'a obtenu aucune réponse de la cible. Comme la plupart des cibles ne répondent pas, statistiquement, la plupart seront UNKNOWN.
C'est assez lent. Vous pouvez augmenter la vitesse en ajoutant le paramètre de ligne de commande
--workers 1000. Mais vous pouvez augmenter encore plus la vitesse en le faisant précéder
de masscan pour trouver rapidement les machines avec le port 3389 ouvert, puis en
utilisant rdpscan uniquement pour scanner ces machines afin de détecter la vulnérabilité.
masscan 10.0.0.0/8 -p3389 --rate 1000000 >ips.txt
rdpscan --file ips.txt > results.txt
Ou, en une seule étape, en redirigeant la sortie de l'un vers l'autre :
masscan 10.0.0.0/8 -p3389 --rate 1000000 | rdpscan --file -
Vous pouvez obtenir des détails de diagnostic plus verbeux en utilisant le paramètre -d, qui sont
imprimés sur sterr. C'est ainsi que je lance habituellement le programme :
rdpscan --file ips.txt 2> diag.txt 1> results.txt
La partie difficile est d'installer les bibliothèques OpenSSL, sans qu'elles n'entrent en conflit avec d'autres versions présentes sur le système. Sous Debian Linux, je fais :
$ sudo apt install libssl-dev
Une fois ce problème résolu, il vous suffit de compiler tous les fichiers .c ensemble
comme ceci :
$ gcc *.c -lssl -lcrypto -o rdpscan
J'ai mis un Makefile dans le répertoire pour cela, donc vous pouvez probablement faire simplement :
$ make
Le code est écrit en C, donc un compilateur C doit être installé, par exemple en faisant :
$ sudo apt install build-essential
Cette section décrit les erreurs de compilation les plus évidentes.
ssl.h:24:25: fatal error: openssl/rc4.h: No such file or directory
Cela signifie soit que vous n'avez pas les en-têtes OpenSSL installés, soit qu'ils ne se trouvent pas dans un chemin quelconque. Rappelez-vous que même si vous avez les binaires OpenSSL installés, cela ne signifie pas que vous disposez des éléments de développement. Vous devez avoir à la fois les en-têtes et les bibliothèques installés.
Pour installer ces éléments sous Debian, faites :
$ sudo apt install libssl-dev
Pour corriger le problème de chemin, ajoutez une option de compilation -I/usr/local/include, ou quelque chose
de similaire.
Voici un exemple de problème d'édition de liens :
Undefined symbols for architecture x86_64:
"_OPENSSL_init_ssl", referenced from:
_tcp_tls_connect in tcp-fac73c.o
"_RSA_get0_key", referenced from:
_rdssl_rkey_get_exp_mod in ssl-d5fdf5.o
"_SSL_CTX_set_options", referenced from:
_tcp_tls_connect in tcp-fac73c.o
"_X509_get_X509_PUBKEY", referenced from:
_rdssl_cert_to_rkey in ssl-d5fdf5.o
Je rencontre ceci sur macOS car il existe plusieurs versions d'OpenSSL. Je corrige cela en codant en dur les chemins :
$ gcc *.c -lssl -lcrypto -I/usr/local/include -L/usr/local/lib -o rdpscan
D'après les commentaires d'autres utilisateurs, la commande suivante pourrait fonctionner sur macOS si vous avez utilisé Homebrew pour installer les choses. J'obtiens néanmoins toujours les erreurs de liaison ci-dessus, car j'ai installé d'autres composants OpenSSL qui entrent en conflit.
gcc $(brew --prefix)/opt/openssl/lib/libssl.a $(brew --prefix)/opt/openssl/lib/libcrypto.a -o rdpscan *.c
La section ci-dessus donne des conseils de démarrage rapide pour exécuter le programme. Cette section donne une aide plus détaillée.
Pour scanner une seule cible, il suffit de passer l'adresse de la cible :
./rdpscan 192.168.10.101
Vous pouvez passer des adresses IPv6 et des noms DNS. Vous pouvez passer plusieurs cibles. Un exemple serait :
./rdpscan 192.168.10.101 exchange.example.com 2001:0db8:85a3::1
Vous pouvez également scanner des plages d'adresses, en utilisant soit des adresses IPv4 début-fin, soit une spécification CIDR IPv4. Les plages IPv6 ne sont pas prises en charge car elles sont trop grandes.
./rdpscan 10.0.0.1-10.0.0.25 192.168.0.0/16
Par défaut, il ne scanne que 100 cibles à la fois. Vous pouvez augmenter ce nombre
avec le paramètre --workers. Cependant, quelle que soit la valeur de ce paramètre,
en pratique vous obtiendrez au maximum environ 500 à 1500 workers en cours d'exécution
en même temps, selon votre système.
./rdpscan --workers 1000 10.0.0.0/24
Au lieu de spécifier les cibles en ligne de commande, vous pouvez les charger
depuis un fichier, en utilisant le paramètre bien nommé --file :
./rdpscan --file ips.txt
Le format du fichier est une adresse, un nom ou une plage par ligne. Il peut également
consommer le texte généré par masscan. Les espaces superflus sont supprimés,
les lignes vides sont ignorées, et les lignes de commentaire sont ignorées. Un commentaire est
une ligne commençant par le caractère # ou par les caractères //.
La sortie est envoyée sur stdout, donnant le statut VULNERABLE, SAFE,
ou UNKNOWN. Il peut y avoir des raisons supplémentaires pour chacun.
149.129.120.24 - UNKNOWN - FIN received
45.60.213.160 - SAFE - not RDP but HTTP
208.43.229.89 - SAFE - CredSSP required
170.104.127.137 - UNKNOWN - FIN received
86.188.190.117 - UNKNOWN - connect timeout
62.15.34.157 - SAFE - Target appears patched
216.15.251.120 - VULNERABLE -- got appid
69.62.158.174 - VULNERABLE -- got appid
92.111.20.13 - SAFE - Target appears patched
Vous pouvez traiter cette sortie avec des commandes unix supplémentaires comme grep et cut.
Pour obtenir une liste des seules machines vulnérables :
./rdpscan 10.0.0.0/8 | grep 'VULN' | cut -f1 -d'-'
Les éléments marqués « UNKNOWN » valent probablement la peine d'être scannés plus tard,
en particulier pour « FIN received », ce qui signifie généralement que l'autre partie a terminé la connexion
prématurément à cause d'un délai sur Internet. Sauvegardez-les dans un fichier, puis
relisez-les lors du prochain scan avec l'option --file.
Savoir si « CredSSP required » (signifiant que NLA est requis) est « SAFE » est discutable. Cela signifie qu'une connexion par mot de passe est requise avant de pouvoir tester/déclencher la vulnérabilité. La machine peut ne pas être corrigée et être vulnérable à un utilisateur authentifié, elle n'est simplement pas exploitable par un ver ou un utilisateur non authentifié.
Vous devriez toujours obtenir un statut unique sur stdout pour chaque adresse IP
que vous scannez. Bien sûr, si vous spécifiez une adresse IP plusieurs fois, vous obtiendrez plusieurs
statuts pour cette adresse.
Cependant, comme ce code est basé sur rdestkop, certaines erreurs de protocole
ne mèneront pas à un statut. Si vous avez une adresse IP publique sur Internet
qui produit l'une de ces erreurs, je suis impatient de la corriger.
L'ajout du paramètre -d vide les informations de diagnostic sur les connexions vers stderr.
./rdpscan 62.15.34.157 -d
[+] [62.15.34.157]:3389 - connecting...
[+] [62.15.34.157]:3389 - connected from [10.1.10.133]:49211
[+] [62.15.34.157]:3389 - SSL connection
[+] [62.15.34.157]:3389 - version = v4.8
[+] [62.15.34.157]:3389 - Sending MS_T120 check packet
[-] [62.15.34.157]:3389 - Max sends reached, waiting...
62.15.34.157 - SAFE - Target appears patched
Sur macOS/Linux, vous pouvez rediriger stdout et stderr séparément vers différents
fichiers de la manière habituelle :
./rdpscan --file ips.txt 2> diag.txt 1> results.txt
Il inclut donc la prise en charge de SOCKS5 :
./rdpscan --file ips.txt --socks5 localhost --socks5port 9050
Cela aggrave les problèmes de connexion, ce qui donne beaucoup plus de résultats « UNKNOWN ».