Wrapper Python autour de masscan et nmap pour la découverte de ports à grande échelle, la découverte d'hôtes, la récupération de bannières et l'analyse de vulnérabilités basée sur NSE sur des réseaux internes ou externes.
Ce script est un wrapper pour masscan et nmap. nmap gère la découverte d'hôtes et (pour les scans plus petits) la découverte de ports, la récupération de bannières de service et les scripts NSE. Masscan est utilisé pour la découverte de ports à grande échelle, là où la vitesse brute est primordiale. Installez les deux depuis votre gestionnaire de paquets préféré ou depuis les sources.
Python 3.8+ est requis (requires-python dans pyproject.toml ; la CI démarre à 3.8).
SpooNMAP peut être exécuté directement depuis un checkout — aucune étape d'installation n'est nécessaire, voir « Utilisation » ci-dessous — ou installé comme commande autonome avec uv :
uv tool install git+https://github.com/trustedsec/spoonmap
Cela place un exécutable spoonmap dans votre PATH, vous pouvez donc l'invoquer en tant que
spoonmap depuis n'importe quel répertoire au lieu de cloner le dépôt et d'exécuter
./spoonmap.py. Il n'y a pas de paquet PyPI — ce projet n'a jamais
été publié sur pypi.org, et la commande ci-dessus installe directement depuis le
dépôt git à la place. Utilisez la forme complète git+https://... ci-dessus, et non un
simple uv tool install spoonmap ; quel que soit le nom vers lequel cela pointe sur PyPI, maintenant
ou à l'avenir, ce n'est pas ce projet.
Pour mettre à jour vers le dernier commit :
uv tool upgrade spoonmap
Installer de cette façon ne fait pas de SpooNMAP un scanner autonome :
masscan et nmap restent des outils système distincts qui doivent être installés
indépendamment (voir « Dependencies » ci-dessus), exactement comme lors d'une exécution depuis un
checkout — uv tool install ne package que le code Python propre à SpooNMAP et ses
scripts NSE intégrés, pas les binaires externes qu'il invoque.
La seule chose qu'il vaut la peine de comprendre avant d'installer de cette façon : le module Python
d'un spoonmap installé réside là où uv a placé son environnement d'outil géré — pas dans un répertoire où vous penseriez
un jour chercher un fichier de configuration ou une sortie de scan. C'est exactement le scénario dont traite la section « Where Files
Live » ci-dessous — lisez cette section pour savoir ce qui se résout par rapport
à votre répertoire courant et pourquoi ; installer via uv tool install ne
change pas la règle, cela la rend simplement importante, puisqu'il ne reste aucun répertoire de checkout
vers lequel un chemin de configuration ou de sortie pourrait se replier par habitude.
Il suffit d'exécuter le script pour qu'il vous demande toutes les options requises.
config.json, les fichiers de cibles/exclusions et la sortie de scan se résolvent tous par rapport
au répertoire depuis lequel vous lancez la commande — voir « Where Files Live » ci-dessous si
votre sortie n'est pas là où vous l'attendez, surtout si vous avez l'habitude d'invoquer
SpooNMAP par chemin depuis l'extérieur de son propre répertoire.
Si vous utilisez uv, vous pouvez exécuter sans environnement virtuel séparé :
uv run spoonmap.py
Ou invoquez directement si le script est exécutable :
# ./spoonmap.py
________ _____ _______ _________________
__ ___/______________________ | / /__ |/ /__ |__ __ \
_____ \___ __ \ __ \ __ \_ |/ /__ /|_/ /__ /| |_ /_/ /
____/ /__ /_/ / /_/ / /_/ / /| / _ / / / _ ___ | ____/
/____/ _ .___/\____/\____//_/ |_/ /_/ /_/ /_/ |_/_/
/_/
Service Categories (comma-separated numbers, default: All)
(1) Web [80, 443, 7001, 7002, 8000, 8080, 8081, 8443, 8888, 9090, 10443]
(2) Database [1433, U:1434, 1521, 3306, 5432, 6379, 9200, 27017]
(3) Remote Management [22, 23, 3389, 5900, 5901, 6129, 1723, 5985, 5986]
(4) Email [25, 110, 143, 465, 587, 993, 995]
(5) LDAP [389, 636]
(6) Network Infrastructure [53, 179, U:500, U:161, U:623, U:631, U:1194, 1194]
(7) File Transfer [21, 111]
(8) SMB [445, 135, 139, U:137]
(9) Specialized [1090, 3300, 4786, 6970, 2375, 4243, 9100, 8530, 8531]
(10) Containers & Debuggers [2377, 10250, 8001, 9229, 2345, 5005, 61616, 8009, 6000]
(11) Local LLM [11434, 1234, 7860, 5000, 5001, 1337, 3000, 8000, 8080]
(12) Full Port Scan [1-65535, TCP only — no UDP]
(c) Custom Port Scan [enter your own comma-separated ports]
(The Full Port Scan number increments automatically with the number of categories.)
**Full Port Scan is TCP only.** It sweeps TCP 1-65535 and runs no UDP discovery at
all, so every `U:` port listed in the categories above — SNMP (U:161), IKE (U:500),
IPMI (U:623), IPP (U:631), OpenVPN (U:1194), NetBIOS (U:137), SQL Browser (U:1434) —
is skipped, along with the NSE scripts and findings that depend on them. It is
*wider* than All on TCP and *narrower* on UDP. For both, run All and Full as two
passes, or use the Custom option with the UDP ports appended
(e.g. `1-65535,U:161,U:500,U:623`).
Which categories would you like to scan (e.g. 1,3 — default: All)?
Would you like to enumerate service banners for any identified services (default: Yes)?
Would you like to run NSE security scripts on identified services (default: No)?
Target Scan
(1) External
(2) Internal
Is this an internal or external scan (default: External)?
How fast would you like to scan (default: 20000 packets/second)?
Please enter the full path for the file containing target hosts (default: /opt/spoonmap/ranges.txt):
Would you like to exclude any hosts? (default: No)
Run host discovery before port scanning (default: Yes)?
Tune advanced settings (nmap threads, masscan batch size, nmap work-unit threshold)? (default: No)
Vous pouvez également créer un fichier config.json (basé sur config.json.sample) pour ignorer toutes les invites :
{
"scan_categories": ["Web", "Database", "Remote Management"],
"banner_scan": "True",
"script_scan": "False",
"host_discovery": "True",
"target_scan": "Internal",
"max_rate": "2000",
"target_file": "ranges.txt",
"output_path": "./",
"exclusions_file": "exclusions.txt",
"nmap_threads": 5,
"masscan_batch_size": 5,
"nmap_threshold": 5000000
}
Pour scanner toutes les catégories, définissez "scan_categories": "All".
Pour scanner les 65535 ports TCP, définissez "scan_categories": "Full" — notez que cela concerne uniquement TCP et n'effectue aucune découverte UDP.
Pour une liste de ports entièrement personnalisée, omettez scan_categories et utilisez plutôt "dest_ports": ["80","443","U:53"].
Les ports UDP sont spécifiés avec un préfixe U: (par ex. "U:53").
Lorsque vous répondez aux invites interactives, les options sélectionnées sont écrites dans config.json avant le début du scan. Le fichier généré documente chaque champ modifiable de la même manière que config.json.sample, et porte une clé marqueur __generated_by_prompts__. Cela signifie qu'un scan interactif interrompu peut être repris de la même manière qu'un scan piloté par configuration — il suffit de le relancer avec --resume, et toutes les invites sont ignorées.
Si la sortie d'un scan précédent est détectée dans output_path, l'outil propose trois choix : [d]elete (supprimer la sortie précédente et repartir de zéro), [a]ppend (conserver la sortie précédente mais réexécuter toutes les phases), ou [r]esume (conserver la sortie précédente et ignorer le travail déjà effectué, exactement comme le fait le drapeau --resume).