
Пассивный DNS-сервер, который обнаруживает открытые облачные хранилища (AWS S3, GCP, Azure) путем разрешения DNS-запросов, трассировки цепочек CNAME и выявления потенциальных захватов поддоменов во время разведки.
# S3DNS **s3dns** — это легковесный DNS-сервер, который помогает обнаруживать облачные бакеты для хранения данных (AWS S3, Google Cloud Storage и Azure Blob) путем обработки DNS-запросов, отслеживания CNAME-записей и сопоставления с известными шаблонами URL-адресов бакетов. Это удобный инструмент для **пентестеров**, **охотников за багами** и **аналитиков облачной безопасности**, которые хотят выявлять открытые облачные бакеты при анализе DNS-трафика. Если S3DNS экономит ваше время во время разведки, поставьте ему ⭐️ — это поможет другим найти проект. --- --- ### 🆕 Обновление 2026/03/06 * **Поддержка TCP/53** — S3DNS теперь слушает как по UDP, так и по TCP на порту 53. Клиенты, которые повторяют запрос по TCP после усеченного UDP-ответа, обрабатываются корректно: запрос пересылается вышестоящему DNS-серверу по TCP для получения полного ответа. * **Увеличенный DNS-буфер** — Буфер приема UDP увеличен с 512 до 4096 байт. EDNS0-опции от клиента передаются вышестоящему резолверу без изменений. * **Кэш ответов** — LRU-кэш DNS-ответов с учетом TTL, общий для путей UDP и TCP. Снижает нагрузку на вышестоящий сервер и задержки во время активной разведки. Настраивается через `CACHE_SIZE` (по умолчанию: `1000` записей; установите `0` для отключения). * **Ограничение скорости** — Ограничение количества запросов на один IP-адрес клиента для предотвращения злоупотреблений. Настраивается через `RATE_LIMIT` (по умолчанию: `100` запросов/с; установите `0` для отключения). * **Обнаружение перехвата поддоменов** — Когда домен соответствует шаблону облачного хранилища, но возвращает `NXDOMAIN`, S3DNS помечает его как **возможный перехват домена**. Это указывает на болтающуюся DNS-запись, указывающую на незарегистрированный бакет, который может зарегистрировать злоумышленник. * **Проверка диапазонов IPv6** — AAAA-записи теперь также разрешаются и проверяются на принадлежность к известным диапазонам IP-адресов облачных хранилищ. IPv6-префиксы AWS S3 загружаются вместе с IPv4-диапазонами. * **Лимит глубины CNAME** — Рекурсивное отслеживание цепочек CNAME теперь ограничено (по умолчанию: 10 переходов), чтобы предотвратить бесконечные циклы на искусственных или циклических записях. Настраивается через параметр `max_cname_depth`. ### Обновление 2025/08/19 * Добавлены офлайн-диапазоны IP AWS в виде JSON-файла. * Добавлены офлайн-диапазоны IP Azure Storage в виде JSON-файла. * Добавлена возможность отключить проверку IP-диапазонов для каждого сервиса с помощью: * `AZURE_IP_RANGES=false` или `AWS_IP_RANGES=false` (по умолчанию true). * Перемещены `regex_patterns` и жестко заданные шаблоны в папку `patterns` как YAML-файлы. Вы можете добавлять свои собственные шаблоны. * **Regex-шаблоны должны начинаться с `regex_`.** * Добавлено ещё несколько облачных провайдеров: * IBM Cloud Object Storage * Oracle Object Storage * Alibaba OSS * Backblaze B2 * Linode Object Storage * Scaleway Object Storage * Vultr Object Storage * Cloudflare R2 ### Обновление 2025/06/21 * Добавлена поддержка AWS GovCloud. ### Обновление 2025/04/16 * Обновлены regex-шаблоны. * Улучшен вывод для лучшей наглядности (отображается исходный домен для CNAME, IP-адрес клиента и индикаторы диапазона IP). * Автоматическая загрузка IP-диапазонов от AWS — теперь проверяются и они! * Возможность добавить свои собственные IP-диапазоны (вручную настроить шаблоны или IP-диапазоны в классе). ### Обновление 2025/04/14 * Добавлена поддержка regex для бакетов **Google Cloud Storage** и **Azure Blob Storage**. --- ## 🚀 Возможности * Работает как DNS-сервер на порту `53` (UDP **и** TCP) * Обнаруживает потенциальные облачные бакеты в DNS-запросах: * **AWS S3** (виртуальный хост и стиль пути, включая GovCloud) * **GCP Buckets** * **Azure Blob Containers** * **DigitalOcean Spaces**, **Wasabi**, **IBM COS**, **Oracle Object Storage**, **Alibaba OSS**, **Backblaze B2**, **Linode**, **Scaleway**, **Vultr**, **Cloudflare R2** * Рекурсивно отслеживает **цепочки CNAME** (настраиваемый лимит глубины) для выявления скрытых ссылок на облачные бакеты * Помечает **потенциальные перехваты поддоменов** — шаблоны облачных хранилищ, возвращающие NXDOMAIN * Проверяет разрешенные IP-адреса (как A, так и AAAA) на вхождение в известные **IP-диапазоны AWS S3 и Azure Storage** * **Кэш ответов с учетом TTL** для снижения задержки и нагрузки на вышестоящие серверы во время разведки * **Ограничение скорости на IP** для предотвращения злоупотреблений * Логирует все находки в консоль и файл * Дружелюбен к контейнерам --- ## ⚙️ Как это работает S3DNS слушает **порт 53 (UDP и TCP)** для DNS-запросов. Для каждого запроса он: 1. **Извлекает запрошенный домен** 2. **Проверяет кэш ответов** — если есть валидный кэшированный ответ, он возвращается немедленно 3. **Пересылает запрос реальному DNS-резолверу** (например, `1.1.1.1`) — по UDP для UDP-клиентов, по TCP для TCP-клиентов 4. **Возвращает валидный DNS-ответ клиенту** Параллельно он: * **Проверяет шаблоны облачных бакетов** (regex и точное совпадение имени хоста) * **Проверяет разрешенные IP-адреса на вхождение в известные диапазоны AWS S3 и Azure Storage** (IPv4 и IPv6) * **Рекурсивно отслеживает цепочки CNAME** до заданной глубины * **Помечает попадания NXDOMAIN** по совпавшим шаблонам как возможные кандидаты на перехват поддомена * **Логирует все находки** в консоль и файл `s3dns.log` ⚡ Используйте это как ваш DNS во время разведки, и он пассивно выявит облачные бакеты и кандидатов на перехват для каждого домена, который разрешают ваши инструменты или браузер. --- ## 🧱 Предварительные требования Вам понадобится только одно из следующего: * Python **3.11+** * Docker (опционально, но рекомендуется) --- ## 🔧 Установка *Требуется только если вы хотите запускать локально с помощью Python* ### Клонирование репозитория ```bash git clone https://github.com/olizimmermann/s3dns.git cd s3dns ``` ### Установка зависимостей (Рекомендуется использовать виртуальное окружение) ```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` --- ## 🧪 Использование ### Запуск с Python Порт 53 требует повышенных привилегий: ```bash sudo python s3dns.py ``` *Если `sudo` сообщает о недостающем модуле, попробуйте: `sudo venv/bin/python s3dns.py`* * Если вы собираете образ самостоятельно, обязательно тегните его так же, как версию на Docker Hub для согласованности: `docker build -t ozimmermann/s3dns:latest .` ### Использование Docker *Самый простой способ начать работу с 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 ``` ### Сборка и запуск с 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 ``` Результаты сохраняются: * В **терминале** и/или * В `./bucket_findings/` ### Устранение неполадок При использовании S3DNS на той же машине, где вы проводите анализ, может помочь установка флага `--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 ``` Поскольку порт 53 требует повышенных привилегий, некоторым пользователям (например, пользователям Mac) может понадобиться `sudo`: ```bash sudo docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` --- ## 🌐 Использование S3DNS в разведке Укажите **DNS-резолвер** вашей системы или инструмента на ваш экземпляр S3DNS. > Во время просмотра сайта или фаззинга цели S3DNS анализирует каждый домен и сообщает, разрешается ли он в: > > * **AWS S3 bucket** > * **GCP bucket** > * **Azure Blob container** > * Любой из 13 других поддерживаемых облачных провайдеров > > Он **отслеживает CNAME**, так что если домен указывает на `cdn.example.com`, который, в свою очередь, ведёт на облачный бакет, это тоже будет обнаружено. > > Он также **помечает потенциальные перехваты поддоменов** — если домен соответствует шаблону облачного хранилища, но целевой бакет не существует (NXDOMAIN), висячая запись будет выделена как возможный кандидат на перехват. Используйте его пассивно во время анализа сайта, чтобы **обнаружить открытые бакеты и возможности перехвата без активного сканирования**. --- ## ⚙️ Конфигурация Вы можете настроить поведение с помощью флагов командной строки, переменных окружения или изменения `s3dns.py`. Приоритет для каждой опции: **флаг командной строки > переменная окружения > интерактивное приглашение / значение по умолчанию.** Запуск без флагов работает точно так же, как и раньше. ### Флаги командной строки Запустите `python s3dns.py -h` для полного списка: | Флаг | Эквивалентная переменная окружения | Описание | |---|---|---| | `-h`, `--help` | – | Показать справку и выйти | | `--version` | – | Показать версию и выйти | | `-d`, `--debug` | `DEBUG` | Включить подробный отладочный вывод | | `-l`, `--listen IP` | `LOCAL_DNS_SERVER_IP` | Локальный интерфейс для прослушивания | | `-u`, `--upstream IP` | `REAL_DNS_SERVER_IP` | Вышестоящий DNS-резолвер для пересылки | | `-b`, `--bucket-file PATH` | `BUCKET_FILE` | Путь для записи обнаруженных доменов бакетов | | `--aws-ip-ranges` / `--no-aws-ip-ranges` | `AWS_IP_RANGES` | Включение/отключение проверки IP-диапазонов AWS S3 | | `--azure-ip-ranges` / `--no-azure-ip-ranges` | `AZURE_IP_RANGES` | Включение/отключение проверки IP-диапазонов Azure Storage | | `--rate-limit N` | `RATE_LIMIT` | Макс. количество DNS-запросов/сек на IP клиента (`0` = отключено) | | `--cache-size N` | `CACHE_SIZE` | Макс. количество кэшированных DNS-ответов (`0` = отключено) | | `--max-cname-depth N` | – | Макс. глубина отслеживания цепочки CNAME (по умолчанию: 10) | Пример: ```bash sudo python s3dns.py -l 0.0.0.0 -u 1.1.1.1 --rate-limit 200 --no-azure-ip-ranges ``` ### Переменные окружения | Переменная | По умолчанию | Описание | |---|---|---| | `DEBUG` | `false` | Включить подробный отладочный вывод | | `AWS_IP_RANGES` | `true` | Включить проверку IP-диапазонов AWS S3 | | `AZURE_IP_RANGES` | `true` | Включить проверку IP-диапазонов Azure Storage | | `REAL_DNS_SERVER_IP` | `1.1.1.1` | Вышестоящий DNS-резолвер для пересылки запросов | | `LOCAL_DNS_SERVER_IP` | `0.0.0.0` | Локальный интерфейс для прослушивания | | `BUCKET_FILE` | `buckets.txt` | Путь для записи обнаруженных доменов бакетов | | `RATE_LIMIT` | `100` | Макс. количество DNS-запросов/сек на IP клиента (`0` = отключено) | | `CACHE_SIZE` | `1000` | Макс. количество кэшированных DNS-ответов (`0` = отключено) | #### ⚠️ Примечание по IP-диапазонам Azure Поскольку Microsoft не называет явно свои IP-диапазоны Azure Blob Storage, S3DNS использует **все публично предоставляемые IP-адреса Azure Storage**. Это может привести к ложным срабатываниям. Рекомендуется отключить эту проверку при возникновении проблем: ```bash AZURE_IP_RANGES=false ``` ### Добавление пользовательских шаблонов Добавьте YAML-файлы в директорию `patterns/`. Файлы с префиксом `regex_` обрабатываются как regex-шаблоны; все остальные — как поиск подстроки. --- ### Режим отладки **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 ``` Установка нескольких переменных окружения в 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 ``` --- ## Пример вывода  --- ## Вклад в проект Приветствуются любые вклады — новые шаблоны облачных провайдеров, исправления ошибок и улучшения. См. [CONTRIBUTING.md](https://github.com/olizimmermann/s3dns/blob/main/CONTRIBUTING.md) для получения рекомендаций. Файлы шаблонов находятся в `patterns/`. Добавление поддержки нового провайдера так же просто, как создание YAML-записи — Python не требуется. --- ## 📄 Лицензия Лицензия MIT — бесплатно для использования, улучшения и распространения. --- ## ⚠️ Отказ от ответственности Используйте ответственно. Сканируйте только те домены, которые вам **принадлежат** или на анализ которых вы имеете **явное разрешение**. Несанкционированный доступ или сканирование могут быть незаконными.