Utilisation des scripts NSE de Nmap
Sommaire
I. Présentation
Dans ce chapitre, nous allons étudier en profondeur les scripts NSE (Nmap Scripting Engine). Nous verrons notamment en quoi ils constituent l’une des grandes forces de cet outil, comment ils fonctionnement et comment parcourir et utiliser les nombreux scripts existants.
Ce chapitre fait suite aux apprentissages précédents de ce cours, dans lesquels nous avons appris à utiliser les fonctionnalités de recherche de vulnérabilité de Nmap de façon basique. Nous allons à présent étudier plus en profondeur le fonctionnement de Nmap à ce sujet pour, encore une fois, réaliser des analyses plus précises et maîtrisées.
II. Le concept des scripts NSE de Nmap
Les scripts NSE de Nmap permettent d’étendre ses capacités de manière très flexible. Ils sont écrits en langage LUA, un langage de scripting plus maniable et facile d’accès que le C ou le C# utilisé par Nmap. L’intérêt d’utiliser un script LUA avec Nmap plutôt qu’un outil seul et que cela nous permet de profiter de la rapidité d’exécution et des fonctionnalités standards de Nmap (découverte d’hôte, de ports, de versions, etc.).
Ces scripts sont organisés par catégorie et un seul script peut faire partie de plusieurs catégories :
auth | Contient les scripts relatifs à l’authentification sur des services, dont l’accès anonyme ou l’énumération des utilisateurs. Exemples : “oracle-enum-users”, “ftp-anon”. |
broadcast | Contient les scripts relatifs aux opérations de broadcast sur le réseau, notamment en vue d’exploiter et de découvrir certains services, hôtes ou protocoles reposant sur le broadcast (IPv6, wake on lan, IGMP, etc.). Exemples : “broadcast-dhcp6-discover”, “broadcast-ospf2-discover”. |
brute | Contient les scripts relatifs aux opérations de brute force de l’authentification sur les services (brute force SSH, MSSQL, etc.). Exemples : “ssh-brute”, “vnc-brute”. |
default | Contient les scripts utilisés dans le cas par défaut (utilisation de “-sC”). Plusieurs critères sont utilisés afin valider l’entrée d’un script dans cette catégorie dont la vitesse d’exécution, la structure de la sortie, la fiabilité du test, le caractère “intrusif” ou “risqué”, etc. |
discovery | Contient les scripts relatifs à la découverte avancée du réseau et des services. On y retrouve par exemple l’énumération du contenu d’un partage SMB, d’une version d’un service VNC, des requêtes SNMP, etc. Exemples : “mysql-info”, “http-security-headers”. |
dos | Contient les scripts pouvant causer un déni de service. Il peut s’agir de scripts créés pour exploiter une vulnérabilité de type de déni service ou alors de script ayant pour effet de bord un déni de service. Prudence donc (ils sont exclus de la catégorie “default”). Exemples : “http-slowloris”, “ipv6-ra-flood”. |
exploit | Contient les scripts créés pour exploiter de manière directe une vulnérabilité. Exemples : “http-shellsock”, “smb-vuln-ms08-067”. |
external | Contient les scripts qui nécessitent l’utilisation d’une ressource tierce, comme une base d’information en ligne. Cela indique notamment une tentative de connexion vers l’extérieur (attention à la confidentialité). Exemples : “whois-ip”, “dns-blacklist”, “ip-geolocation-geoplugin”. |
fuzzer | Contient les scripts conçus pour envoyer des trames, paquets ou paramètres inattendus par un service. Cela permet notamment de causer des erreurs ou dysfonctionnements afin d’obtenir des pistes de vulnérabilité ou des informations techniques. Exemples : “dns-fuzz” ou “http-form-fuzzer”. |
intrusive | Contient les scripts qui sont catégorisés comme “risqués” d’un point de vue disponibilité, ou détection. Ils peuvent provoquer un crash du système ou être détectés comme malveillant par une solution de sécurité. Il s’agit de la catégorie inverse de “safe”. Exemples : “smtp-brute”, “smb-vuln-ms08-067” ou”smb-psexec” |
malware | Contient les scripts conçus pour détecter la présence d’élément caractéristique d’un malware, tel qu’un port en écoute communément utilisé par une backdoor connue. Exemples : “ftp-proftpd-backdoor” ou “smtp-strangeport”. |
safe | Contient les scripts qui sont considérés comme sûrs d’un point de vue détection ou stabilité. Il s’agit de la catégorie inverse de “intrusive” et elle contient en grande majorité de scripts avancés d’identification de version ou de relevé d’élément de configuration. Exemples : “html-title”, “smb2-security-mode” ou “ms-sql-info”. |
version | Contient les scripts qui permettent une détection avancée de version. Ils peuvent être utilisés en complément des Probes et Matchs étudiés précédemment quand la détection d’une version nécessite des opérations un peu plus complexes. Exemples : “http-php-version” ou “vmware-version” |
vuln | Contient les scripts conçus pour détecter la présence de vulnérabilité connue (CVE) sans pour autant les exploiter (à l’inverse de la catégorie “expoit”). Ils se contentent en général de rapporter le statut “vulnérable” ou non d’un service. Exemples : “smb-vuln-ms17-010” (eternal blue) ou “http-phpmyadmin-dir-traversal”. |
Techniquement, les catégories auxquelles appartient un script sont indiquées directement dans son code.
Cet exemple montre une partie du code du script NSE “ftp-anon.nse”, dont nous avons vu le résultat d’exécution dans le chapitre précédent.
III. Lister les scripts NSE existants
Les scripts NSE de Nmap sont par défaut situés dans le répertoire “/usr/share/nmap/scripts/”, sans arborescence ou hiérarchie spécifique. Voici un aperçu du contenu de ce répertoire :
Ce répertoire contient plus de 5 000 scripts NSE. Dans la majorité des cas, la première partie du nom de script contient le protocole ou la catégorie à laquelle il se rattache. Cela nous permet de faire un tri, par exemple si l’on souhaite lister tous les scripts qui visent le service FTP :
Nmap ne propose pas vraiment d’option pour parcourir et lister ses scripts NSE, vous pouvez utiliser la commande “--script-help” suivi du nom d’une catégorie ou d’un mot :
# Lister tous les scripts dont le nom commence par “ftp-”
nmap --script-help=ftp-*
# Lister tous les scripts de la catégorie “discovery”
nmap --script-help=discovery
Cependant, le résultat de sortie sera l’affichage du nom de chaque script et sa description, ce qui n’est pas optimal si la recherche ressort plusieurs dizaines de scripts :
La méthode la plus efficace selon moi reste donc les commandes classiques Linux dans le répertoire “/usr/share/nmap/scripts/” :
# Lister les scripts ciblant le service “ssh”
ls -al /usr/share/nmap/scripts/ssh*
# Lister les scripts de la catérogie “dos”
grep -rl '"dos"' /usr/share/nmap/scripts/
N’hésitez pas à parcourir le code des modules qui vous parlent afin de mieux comprendre comment fonctionne un script NSE.
IV. Utiliser les scripts NSE de Nmap
À présent, nous allons apprendre à réaliser des scans de vulnérabilités en choisissant finement les scripts NSE qui nous intéressent.
A. Sélectionner les scripts par catégories
Pour commencer, nous pouvons choisir d’exécuter tous les scripts appartenant à une catégorie précise. Nous devons indiquer cette ou ces catégories à Nmap avec l’argument “--script <catégorie>” :
# Utiliser les scripts NSE par défaut
nmap --script default 10.10.10.152
Cette première commande est l’équivalent de la commande “nmap -sC”. Par défaut, Nmap va sélectionner les scripts qui sont dans la catégorie “default”, mais c’est pour l’exemple. La commande suivante va par exemple utiliser tous les scripts qui sont présents dans la catégorie “discovery” :
# Utiliser les scripts NSE de la catégorie "discovery"
nmap --script discovery 10.10.10.152
Comme nous l’avons vu, certaines catégories permettent d’identifier rapidement ce que font les scripts NSE qui s’y rattachent (“discovery”, “vuln”, “exploit”), alors que d’autres définissent le niveau de risque, de détection ou la stabilité du test réalisé. Si l’on est dans un contexte sensible et que l’on ne maîtrise pas bien les différentes actions réalisées par notre sélection de scripts, nous pouvons choisir de combiner les sélections pour ne choisir que les scripts qui sont dans les catégories “discovery” et “safe” :
# Utiliser des scripts venant de plusieurs catégories
nmap --script “discovery and safe” 10.10.10.152
Si l’on veut absolument et de manière explicite exclure les scripts des catégories “dos” et “intrusive”, il est possible d’utiliser la notation suivante :
# Exclure des catégories
nmap --script “not intrusive and not dos” 10.10.10.152
Attention, le fait de spécifier des conditions d’exclusion comme ci-dessus entraînera l’utilisation de toutes les autres catégories qui ne sont pas explicitement exclues. Pour être plus juste, nous pouvons indiquer par exemple :
# Inclure les scripts de la catégorie “vuln” sauf ceux trop risqués
nmap --script “vuln and not intrusive and not dos” 10.10.10.152
# Même chose, mais uniquement en visant le protocole HTTP
nmap --script “(http and vuln) and not intrusive and not dos” 10.10.10.152
Voilà différents exemples qui vous permettront de manipuler plus précisément les scripts NSE par catégorie, notamment lors de l’utilisation de Nmap dans le cadre d’une analyse de vulnérabilité dans des contextes réels.
B. Sélectionner les scripts de façon unitaire
Nous pouvons également choisir de mener un seul test bien précis lors d’une analyse, un test correspondant à un script NSE. Pour cela, nous devons indiquer le nom du script dans le paramètre “--script <nom>”. Si l’on reprend l’exemple du script “ftp-anon.nse” :
# Utiliser un script NSE et un port précis
nmap --script ftp-anon -p 21 10.10.10.152
Nous avons alors un résultat très précis :
Nous voyons le résultat de l’exécution du script “ftp-anon” sur le port 21, et aucun autre port, car nous avons spécifié l’option “-p 21”. Nous aurions aussi pu réaliser un scan de port basique, et l’exécution du script NSE “ftp-anon” seulement les services FTP découverts :
# Utiliser un script NSE précis
nmap --script ftp-anon 10.10.10.152
Ainsi, Nmap aurait également exécuté ce test de connexion anonyme s’il avait trouvé un service FTP sur un autre port.
Pour avoir une petite description de ce que fait un script NSE, vous pouvez utiliser l’option “--script-help” évoquée précédemment :
Bref, encore une fois, nous pouvons réutiliser ici toutes les options de découverte réseau, de services, version et technologies utilisées jusqu’ici !
C. Gérer les arguments de scripts
Au cours de votre utilisation de Nmap, vous rencontrerez certains scripts NSE qui nécessitent des arguments en entrée pour pouvoir fonctionner correctement. Nous allons à présent voir comment passer des arguments à ces scripts par l’intermédiaire des options de Nmap.
En exemple, nous allons prendre le script “ssh-brute”, qui permet d’effectuer une attaque par brute force sur le service SSH.
Une attaque par brute force classique consiste à tester plusieurs mots de passe (parfois des millions) pour tenter de s’authentifier sur un compte bien précis. À force de tenter des mots de passe, l’attaquant mise sur une probabilité que l’utilisateur ait utilisé un mot de passe faible qui serait dans le dictionnaire de mot de passe utilisé pour l’attaque.
Ce script possède des options “par défaut”, que nous pourrions personnaliser en fonction de notre contexte. Dans le cadre de cette attaque, nous pouvons par exemple fournir à Nmap la liste des utilisateurs et le dictionnaire de mot de passe à utiliser. À ma connaissance, il n’est pas possible de facilement lister les arguments nécessaires pour un script, le moyen le plus fiable reste le site web officiel de Nmap. Un lien direct vers la documentation d’un script NSE peut être obtenu en réponse à l’option “--script-help” :
En cliquant sur le lien indiqué, nous arrivons sur cette page web du site https://nmap.org :
Ici, nous avons une vue claire des arguments pouvant être utilisés, les principaux dans notre contexte d’utilisation sont “passdb” (fichier contenant une liste des mots de passe) et “userdb” (fichier contenant une liste des utilisateurs). La documentation fait ici une référence à des librairies internes à Nmap, car ces mécanismes de brute force et les options associées sont mutualisés pour être utilisés de façon uniforme entre plusieurs scripts (“ssh-brute”, “mysql-brute”, “mssql-brute”, etc.) et auront donc à peu près les mêmes arguments :
# Création d’un fichier contenant ma liste d’utilisateurs
echo “root” > /tmp/userlist
# Création d’un fichier contenant ma liste de mots de passe
echo “123456” > /tmp/passlist
echo “NomEntreprise75” >> /tmp/passlist
echo “changezmoi” >> /tmp/passlist
# Exécution d’un brutefore SSH via le scan réseau Nmap
nmap --script ssh-brute --script-args userdb=/tmp/userlist,passdb=/tmp/passlist 10.10.10.245 192.168.1.19
Comme vous pouvez le voir dans cette dernière commande, nous pouvons spécifier les arguments nécessaires à un script Nmap en utilisant l’option “--scripts-args clé=valeur,clé=valeur”. Voici un résultat possible de la sortie Nmap lors de la réalisation d’un brute force SSH via le script NSE “ssh-brute” :
Comme vous le voyez, les informations générées par les scripts NSE sont préfixées par un “NSE : [nom du script]” dans l’interactive output (sortie terminal), ce qui permet de s’y retrouver plus facilement. Au sein de l’affichage habituel des résultats de Nmap, nous avons simplement une synthèse indiquant si oui ou non des identifiants faibles ont été découverts (incluant les mots de passe, il faut s’en souvenir).
Pour aller plus loin et rappeler que tout cela est utilisable en plus de toutes les options précédemment étudiées, voici une commande qui va réaliser une découverte du réseau “10.10.10.0/24”, scanner les 2000 ports TCP les plus fréquents et exécuter sur les services FTP une recherche d’accès en anonyme et sur les services SSH une campagne de brute force :
# Exemple de commande complète utilisant plusieurs scripts
nmap --top-ports 2000 10.10.10.0/24 --script ftp-anon,ssh-brute --script-args userdb=/tmp/userlist,passdb=/tmp/passlist
Ceci n’est qu’un exemple parmi les nombreux scripts disponibles et leurs options. Mais, nous avons à présent une meilleure idée de comment mieux appréhender les scripts NSE, savoir s’ils nécessitent des arguments et comment passer ces arguments à Nmap.
V. Conclusion
Ce chapitre nous a permis de manipuler et de comprendre comment concrètement utiliser les scripts NSE de Nmap pour réaliser différentes tâches. Je vous invite ici à prendre le temps de découvrir les différentes catégories de scripts et les scripts eux-mêmes pour vous rendre compte du nombre de tests qu’ils permettent d’automatiser.
Voilà plusieurs chapitres que nous accumulons les options de découverte, scan et énumération plus ou moins avancées. Vous devriez à présent vous rendre compte que l’affichage de sortie et des résultats Nmap commence à être bien fourni, parfois même trop verbeux pour notre terminal. Dans le prochain chapitre, nous allons apprendre à maîtriser cette sortie, notamment en la stockant dans des fichiers sous différents formats.