
Server DNS passivo che rileva bucket di archiviazione cloud esposti (AWS S3, GCP, Azure) risolvendo richieste DNS, tracciando catene CNAME e segnalando potenziali takeover di sottodomini durante la ricognizione.
# S3DNS **s3dns** è un server DNS leggero che aiuta a scoprire bucket di cloud storage (AWS S3, Google Cloud Storage e Azure Blob) risolvendo richieste DNS, tracciando i CNAME e confrontando i pattern URL noti dei bucket. È un pratico compagno per **pentester**, **cacciatori di bug bounty** e **analisti di sicurezza cloud** che vogliono intercettare bucket cloud esposti durante l'analisi del traffico DNS. Se S3DNS ti fa risparmiare tempo durante una sessione di ricognizione, considera di dargli una ⭐️ — aiuta altri a trovare il progetto. --- --- ### 🆕 Aggiornamento 2026/03/06 * **Supporto TCP/53** — S3DNS ora ascolta sia sulla porta UDP 53 che TCP 53. I client che ritentano su TCP dopo una risposta UDP troncata vengono gestiti correttamente, con la query inoltrata a monte su TCP per recuperare la risposta completa. * **Buffer DNS più grande** — Il buffer di ricezione UDP è stato aumentato da 512 a 4096 byte. Le opzioni EDNS0 del client vengono passate al resolver a monte senza modifiche. * **Cache delle risposte** — Cache LRU basata su TTL per le risposte DNS condivisa tra i percorsi UDP e TCP. Riduce il carico a monte e la latenza durante sessioni di ricognizione attive. Configurabile tramite `CACHE_SIZE` (default: `1000` voci, impostare a `0` per disabilitare). * **Rate limiting** — Limite di richieste per IP client per prevenire abusi. Configurabile tramite `RATE_LIMIT` (default: `100` req/s, impostare a `0` per disabilitare). * **Rilevamento subdomain takeover** — Quando un dominio corrisponde a un pattern di cloud storage ma restituisce `NXDOMAIN`, S3DNS lo segnala come **possibile domain takeover**. Ciò indica un record DNS pendente che punta a un bucket non rivendicato che un attaccante potrebbe registrare. * **Controlli su range IP IPv6** — I record AAAA vengono ora anch'essi risolti e controllati rispetto ai range IP noti dei cloud storage. I prefissi AWS S3 IPv6 vengono caricati insieme ai range IPv4. * **Limite di profondità CNAME** — La catena CNAME ricorsiva è ora limitata (default: 10 hop) per prevenire loop infiniti su record artificiosi o ciclici. Configurabile tramite il parametro `max_cname_depth`. ### Aggiornamento 2025/08/19 * Aggiunti range IP AWS offline come file JSON. * Aggiunti range IP Azure Storage offline come file JSON. * Aggiunta l'opzione per disabilitare il controllo dei range IP per ciascun servizio utilizzando: * `AZURE_IP_RANGES=false` o `AWS_IP_RANGES=false` (default è true). * Spostati `regex_patterns` e pattern hardcoded nella cartella `patterns` come file YAML. Puoi aggiungere i tuoi pattern. * **I pattern regex devono iniziare con `regex_`.** * Aggiunti molti altri provider cloud * IBM Cloud Object Storage * Oracle Object Storage * Alibaba OSS * Backblaze B2 * Linode Object Storage * Scaleway Object Storage * Vultr Object Storage * Cloudflare R2 ### Aggiornamento 2025/06/21 * Aggiunto supporto per AWS GovCloud. ### Aggiornamento 2025/04/16 * Pattern regex aggiornati. * Output migliorato per una migliore visibilità (visualizzazione del dominio originale per i CNAME, l'IP del client e gli indicatori di range IP). * Scaricamento automatico dei range IP da AWS — ora li controlliamo anche! * Opzione per aggiungere i propri range IP (regolare manualmente i pattern o i range IP nella classe). ### Aggiornamento 2025/04/14 * Aggiunto supporto regex per bucket **Google Cloud Storage** e **Azure Blob Storage**. --- ## 🚀 Funzionalità * Funziona come server DNS sulla porta `53` (UDP **e** TCP) * Rileva potenziali bucket di cloud storage nelle richieste DNS: * **AWS S3** (stile virtual-host e path, incluso GovCloud) * **Bucket GCP** * **Contenitori Azure Blob** * **DigitalOcean Spaces**, **Wasabi**, **IBM COS**, **Oracle Object Storage**, **Alibaba OSS**, **Backblaze B2**, **Linode**, **Scaleway**, **Vultr**, **Cloudflare R2** * Segue **catene CNAME** in modo ricorsivo (limite di profondità configurabile) per intercettare collegamenti mascherati a bucket cloud * Segnala **potenziali subdomain takeover** — pattern di cloud storage che restituiscono NXDOMAIN * Controlla gli IP risolti (sia A che AAAA) rispetto ai **range IP noti di AWS S3 e Azure Storage** * **Cache delle risposte sensibile al TTL** per ridurre latenza e carico a monte durante la ricognizione * **Rate limiting per IP** per prevenire abusi * Registra tutte le scoperte su console e file * Amichevole per i container --- ## ⚙️ Come funziona S3DNS ascolta sulla **porta 53 (UDP e TCP)** per le query DNS. Per ogni richiesta: 1. **Estrae il dominio richiesto** 2. **Controlla la cache delle risposte** — se esiste una risposta in cache valida, viene restituita immediatamente 3. **Inoltra la richiesta a un resolver DNS reale** (es. `1.1.1.1`) — su UDP per client UDP, su TCP per client TCP 4. **Restituisce la risposta DNS valida al client** In parallelo: * **Controlla i pattern dei bucket di cloud storage** (corrispondenza regex e hostname hardcoded) * **Controlla gli IP risolti rispetto ai range noti di AWS S3 e Azure Storage** (IPv4 e IPv6) * **Segue le catene CNAME** in modo ricorsivo fino alla profondità configurata * **Segnala i colpi NXDOMAIN** su pattern corrispondenti come possibili candidati per subdomain takeover * **Registra tutte le scoperte** su console e `s3dns.log` ⚡ Usalo come tuo DNS durante la ricognizione e rivelerà passivamente bucket cloud e candidati takeover per ogni dominio che i tuoi strumenti o browser risolvono. --- ## 🧱 Prerequisiti Avrai bisogno solo di uno dei seguenti: * Python **3.11+** * Docker (opzionale, ma raccomandato) --- ## 🔧 Installazione *Necessario solo se vuoi eseguirlo localmente con Python* ### Clona il repository ```bash git clone https://github.com/olizimmermann/s3dns.git cd s3dns ``` ### Installa le dipendenze (Si consiglia l'uso di un ambiente virtuale) ```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` --- ## 🧪 Utilizzo ### Esecuzione con Python La porta 53 richiede privilegi elevati: ```bash sudo python s3dns.py ``` *Se `sudo` segnala un modulo mancante, prova: `sudo venv/bin/python s3dns.py`* * Se costruisci l'immagine da solo, assicurati di taggarla con lo stesso nome della versione su Docker Hub per coerenza: `docker build -t ozimmermann/s3dns:latest .` ### Utilizzo con Docker *Il modo più semplice per iniziare con S3DNS.* ```bash docker pull ozimmermann/s3dns:latest docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` ### Costruisci ed esegui con Docker ```bash docker build -t ozimmermann/s3dns:latest . ``` ```bash docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` I risultati vengono salvati: * Nel **terminale**, e/o * In `./bucket_findings/` ### Risoluzione dei problemi Quando usi S3DNS sulla stessa macchina in cui esegui l'analisi, può essere utile impostare il flag `--network host`: ```bash docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --network host \ --name "s3dns" \ ozimmermann/s3dns:latest ``` Poiché la porta 53 richiede privilegi elevati, alcuni utenti (es. utenti Mac) potrebbero aver bisogno di `sudo`: ```bash sudo docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` --- ## 🌐 Utilizzo di S3DNS nella ricognizione Imposta il **resolver DNS** del tuo sistema o strumento sulla tua istanza S3DNS. > Mentre navighi o fai fuzzing del tuo target, S3DNS analizza ogni dominio e ti dice se si risolve in: > > * Un **bucket AWS S3** > * Un **bucket GCP** > * Un **contenitore Azure Blob** > * Uno qualsiasi degli altri 13 provider di cloud storage supportati > > **Segue i CNAME**, quindi se un dominio punta a `cdn.example.com`, che a sua volta punta a un bucket cloud, lo intercetterà. > > **Segnala anche potenziali subdomain takeover** — se un dominio corrisponde a un pattern di cloud storage ma il target non esiste (NXDOMAIN), il record pendente viene evidenziato come possibile candidato takeover. Usalo passivamente mentre analizzi un sito per **individuare bucket esposti e opportunità di takeover senza probing attivo**. --- ## ⚙️ Configurazione Puoi modificare il comportamento tramite flag da riga di comando, variabili d'ambiente o modificando `s3dns.py`. La precedenza per ogni opzione è: **flag da riga di comando > variabile d'ambiente > prompt interattivo / default.** Eseguire senza flag si comporta esattamente come prima. ### Flag da riga di comando Esegui `python s3dns.py -h` per l'elenco completo: | Flag | Variabile d'ambiente equivalente | Descrizione | |---|---|---| | `-h`, `--help` | – | Mostra aiuto ed esci | | `--version` | – | Mostra versione ed esci | | `-d`, `--debug` | `DEBUG` | Abilita output debug dettagliato | | `-l`, `--listen IP` | `LOCAL_DNS_SERVER_IP` | Interfaccia locale su cui ascoltare | | `-u`, `--upstream IP` | `REAL_DNS_SERVER_IP` | Resolver DNS a monte per l'inoltro | | `-b`, `--bucket-file PERCORSO` | `BUCKET_FILE` | Percorso dove scrivere i domini bucket scoperti | | `--aws-ip-ranges` / `--no-aws-ip-ranges` | `AWS_IP_RANGES` | Attiva/disattiva controlli range IP AWS S3 | | `--azure-ip-ranges` / `--no-azure-ip-ranges` | `AZURE_IP_RANGES` | Attiva/disattiva controlli range IP Azure Storage | | `--rate-limit N` | `RATE_LIMIT` | Max richieste DNS/sec per IP client (`0` = disabilitato) | | `--cache-size N` | `CACHE_SIZE` | Max risposte DNS in cache (`0` = disabilitato) | | `--max-cname-depth N` | – | Profondità massima catena CNAME da seguire (default: 10) | Esempio: ```bash sudo python s3dns.py -l 0.0.0.0 -u 1.1.1.1 --rate-limit 200 --no-azure-ip-ranges ``` ### Variabili d'ambiente | Variabile | Default | Descrizione | |---|---|---| | `DEBUG` | `false` | Abilita output debug dettagliato | | `AWS_IP_RANGES` | `true` | Abilita controlli range IP AWS S3 | | `AZURE_IP_RANGES` | `true` | Abilita controlli range IP Azure Storage | | `REAL_DNS_SERVER_IP` | `1.1.1.1` | Resolver DNS a monte per l'inoltro delle query | | `LOCAL_DNS_SERVER_IP` | `0.0.0.0` | Interfaccia locale su cui ascoltare | | `BUCKET_FILE` | `buckets.txt` | Percorso dove scrivere i domini bucket scoperti | | `RATE_LIMIT` | `100` | Max richieste DNS al secondo per IP client (`0` = disabilitato) | | `CACHE_SIZE` | `1000` | Max risposte DNS in cache (`0` = disabilitato) | #### ⚠️ Nota sui range IP Azure Poiché Microsoft non denomina esplicitamente i propri range IP di Azure Blob Storage, S3DNS utilizza **tutti gli indirizzi IP di Azure Storage forniti pubblicamente**. Ciò può portare a falsi positivi. Considera di disabilitare questo controllo se riscontri problemi: ```bash AZURE_IP_RANGES=false ``` ### Aggiungere pattern personalizzati Aggiungi file YAML nella directory `patterns/`. I file con prefisso `regex_` vengono trattati come pattern regex; tutti gli altri come corrispondenze di sottostringa. --- ### Modalità debug **Python:** ```bash sudo su export DEBUG=true python s3dns.py ``` **Docker:** ```bash docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ -e "DEBUG=true" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` Impostare più variabili d'ambiente in Docker: ```bash docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ -e "LOCAL_DNS_SERVER_IP=0.0.0.0" \ -e "REAL_DNS_SERVER_IP=1.1.1.1" \ -e "RATE_LIMIT=200" \ -e "CACHE_SIZE=2000" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` --- ## Esempio di output  --- ## Contributi I contributi sono benvenuti — nuovi pattern per provider cloud, correzioni di bug e miglioramenti. Vedi [CONTRIBUTING.md](https://github.com/olizimmermann/s3dns/blob/main/CONTRIBUTING.md) per le linee guida. I file dei pattern risiedono in `patterns/`. Aggiungere il supporto per un nuovo provider è semplice come aggiungere una voce YAML — non è richiesto Python. --- ## 📄 Licenza Licenza MIT — Libero da usare, migliorare e condividere. --- ## ⚠️ Disclaimer Utilizza responsabilmente. Scansiona solo domini di cui **sei proprietario** o per cui hai **esplicita autorizzazione** all'analisi. L'accesso non autorizzato o il probing potrebbero essere illegali.