
Servidor DNS pasivo que detecta buckets de almacenamiento en la nube expuestos (AWS S3, GCP, Azure) resolviendo solicitudes DNS, rastreando cadenas CNAME y marcando posibles secuestros de subdominio durante el reconocimiento.
# S3DNS **s3dns** es un servidor DNS ligero que ayuda a descubrir buckets de almacenamiento en la nube (AWS S3, Google Cloud Storage y Azure Blob) resolviendo solicitudes DNS, rastreando CNAMEs y coincidiendo con patrones conocidos de URLs de buckets. Es un compañero útil para **pentesters**, **cazadores de recompensas por bugs** y **analistas de seguridad en la nube** que quieran detectar buckets en la nube expuestos durante el análisis de tráfico DNS. Si S3DNS te ahorra tiempo en una sesión de reconocimiento, considera darle una ⭐️ — ayuda a que otros encuentren el proyecto. --- --- ### 🆕 Actualización 2026/03/06 * **Soporte TCP/53** — S3DNS ahora escucha tanto en UDP como en TCP puerto 53. Los clientes que reintentan vía TCP después de una respuesta UDP truncada se manejan correctamente, reenviando la consulta upstream por TCP para obtener la respuesta completa. * **Buffer DNS más grande** — Buffer de recepción UDP incrementado de 512 a 4096 bytes. Las opciones EDNS0 del cliente se transmiten sin cambios al resolutor upstream. * **Caché de respuestas** — Caché LRU basada en TTL para respuestas DNS compartida entre los caminos UDP y TCP. Reduce la carga upstream y la latencia durante sesiones activas de reconocimiento. Configurable mediante `CACHE_SIZE` (por defecto: `1000` entradas, poner `0` para deshabilitar). * **Límite de tasa** — Límite de solicitudes por IP de cliente para prevenir abusos. Configurable mediante `RATE_LIMIT` (por defecto: `100` req/s, poner `0` para deshabilitar). * **Detección de subdominios tomables** — Cuando un dominio coincide con un patrón de almacenamiento en la nube pero devuelve `NXDOMAIN`, S3DNS lo marca como un **posible subdominio tomable**. Esto indica un registro DNS colgante que apunta a un bucket no reclamado que un atacante podría registrar. * **Verificación de rangos IP IPv6** — Los registros AAAA ahora también se resuelven y verifican contra rangos IP conocidos de almacenamiento en la nube. Los prefijos IPv6 de AWS S3 se cargan junto con los rangos IPv4. * **Límite de profundidad CNAME** — El seguimiento recursivo de cadenas CNAME ahora tiene un límite (por defecto: 10 saltos) para evitar bucles infinitos en registros maliciosos o cíclicos. Configurable mediante el parámetro `max_cname_depth`. ### Actualización 2025/08/19 * Añadidos rangos IP offline de AWS como archivo JSON. * Añadidos rangos IP offline de Azure Storage como archivo JSON. * Añadida la opción de deshabilitar la verificación de rangos IP para cada servicio usando: * `AZURE_IP_RANGES=false` o `AWS_IP_RANGES=false` (por defecto es true). * Movidos `regex_patterns` y patrones codificados a la carpeta `patterns` como archivos YAML. Puedes añadir tus propios patrones. * **Los patrones regex deben comenzar con `regex_`.** * Añadidos múltiples proveedores de nube más: * IBM Cloud Object Storage * Oracle Object Storage * Alibaba OSS * Backblaze B2 * Linode Object Storage * Scaleway Object Storage * Vultr Object Storage * Cloudflare R2 ### Actualización 2025/06/21 * Añadido soporte para AWS GovCloud. ### Actualización 2025/04/16 * Actualizados patrones regex. * Actualizada la salida para mejor visibilidad (mostrando el dominio original para CNAMEs, la IP del cliente e indicadores de rango IP). * Descarga automática de rangos IP de AWS — ¡ahora también verificándolos! * Opción para añadir tus propios rangos IP (ajustar manualmente los patrones o rangos IP en la clase). ### Actualización 2025/04/14 * Añadido soporte regex para buckets de **Google Cloud Storage** y **Azure Blob Storage**. --- ## 🚀 Características * Funciona como servidor DNS en el puerto `53` (UDP **y** TCP) * Detecta posibles buckets de almacenamiento en la nube en solicitudes DNS: * **AWS S3** (estilo virtual-host y path, incluyendo GovCloud) * **GCP Buckets** * **Azure Blob Containers** * **DigitalOcean Spaces**, **Wasabi**, **IBM COS**, **Oracle Object Storage**, **Alibaba OSS**, **Backblaze B2**, **Linode**, **Scaleway**, **Vultr**, **Cloudflare R2** * Sigue **cadenas CNAME** de forma recursiva (límite de profundidad configurable) para detectar enlaces de buckets enmascarados * Marca **posibles subdominios tomables** — patrones de almacenamiento en la nube que devuelven NXDOMAIN * Verifica las IPs resueltas (tanto A como AAAA) contra rangos IP conocidos de **AWS S3 y Azure Storage** * **Caché de respuestas con TTL** para reducir latencia y carga upstream durante reconocimiento * **Límite de tasa por IP** para prevenir abusos * Registra todos los hallazgos en consola y archivo * Amigable con contenedores --- ## ⚙️ Cómo Funciona S3DNS escucha en el **puerto 53 (UDP y TCP)** para consultas DNS. Por cada solicitud: 1. **Extrae el dominio solicitado** 2. **Verifica la caché de respuestas** — si existe una respuesta en caché válida, se devuelve inmediatamente 3. **Reenvía la solicitud a un resolutor DNS real** (ej., `1.1.1.1`) — por UDP para clientes UDP, por TCP para clientes TCP 4. **Devuelve la respuesta DNS válida al cliente** En paralelo, realiza lo siguiente: * **Verifica patrones de buckets de almacenamiento en la nube** (coincidencia regex y de hostname codificado) * **Verifica las IPs resueltas contra rangos conocidos de AWS S3 y Azure Storage** (IPv4 e IPv6) * **Sigue cadenas CNAME** recursivamente hasta la profundidad configurada * **Marca aciertos NXDOMAIN** en patrones coincidentes como posibles candidatos a toma de subdominios * **Registra todos los hallazgos** en consola y en `s3dns.log` ⚡ Úsalo como tu DNS durante el reconocimiento, y detectará pasivamente buckets en la nube y candidatos a toma de subdominios para cada dominio que tus herramientas o navegador resuelvan. --- ## 🧱 Prerrequisitos Solo necesitarás una de las siguientes opciones: * Python **3.11+** * Docker (opcional, pero recomendado) --- ## 🔧 Instalación *Solo necesario si quieres ejecutarlo localmente con Python* ### Clonar el Repositorio ```bash git clone https://github.com/olizimmermann/s3dns.git cd s3dns ``` ### Instalar Dependencias (Se recomienda usar un entorno virtual) ```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` --- ## 🧪 Uso ### Ejecutar con Python El puerto 53 requiere privilegios elevados: ```bash sudo python s3dns.py ``` *Si `sudo` informa de un módulo faltante, intenta: `sudo venv/bin/python s3dns.py`* * Si construyes la imagen tú mismo, asegúrate de etiquetarla igual que la versión de Docker Hub para consistencia: `docker build -t ozimmermann/s3dns:latest .` ### Usar Docker *La forma más fácil de empezar 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 ``` ### Construir y Ejecutar 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 ``` Los hallazgos se guardan: * En la **terminal**, y/o * En `./bucket_findings/` ### Solución de Problemas Al usar S3DNS en la misma máquina donde realizas el análisis, puede ayudar configurar la bandera `--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 ``` Dado que el puerto 53 requiere privilegios elevados, algunos usuarios (ej., usuarios de Mac) pueden necesitar `sudo`: ```bash sudo docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` --- ## 🌐 Usando S3DNS en Reconocimiento Configura el **resolutor DNS** de tu sistema o herramienta para que apunte a tu instancia de S3DNS. > Mientras navegas o haces fuzzing a tu objetivo, S3DNS analiza cada dominio y te indica si resuelve a: > > * Un **bucket de AWS S3** > * Un **bucket de GCP** > * Un **contenedor de Azure Blob** > * Cualquiera de los otros 13 proveedores de almacenamiento en la nube soportados > > **Sigue los CNAMEs**, por lo que si un dominio apunta a `cdn.ejemplo.com`, que a su vez apunta a un bucket en la nube, también lo detectará. > > También **marca posibles subdominios tomables** — si un dominio coincide con un patrón de almacenamiento en la nube pero el objetivo no existe (NXDOMAIN), el registro colgante se resalta como posible candidato a toma de subdominio. Úsalo pasivamente mientras analizas un sitio para **detectar buckets expuestos y oportunidades de toma sin sondeo activo**. --- ## ⚙️ Configuración Puedes ajustar el comportamiento mediante banderas de línea de comandos, variables de entorno o modificando `s3dns.py`. La precedencia para cada opción es: **bandera de línea de comandos > variable de entorno > indicación interactiva / predeterminado.** Ejecutar sin banderas se comporta exactamente como antes. ### Banderas de Línea de Comandos Ejecuta `python s3dns.py -h` para la lista completa: | Banderas | Variable de entorno equivalente | Descripción | |---|---|---| | `-h`, `--help` | – | Mostrar ayuda y salir | | `--version` | – | Mostrar versión y salir | | `-d`, `--debug` | `DEBUG` | Habilitar salida de depuración detallada | | `-l`, `--listen IP` | `LOCAL_DNS_SERVER_IP` | Interfaz local en la que escuchar | | `-u`, `--upstream IP` | `REAL_DNS_SERVER_IP` | Resolutor DNS upstream al que reenviar | | `-b`, `--bucket-file RUTA` | `BUCKET_FILE` | Ruta para escribir los dominios de buckets descubiertos | | `--aws-ip-ranges` / `--no-aws-ip-ranges` | `AWS_IP_RANGES` | Activar/desactivar verificación de rangos IP de AWS S3 | | `--azure-ip-ranges` / `--no-azure-ip-ranges` | `AZURE_IP_RANGES` | Activar/desactivar verificación de rangos IP de Azure Storage | | `--rate-limit N` | `RATE_LIMIT` | Máx. solicitudes DNS/segundo por IP de cliente (`0` = deshabilitado) | | `--cache-size N` | `CACHE_SIZE` | Máx. respuestas DNS en caché (`0` = deshabilitado) | | `--max-cname-depth N` | – | Profundidad máxima de cadena CNAME a seguir (por defecto: 10) | Ejemplo: ```bash sudo python s3dns.py -l 0.0.0.0 -u 1.1.1.1 --rate-limit 200 --no-azure-ip-ranges ``` ### Variables de Entorno | Variable | Predeterminado | Descripción | |---|---|---| | `DEBUG` | `false` | Habilitar salida de depuración detallada | | `AWS_IP_RANGES` | `true` | Activar verificación de rangos IP de AWS S3 | | `AZURE_IP_RANGES` | `true` | Activar verificación de rangos IP de Azure Storage | | `REAL_DNS_SERVER_IP` | `1.1.1.1` | Resolutor DNS upstream para reenviar consultas | | `LOCAL_DNS_SERVER_IP` | `0.0.0.0` | Interfaz local en la que escuchar | | `BUCKET_FILE` | `buckets.txt` | Ruta para escribir los dominios de buckets descubiertos | | `RATE_LIMIT` | `100` | Máx. solicitudes DNS por segundo por IP de cliente (`0` = deshabilitado) | | `CACHE_SIZE` | `1000` | Máx. respuestas DNS en caché (`0` = deshabilitado) | #### ⚠️ Nota sobre rangos IP de Azure Dado que Microsoft no nombra explícitamente sus rangos IP de Azure Blob Storage, S3DNS usa **todas las direcciones IP de Azure Storage proporcionadas públicamente**. Esto puede provocar falsos positivos. Considera deshabilitar esta verificación si encuentras problemas: ```bash AZURE_IP_RANGES=false ``` ### Añadir Patrones Personalizados Añade archivos YAML al directorio `patterns/`. Los archivos con prefijo `regex_` se tratan como patrones regex; todos los demás se tratan como coincidencias de subcadena. --- ### Modo Depuración **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 ``` Configurar múltiples variables de entorno en 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 ``` --- ## Ejemplo de Salida  --- ## Contribuir Las contribuciones son bienvenidas — nuevos patrones de proveedores de nube, correcciones de errores y mejoras. Consulta [CONTRIBUTING.md](https://github.com/olizimmermann/s3dns/blob/main/CONTRIBUTING.md) para las pautas. Los archivos de patrones residen en `patterns/`. Añadir soporte para un nuevo proveedor es tan simple como añadir una entrada YAML — no se requiere Python. --- ## 📄 Licencia Licencia MIT — Libre de usar, mejorar y compartir. --- ## ⚠️ Aviso Legal Úsalo responsablemente. Solo escanea dominios que **poseas** o para los que tengas **permiso explícito** para analizar. El acceso no autorizado o la exploración pueden ser ilegales.