
Estendi la tua ricognizione con la potenza del cloud

ReconSwarm è un framework di automazione per ricognizioni modulare progettato per test di sicurezza distribuiti. Effettua il provisioning dell'infrastruttura cloud, esegue pipeline di ricognizione in parallelo e raccoglie risultati con un overhead di configurazione minimo.
ReconSwarm è adatto per cacciatori di bug, penetration tester, ingegneri DevSecOps e ricercatori di sicurezza che necessitano di flussi di lavoro di ricognizione scalabili e automatizzati senza gestione manuale dell'infrastruttura.

ReconSwarm segue un'architettura modulare con una chiara separazione delle responsabilità tra provisioning cloud, controllo remoto del sistema, esecuzione della pipeline e gestione della configurazione.
ReconSwarm utilizza un pattern a unione discriminata per i provisioner cloud. Il campo provisioner.type determina quale configurazione del provider è attiva:
provisioner:
type: yandex_cloud # Campo discriminante
yandex_cloud: # Attivo quando type: yandex_cloud
iam_token: "${YC_TOKEN}"
# key_path: "./sa_auth_key.json"
folder_id: "${YC_FOLDER_ID}"
# ... impostazioni specifiche del provider
È possibile integrare ulteriori provider cloud implementando l'interfaccia Provisioner e aggiungendo un nuovo tipo alla factory.
Le fasi sono componenti estensibili che eseguono operazioni sulle VM worker:
Tutti i campi delle fasi supportano il rendering dei template. È possibile aggiungere nuovi tipi di fase per estendere le funzionalità.
Il server ReconSwarm è completamente stateless — tutto lo stato è persistito in etcd:
Questa architettura consente:
| Capacità | Descrizione |
|---|---|
| Scalabilità orizzontale |
Setup per alta disponibilità:
┌─────────────┐
│ Client │
└──────┬──────┘
│
┌──────▼──────┐
│Load Balancer│
└──────┬──────┘
┌────────────┼────────────┐
│ │ │
┌──────▼──────┐ ┌───▼───┐ ┌──────▼──────┐
│ Server 1 │ │Server2│ │ Server 3 │
└──────┬──────┘ └───┬───┘ └──────┬──────┘
│ │ │
└────────────┼────────────┘
│
┌──────▼──────┐
│ etcd cluster│
└─────────────┘
Tutti i server condividono lo stesso cluster etcd e possono gestire qualsiasi richiesta. Se un server si arresta durante una pipeline, un altro server può continuare l'esecuzione dopo aver letto lo stato da etcd.
Nota: L'implementazione corrente esegue le pipeline in memoria dopo il caricamento da etcd. Il recupero completo da crash con ripresa della pipeline è previsto per release future.
git clone <repository>
cd reconswarm
go mod download
task build
ReconSwarm separa la configurazione del server dalla configurazione della pipeline:
| Tipo di Config | File | Descrizione |
|---|---|---|
| Server | reconswarm.yaml | Provider cloud, etcd, impostazioni pool worker |
| Pipeline | File YAML separato | Target e fasi, passato tramite flag -f |
La configurazione del server è memorizzata in reconswarm.yaml (configurabile tramite la variabile d'ambiente CONFIG_PATH). Tutti i valori stringa supportano l'espansione delle variabili d'ambiente usando la sintassi ${VAR} o $VAR.
# Impostazioni server
server:
port: 50051
# Connessione etcd per la gestione dello stato
etcd:
endpoints:
- "localhost:2379"
dial_timeout: 5 # secondi
username: "" # opzionale, supporta ${ETCD_USER}
password: "" # opzionale, supporta ${ETCD_PASSWORD}
# Provisioner cloud (unione discriminata)
provisioner:
type: yandex_cloud # Selettore del provider
# Configurazione Yandex Cloud (attiva quando 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
# Impostazioni pool worker
workers:
max_workers: 5
setup_commands:
- "apt update"
- "apt install -y docker.io"
La configurazione della pipeline è memorizzata in un file YAML separato e passata tramite il flag -f. Sono supportati sia il formato wrapped che unwrapped:
Formato wrapped (consigliato):
# pipeline.yaml
pipeline:
targets:
- value: "example.com"
type: crtsh
- value: ["sub1.example.com", "sub2.example.com"]
type: list
stages:
- name: "Esegui scanner"
type: exec
steps:
- "nmap -sC -sV -iL {{.Targets.filepath}} -oN /opt/recon/scan.txt"
- name: "Raccogli risultati"
type: sync
src: "/opt/recon/scan.txt"
dest: "./results/{{.Worker.Name}}.txt"
Formato unwrapped (anch'esso supportato):
# pipeline.yaml
targets:
- value: "example.com"
type: crtsh
stages:
- name: "Esegui scanner"
type: exec
steps:
- "nmap -iL {{.Targets.filepath}} -oN /opt/recon/scan.txt"
I valori di configurazione supportano la sostituzione delle variabili d'ambiente in due formati:
${VAR} — Nome completo della variabile tra graffe$VAR — Nome semplice della variabileSe una variabile d'ambiente non è impostata, verrà utilizzata la stringa letterale (inclusi ${VAR} o $VAR).
Per l'integrazione con Yandex Cloud, utilizzare lo script di setup fornito:
Installa Yandex Cloud CLI (se non già installato):
# Segui la documentazione ufficiale di Yandex Cloud per l'installazione della CLI
Configura Yandex Cloud CLI:
yc config profile create <nome-profilo>
yc config set cloud-id <id-cloud>
yc config set folder-id <id-folder>
Esporta le credenziali:
source ./secrets-setup.sh
Questo script esporta:
YC_TOKEN — Token IAM per l'autenticazioneYC_FOLDER_ID — ID folder per la gestione delle risorseYC_CLOUD_ID — ID cloud (se necessario)Riferimento nella configurazione:
provisioner:
type: yandex_cloud
yandex_cloud:
iam_token: "${YC_TOKEN}"
# key_path: "./sa_auth_key.json"
folder_id: "${YC_FOLDER_ID}"
Lo script secrets-setup.sh genera automaticamente un nuovo token IAM ogni volta che viene eseguito, garantendo un'autenticazione sicura senza scrivere le credenziali in chiaro.
Crea un Service Account:
Configura l'ambiente:
export GCP_PROJECT_ID="id-tuo-progetto"
export GCP_CREDENTIALS_PATH="/percorso/della/chiave.json"
Riferimento nella configurazione:
provisioner:
type: gcp
gcp:
project_id: "${GCP_PROJECT_ID}"
credentials_path: "${GCP_CREDENTIALS_PATH}"
default_zone: "us-central1-a"
Crea un utente IAM:
Configura l'ambiente:
export AWS_ACCESS_KEY_ID="tua-access-key"
export AWS_SECRET_ACCESS_KEY="tua-secret-key"
Riferimento nella configurazione:
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"
Genera un token:
Configura l'ambiente:
export DO_TOKEN="tuo-token"
Riferimento nella configurazione:
provisioner:
type: digitalocean
digitalocean:
token: "${DO_TOKEN}"
default_region: "nyc1"
Enumerazione da crt.sh:
targets:
- value: "example.com"
type: crtsh
Elenco manuale:
targets:
- value: ["sub1.example.com", "sub2.example.com"]
type: list
Tutti i campi di configurazione delle fasi supportano la sintassi Go template per la generazione dinamica dei valori. Le variabili del template vengono renderizzate al momento dell'esecuzione con i dati di contesto forniti automaticamente.
Contesto del template
I seguenti dati sono disponibili in tutti i template delle fasi:
| Variabile | Descrizione |
|---|---|
{{.Targets.filepath}} | Percorso assoluto al file dei target sulla VM remota |
{{.Targets.list}} | Array di stringhe target per accesso programmatico |
{{.Worker.Name}} | Identificatore univoco dell'istanza worker VM |
Fase exec — Esegue comandi shell con supporto template:
stages:
- name: "Esegui strumento"
type: exec
steps:
- "docker run --rm -v /opt/recon:/data scanner:latest {{.Targets.filepath}}"
- "cat /opt/recon/results.json"
Tutti i comandi nell'array steps vengono renderizzati con il template prima dell'esecuzione.
Fase sync — Copia file o directory dal remoto al locale usando SFTP. Rileva automaticamente se il percorso è un file o una directory:
stages:
- name: "Raccogli risultati"
type: sync
src: "/opt/recon/results.json"
dest: "./results/{{.Worker.Name}}.json"
# Sincronizza l'intera directory in modo ricorsivo
- name: "Raccogli tutti i risultati"
type: sync
src: "/opt/recon"
dest: "./results/{{.Worker.Name}}"
Sia src (percorso remoto) che dest (percorso locale) supportano il rendering dei template per percorsi dinamici. La fase sync rileva automaticamente se il percorso di origine è un file o una directory e lo gestisce di conseguenza.
Avvia il server gRPC per accettare l'invio di pipeline:
reconswarm server
Il server legge la configurazione da reconswarm.yaml e rimane in ascolto sulla porta configurata (default: 50051).
Invia una pipeline a un server in esecuzione:
reconswarm run -f examples/pipelines/nuclei.yaml
Opzioni:
-f, --pipeline — Percorso del file YAML della pipeline (obbligatorio)-s, --server — Indirizzo del server (default: localhost:50051)reconswarm status <pipeline-id>
Esegue una pipeline direttamente senza il server gRPC (utile per test):
reconswarm manual -f examples/pipelines/nuclei.yaml
Questo comando:
reconswarm.yamlworkers.max_workersLa deallocazione automatica dell'infrastruttura garantisce completa autonomia — tutte le risorse cloud vengono provisionate, utilizzate e distrutte senza intervento manuale, consentendo flussi di lavoro di ricognizione completamente automatizzati.
Per esempi completi di pipeline, consulta la directory examples/pipelines.
Enumerazione di base dei sottodomini e scansione:
# pipeline.yaml
pipeline:
targets:
- value: "example.com"
type: crtsh
stages:
- name: "Scansiona target"
type: exec
steps:
- "nmap -sC -sV -iL {{.Targets.filepath}} -oN /opt/recon/nmap-{{.Worker.Name}}.txt"
- name: "Raccogli risultati"
type: sync
src: "/opt/recon/nmap-{{.Worker.Name}}.txt"
dest: "./results/nmap-{{.Worker.Name}}.txt"
Esegui con:
reconswarm manual -f pipeline.yaml
# oppure invia al server:
reconswarm run -f pipeline.yaml
Target multipli con scansione basata su Docker:
pipeline:
targets:
- value: "example.com"
type: crtsh
- value: ["api.example.com", "www.example.com"]
type: list
stages:
- name: "Esegui scansione 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: "Copia risultati nuclei"
type: sync
src: "/opt/recon/nuclei-{{.Worker.Name}}.json"
dest: "./results/nuclei-{{.Worker.Name}}.json"
Toolchain personalizzata con più fasi:
Configurazione server (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"
Configurazione pipeline (pipeline.yaml):
pipeline:
targets:
- value: "example.com"
type: crtsh
stages:
- name: "Enumerazione aggiuntiva"
type: exec
steps:
- "cd subfinder && ./subfinder -dL {{.Targets.filepath}} -o /opt/recon/subfinder-{{.Worker.Name}}.txt"
- name: "Unisci target"
type: exec
steps:
- "cat {{.Targets.filepath}} /opt/recon/subfinder-{{.Worker.Name}}.txt | sort -u > /opt/recon/all-targets-{{.Worker.Name}}.txt"
- name: "Scansiona target uniti"
type: exec
steps:
- "nmap -sC -sV -iL /opt/recon/all-targets-{{.Worker.Name}}.txt -oN /opt/recon/scan-{{.Worker.Name}}.txt"
- name: "Raccogli tutti i risultati"
type: sync
src: "/opt/recon"
dest: "./results/{{.Worker.Name}}"
Nota: La fase sync rileva automaticamente che /opt/recon è una directory e copia ricorsivamente tutti i file e le sottodirectory nella destinazione locale.
Enumerazione sottodomini:
reconswarm crtsh-dump example.com
Recupera e filtra i sottodomini risolvibili da crt.sh per un dato dominio.
Comando di debug (per testare il provisioning delle VM):
reconswarm debug
Compila e testa usando Task:
task build # Compila il binario
task test # Esegue i test
task lint # Esegue il linter
task vet # Esegue go vet
task ci # Esegue tutti i controlli CI
notify — Inviare notifiche o avvisi (webhook, email, Slack)conditional — Eseguire fasi in base ai risultati di fasi precedentiparallel — Eseguire più operazioni contemporaneamente sullo stesso workerretry — Ripetere automaticamente operazioni fallite con backoff configurabiletimeout — Impostare timeout di esecuzione per fasevalidate — Validare risultati o condizioni prima di procedereLicenza MIT. Vedi il file LICENSE per i dettagli.
| Esecuzione di più istanze del server dietro un bilanciatore di carico |
| Riavvii senza downtime | Riavvio del server senza perdere lo stato della pipeline |
| Recupero da crash | Una nuova istanza del server riparte da dove si era interrotta la precedente |
| Ispezione dello stato | Query diretta a etcd per debug e monitoraggio |