
Étendez votre reconnaissance avec la puissance du cloud

ReconSwarm est un framework modulaire d'automatisation de reconnaissance conçu pour les tests de sécurité distribués. Il provisionne une infrastructure cloud, exécute des pipelines de reconnaissance parallèles et collecte les résultats avec un minimum de configuration.
ReconSwarm est adapté aux chasseurs de bug bounty, testeurs d'intrusion, ingénieurs DevSecOps et chercheurs en sécurité qui ont besoin de workflows de reconnaissance automatisés et évolutifs sans gestion manuelle de l'infrastructure.

ReconSwarm suit une architecture modulaire avec une séparation claire des responsabilités entre le provisionnement cloud, le contrôle à distance du système, l'exécution des pipelines et la gestion de la configuration.
ReconSwarm utilise un modèle d'union discriminée pour les provisionneurs cloud. Le champ provisioner.type détermine quelle configuration de fournisseur est active :
provisioner:
type: yandex_cloud # Champ discriminant
yandex_cloud: # Actif lorsque type: yandex_cloud
iam_token: "${YC_TOKEN}"
# key_path: "./sa_auth_key.json"
folder_id: "${YC_FOLDER_ID}"
# ... paramètres spécifiques au fournisseur
Des fournisseurs cloud supplémentaires peuvent être intégrés en implémentant l'interface Provisioner et en ajoutant un nouveau type à la fabrique.
Les étapes sont des composants extensibles qui exécutent des opérations sur les machines virtuelles des workers :
Tous les champs des étapes prennent en charge le rendu des templates. De nouveaux types d'étapes peuvent être ajoutés pour étendre les fonctionnalités.
Le serveur ReconSwarm est complètement sans état — tout l'état est persistant dans etcd :
Cette architecture permet :
| Capacité | Description |
|---|---|
| Mise à l'échelle horizontale |
Configuration haute disponibilité :
┌─────────────┐
│ Client │
└──────┬──────┘
│
┌──────▼──────┐
│Load Balancer│
└──────┬──────┘
┌────────────┼────────────┐
│ │ │
┌──────▼──────┐ ┌───▼───┐ ┌──────▼──────┐
│ Server 1 │ │Server2│ │ Server 3 │
└──────┬──────┘ └───┬───┘ └──────┬──────┘
│ │ │
└────────────┼────────────┘
│
┌──────▼──────┐
│ etcd cluster│
└─────────────┘
Tous les serveurs partagent le même cluster etcd et peuvent traiter n'importe quelle requête. Si un serveur tombe en panne au milieu d'un pipeline, un autre serveur peut continuer l'exécution après avoir lu l'état depuis etcd.
Remarque : L'implémentation actuelle exécute les pipelines en mémoire après les avoir chargés depuis etcd. La récupération complète après crash avec reprise du pipeline est prévue pour les prochaines versions.
git clone <repository>
cd reconswarm
go mod download
task build
ReconSwarm sépare la configuration du serveur de la configuration du pipeline :
| Type de configuration | Fichier | Description |
|---|---|---|
| Serveur | reconswarm.yaml | Fournisseur cloud, etcd, paramètres du pool de workers |
| Pipeline | Fichier YAML séparé | Cibles et étapes, passé via le flag -f |
La configuration du serveur est stockée dans reconswarm.yaml (configurable via la variable d'environnement CONFIG_PATH). Toutes les valeurs de chaîne prennent en charge le développement des variables d'environnement en utilisant la syntaxe ${VAR} ou $VAR.
# Paramètres du serveur
server:
port: 50051
# Connexion etcd pour la gestion d'état
etcd:
endpoints:
- "localhost:2379"
dial_timeout: 5 # secondes
username: "" # optionnel, supporte ${ETCD_USER}
password: "" # optionnel, supporte ${ETCD_PASSWORD}
# Provisionneur cloud (union discriminée)
provisioner:
type: yandex_cloud # Sélecteur de fournisseur
# Configuration Yandex Cloud (active quand type: yandex_cloud)
yandex_cloud:
iam_token: "${YC_TOKEN}"
# key_path: "./sa_auth_key.json"
folder_id: "${YC_FOLDER_ID}"
default_zone: "ru-central1-b"
default_image: "fd8b1cmhmncn7lt4tqn4"
default_username: "root"
default_cores: 2
default_memory: 2 # GB
default_disk_size: 20 # GB
# Paramètres du pool de workers
workers:
max_workers: 5
setup_commands:
- "apt update"
- "apt install -y docker.io"
La configuration du pipeline est stockée dans un fichier YAML séparé et passée via le flag -f. Les formats avec et sans enveloppe sont pris en charge :
Format avec enveloppe (recommandé) :
# pipeline.yaml
pipeline:
targets:
- value: "example.com"
type: crtsh
- value: ["sub1.example.com", "sub2.example.com"]
type: list
stages:
- name: "Exécuter le scanner"
type: exec
steps:
- "nmap -sC -sV -iL {{.Targets.filepath}} -oN /opt/recon/scan.txt"
- name: "Récupérer les résultats"
type: sync
src: "/opt/recon/scan.txt"
dest: "./results/{{.Worker.Name}}.txt"
Format sans enveloppe (également pris en charge) :
# pipeline.yaml
targets:
- value: "example.com"
type: crtsh
stages:
- name: "Exécuter le scanner"
type: exec
steps:
- "nmap -iL {{.Targets.filepath}} -oN /opt/recon/scan.txt"
Les valeurs de configuration prennent en charge la substitution de variables d'environnement dans deux formats :
${VAR} — Nom complet de la variable entre accolades$VAR — Nom simple de la variableSi une variable d'environnement n'est pas définie, la chaîne littérale (y compris ${VAR} ou $VAR) sera utilisée.
Pour l'intégration à Yandex Cloud, utilisez le script de configuration fourni :
Installez Yandex Cloud CLI (si ce n'est pas déjà fait) :
# Suivez la documentation officielle de Yandex Cloud pour l'installation de CLI
Configurez Yandex Cloud CLI :
yc config profile create <nom-profil>
yc config set cloud-id <votre-cloud-id>
yc config set folder-id <votre-folder-id>
Exportez les identifiants :
source ./secrets-setup.sh
Ce script exporte :
YC_TOKEN — Jeton IAM pour l'authentificationYC_FOLDER_ID — ID du dossier pour la gestion des ressourcesYC_CLOUD_ID — ID du cloud (si nécessaire)Référencez dans la configuration :
provisioner:
type: yandex_cloud
yandex_cloud:
iam_token: "${YC_TOKEN}"
# key_path: "./sa_auth_key.json"
folder_id: "${YC_FOLDER_ID}"
Le script secrets-setup.sh génère automatiquement un nouveau jeton IAM à chaque exécution, garantissant une authentification sécurisée sans codage en dur des identifiants.
Créez un compte de service :
Configurez l'environnement :
export GCP_PROJECT_ID="votre-id-projet"
export GCP_CREDENTIALS_PATH="/chemin/vers/key.json"
Référencez dans la configuration :
provisioner:
type: gcp
gcp:
project_id: "${GCP_PROJECT_ID}"
credentials_path: "${GCP_CREDENTIALS_PATH}"
default_zone: "us-central1-a"
Créez un utilisateur IAM :
Configurez l'environnement :
export AWS_ACCESS_KEY_ID="votre-cle-acces"
export AWS_SECRET_ACCESS_KEY="votre-cle-secrete"
Référencez dans la configuration :
provisioner:
type: aws
aws:
region: "us-east-1"
access_key_id: "${AWS_ACCESS_KEY_ID}"
secret_access_key: "${AWS_SECRET_ACCESS_KEY}"
default_zone: "us-east-1a"
Générez un jeton :
Configurez l'environnement :
export DO_TOKEN="votre-jeton"
Référencez dans la configuration :
provisioner:
type: digitalocean
digitalocean:
token: "${DO_TOKEN}"
default_region: "nyc1"
Énumération crt.sh :
targets:
- value: "example.com"
type: crtsh
Liste manuelle :
targets:
- value: ["sub1.example.com", "sub2.example.com"]
type: list
Tous les champs de configuration des étapes prennent en charge la syntaxe Go template pour la génération dynamique de valeurs. Les variables template sont rendues au moment de l'exécution avec les données de contexte fournies automatiquement.
Contexte du template
Les données suivantes sont disponibles dans tous les templates d'étapes :
| Variable | Description |
|---|---|
{{.Targets.filepath}} | Chemin absolu vers le fichier de cibles sur la machine virtuelle distante |
{{.Targets.list}} | Tableau de chaînes de cibles pour un accès programmatique |
{{.Worker.Name}} | Identifiant unique de l'instance de worker |
Étape exec — Exécute des commandes shell avec support des templates :
stages:
- name: "Exécuter l'outil"
type: exec
steps:
- "docker run --rm -v /opt/recon:/data scanner:latest {{.Targets.filepath}}"
- "cat /opt/recon/results.json"
Toutes les commandes dans le tableau steps sont rendues via template avant exécution.
Étape sync — Copie des fichiers ou répertoires du distant vers le local via SFTP. Détecte automatiquement si le chemin est un fichier ou un répertoire :
stages:
- name: "Récupérer les résultats"
type: sync
src: "/opt/recon/results.json"
dest: "./results/{{.Worker.Name}}.json"
# Synchroniser tout un répertoire récursivement
- name: "Récupérer tous les résultats"
type: sync
src: "/opt/recon"
dest: "./results/{{.Worker.Name}}"
src (chemin distant) et dest (chemin local) prennent en charge le rendu template pour des chemins de fichiers dynamiques. L'étape sync détecte automatiquement si le chemin source est un fichier ou un répertoire et le traite en conséquence.
Démarrez le serveur gRPC pour accepter les soumissions de pipelines :
reconswarm server
Le serveur lit la configuration depuis reconswarm.yaml et écoute sur le port configuré (par défaut : 50051).
Soumettez un pipeline à un serveur en cours d'exécution :
reconswarm run -f examples/pipelines/nuclei.yaml
Options :
-f, --pipeline — Chemin vers le fichier YAML du pipeline (obligatoire)-s, --server — Adresse du serveur (par défaut : localhost:50051)reconswarm status <id-pipeline>
Exécutez un pipeline directement sans le serveur gRPC (utile pour les tests) :
reconswarm manual -f examples/pipelines/nuclei.yaml
Cette commande :
reconswarm.yamlworkers.max_workersLa désallocation automatique de l'infrastructure garantit une autonomie complète — toutes les ressources cloud sont provisionnées, utilisées et détruites sans intervention manuelle, permettant des workflows de reconnaissance entièrement automatisés.
Pour des exemples complets de pipelines, voir le répertoire examples/pipelines.
Énumération et analyse de base des sous-domaines :
# pipeline.yaml
pipeline:
targets:
- value: "example.com"
type: crtsh
stages:
- name: "Scanner les cibles"
type: exec
steps:
- "nmap -sC -sV -iL {{.Targets.filepath}} -oN /opt/recon/nmap-{{.Worker.Name}}.txt"
- name: "Récupérer les résultats"
type: sync
src: "/opt/recon/nmap-{{.Worker.Name}}.txt"
dest: "./results/nmap-{{.Worker.Name}}.txt"
Exécutez avec :
reconswarm manual -f pipeline.yaml
# ou soumettre au serveur :
reconswarm run -f pipeline.yaml
Cibles multiples avec analyse basée sur Docker :
pipeline:
targets:
- value: "example.com"
type: crtsh
- value: ["api.example.com", "www.example.com"]
type: list
stages:
- name: "Exécuter le scan nuclei"
type: exec
steps:
- "docker run --rm -v /opt/recon:/data projectdiscovery/nuclei:latest -l {{.Targets.filepath}} -json -o /opt/recon/nuclei-{{.Worker.Name}}.json"
- name: "Copier les résultats nuclei"
type: sync
src: "/opt/recon/nuclei-{{.Worker.Name}}.json"
dest: "./results/nuclei-{{.Worker.Name}}.json"
Chaîne d'outils personnalisée avec plusieurs étapes :
Configuration du serveur (reconswarm.yaml) :
workers:
max_workers: 5
setup_commands:
- "apt update"
- "apt install -y git golang"
- "git clone https://github.com/projectdiscovery/subfinder.git"
- "cd subfinder && go build"
Configuration du pipeline (pipeline.yaml) :
pipeline:
targets:
- value: "example.com"
type: crtsh
stages:
- name: "Énumération supplémentaire"
type: exec
steps:
- "cd subfinder && ./subfinder -dL {{.Targets.filepath}} -o /opt/recon/subfinder-{{.Worker.Name}}.txt"
- name: "Fusionner les cibles"
type: exec
steps:
- "cat {{.Targets.filepath}} /opt/recon/subfinder-{{.Worker.Name}}.txt | sort -u > /opt/recon/all-targets-{{.Worker.Name}}.txt"
- name: "Scanner les cibles fusionnées"
type: exec
steps:
- "nmap -sC -sV -iL /opt/recon/all-targets-{{.Worker.Name}}.txt -oN /opt/recon/scan-{{.Worker.Name}}.txt"
- name: "Collecter tous les résultats"
type: sync
src: "/opt/recon"
dest: "./results/{{.Worker.Name}}"
Remarque : L'étape sync détecte automatiquement que /opt/recon est un répertoire et copie récursivement tous les fichiers et sous-répertoires vers la destination locale.
Énumération de sous-domaines :
reconswarm crtsh-dump example.com
Récupère et filtre les sous-domaines résolvables depuis crt.sh pour un domaine donné.
Commande de débogage (pour tester le provisionnement des machines virtuelles) :
reconswarm debug
Construisez et testez en utilisant Task :
task build # Construire le binaire
task test # Exécuter les tests
task lint # Exécuter le linter
task vet # Exécuter go vet
task ci # Exécuter toutes les vérifications CI
notify — Envoyer des notifications ou alertes (webhooks, email, Slack)conditional — Exécuter des étapes en fonction des résultats d'étapes précédentesparallel — Exécuter plusieurs opérations simultanément sur le même workerretry — Réessayer automatiquement les opérations échouées avec backoff configurabletimeout — Définir des délais d'expiration par étapevalidate — Valider les résultats ou conditions avant de continuerLicence MIT. Voir le fichier LICENSE pour plus de détails.
| Exécuter plusieurs instances de serveur derrière un répartiteur de charge |
| Redémarrages sans interruption | Redémarrer le serveur sans perdre l'état du pipeline |
| Récupération après crash | Une nouvelle instance de serveur reprend là où la précédente s'est arrêtée |
| Inspection de l'état | Interroger etcd directement pour le débogage et la surveillance |