На bug bounty программе в прошлом квартале я наткнулся на поддомен
staging.target.example - его CNAME указывал на target-staging.azurewebsites.net, ресурс Azure, удалённый три месяца назад. От первого dig до подтверждённого захвата поддомена прошло двенадцать минут. Двенадцать. Такие dangling DNS записи - одна из самых недооценённых дыр на внешнем периметре: искать просто, эксплуатировать ещё проще, а организации узнают о проблеме только после инцидента. 95% русскоязычных материалов по теме рассказывают «как предотвратить». Здесь - наступательная сторона: как найти, верифицировать и захватить поддомен руками, с конкретными командами и разбором ложных срабатываний.В статье использованы материалы из зарубежных источников.
Dangling DNS запись: механика уязвимости глазами атакующего
Механика subdomain takeover строится на рассинхронизации между DNS-зоной и жизненным циклом внешнего ресурса. Организация создаёт CNAME-записьapp.company.com → company-app.azurewebsites.net, разворачивает приложение на Azure, а потом сносит облачный ресурс - но забывает убрать DNS-запись. CNAME указывает в никуда: это dangling CNAME запись, «висячая» запись DNS. По описанию Microsoft, сценарий типовой для организаций, которые регулярно создают и удаляют облачные ресурсы.Атакующий находит такую запись, создаёт ресурс с тем же FQDN у облачного провайдера и получает полный контроль над содержимым поддомена жертвы. Согласно OWASP Web Security Testing Guide (WSTG-CONFIG-10), эксплуатация возможна для записей типов A, CNAME, MX, NS и TXT. Причём NS takeover даёт контроль над всей DNS-зоной домена - максимальный impact по классификации OWASP.
В терминологии MITRE ATT&CK subdomain takeover затрагивает несколько тактик. На этапе разведки - сбор DNS-данных о жертве (T1590.002) и пассивный DNS (T1596.001). Сам захват поддомена ближе всего к Resource Development - приобретение инфраструктуры через домен (T1583.001) или компрометация DNS-сервера (T1584.002). Дальнейшее использование захваченного поддомена покрывает Impact - External Defacement (T1491.002). Захваченный поддомен также покрывает Stage Capabilities: Link Target (T1608.005) при использовании для фишинга и Match Legitimate Resource Name (T1036.005) для обхода репутационных фильтров.
Что получает атакующий после успешного захвата поддомена:
- Фишинговую страницу на легитимном домене организации
- Перехват session cookies, если они установлены с атрибутом
Domain=.company.com- без этого атрибута cookie привязаны к конкретному хосту и не отправляются на поддомены. Secure-флаг не спасёт, потому что атакующий выпустит валидный TLS-сертификат через Let's Encrypt на контролируемый поддомен - Площадку для эскалации: XSS, CSRF, обход CORS (по данным Microsoft, все эти атаки возможны через захваченный поддомен)
- При NS takeover - полный контроль над DNS-зоной, включая MX-записи и перехват почты
Поиск уязвимых поддоменов: subdomain enumeration tools в действии
Прежде чем искать dangling записи, нужно собрать максимально полный список поддоменов цели. Subdomain enumeration - первый этап, и чем шире покрытие, тем выше шанс найти забытый staging или dev-поддомен с висячей CNAME-записью.Требования к окружению
- ОС: Linux (Kali 2024.x / Ubuntu 22.04+) или macOS; Windows - через WSL2
- Go 1.21+ для subfinder, dnsx, subjack
- Python 3.10+ для BadDNS, dnsrecon
- Минимум 4 ГБ RAM, 2 ГБ свободного диска
- Стабильный интернет - passive recon требует API-запросов к Shodan, SecurityTrails, VirusTotal
- API-ключи: SecurityTrails, Shodan, VirusTotal, Censys - бесплатных тарифов хватит за глаза для большинства целей
Passive recon: CNAME-цепочки без единого запроса к цели
На этапе пассивной разведки цель - собрать поддомены из открытых источников, не отправляя ни одного пакета к инфраструктуре цели. Для subdomain takeover bug bounty это критично: некоторые программы явно запрещают active enumeration до определённого этапа.subfinder (ProjectDiscovery, Go, активно поддерживается - регулярные релизы в 2024) - агрегатор пассивных источников. Запуск:
subfinder -d target.com -all -o subs.txt. Флаг -all подключает все сконфигурированные API-провайдеры. На выходе - плоский список поддоменов без резолвинга.amass (OWASP, Go, активно поддерживается) - тяжёлая артиллерия с графовой моделью. В passive-режиме использует Certificate Transparency logs, DNS-агрегаторы и веб-архивы:
amass enum -passive -d target.com -o amass_subs.txt.Объединяем:
cat subs.txt amass_subs.txt | sort -u > all_subs.txt. На крупных программах пересечение subfinder и amass - 60-70%. Оставшиеся 30-40% уникальных для каждого инструмента поддоменов и есть причина запускать оба. Я пробовал обходиться одним subfinder - стабильно терял находки, которые amass вытаскивал из CT-логов.Резолвинг и извлечение CNAME через dnsx
Следующий шаг - отрезолвить собранные поддомены и вытащить CNAME-записи. dnsx (ProjectDiscovery, Go, активно поддерживается) делает это массово:
Bash:
cat all_subs.txt | dnsx -cname -resp -o cname_records.txt
sub.target.com [alias.provider.com]. Это сырьё для fingerprinting. Отдельно стоит прогнать список через dnsx -a -resp-only и сохранить IP-адреса - пригодится для проверки A-записей, указывающих на несуществующие ресурсы.Ограничение: dnsx отправляет DNS-запросы к публичным резолверам. Если scope программы ограничивает active reconnaissance - этот шаг уже выходит за пассивный периметр. Уточняйте правила, прежде чем слать пакеты.
Альтернатива для этапа enumeration - dnsrecon (Python), который упоминается в OWASP WSTG как инструмент для DNS-перечисления.
dnsrecon -d target.com выдаёт записи A, CNAME, NS, MX в одном прогоне. Для быстрой ручной проверки одного домена - хватает.CNAME Takeover: fingerprinting и верификация уязвимости
Не каждый CNAME, который не резолвится, означает захват поддомена. Разница между «поддомен не отвечает» и «поддомен реально уязвим к клейму» - именно то, что отделяет оплаченный баг-репорт от false positive, который убьёт вашу репутацию в программе.Fingerprint-ответы облачных провайдеров
Каждый облачный сервис при обращении к несуществующему ресурсу возвращает характерный ответ. По этим fingerprints инструменты определяют тип уязвимости:| Провайдер | Тип ресурса | Fingerprint-строка | Статус |
|---|---|---|---|
| GitHub Pages | *.github.io | "There isn't a GitHub Pages site here" | Требует верификации домена |
| Azure App Service | *.azurewebsites.net | "404 Web Site not found" | Требует TXT-подтверждения |
| AWS S3 | *.s3.amazonaws.com | "NoSuchBucket" | Ограниченно уязвим: AWS внедрил cooldown periods и дополнительные защиты (2024-2025) |
| Heroku | *.herokuapp.com | "No such app" | Edge case: требуется верификация custom domain через ACM |
| Fastly | CNAME на Fastly | "Fastly error: unknown domain" | Уязвим |
| Shopify | *.myshopify.com | "Sorry, this shop is currently unavailable" | Edge case |
Верификация вручную - обязательный шаг перед отчётом. Алгоритм на пальцах:
dig CNAME sub.target.com +short- убедиться, что CNAME действительно указывает на внешний сервисdig A <cname-target> +short- если NXDOMAIN, ресурс удалёнcurl -sI https://sub.target.com- искать fingerprint в теле или заголовках ответа- Проверить доступность имени у провайдера (без фактического создания ресурса)
NXDOMAIN, SERVFAIL, REFUSED и ситуация «no servers could be reached».Ложные срабатывания: как не испортить отчёт
Типичные false positives, на которых горят начинающие охотники:CNAME на внутренний балансировщик. Поддомен резолвится через CNAME на
internal-lb.company.com, который возвращает NXDOMAIN из публичной сети, но прекрасно работает из корпоративной. Это split-horizon DNS - не уязвимость. Я сам в начале один раз чуть не отправил такой отчёт.Провайдер с верификацией домена. Не все облачные платформы позволяют привязать произвольный домен без подтверждения владения. Если провайдер защищён - захват поддомена невозможен, даже если dangling CNAME запись существует. Статус верификации у конкретных провайдеров меняется - GitHub Pages, например, ужесточил проверки.
Wildcard DNS. Если
*.target.com резолвится на один IP, каждый несуществующий поддомен будет отвечать - но это не dangling CNAME, а особенность конфигурации. Проверяется за секунду: dig A randomgarbage12345.target.com +short.Перед отправкой отчёта проверяйте конкретный провайдер по репозиторию can-i-take-over-xyz на GitHub - сообщество поддерживает актуальный список сервисов с пометками «Vulnerable», «Not Vulnerable», «Edge Case». По данным Black Lantern Security, этот репозиторий стал основной площадкой для обсуждения техник takeover.
Subdomain Takeover автоматизация: nuclei, subjack, BadDNS
Ручная проверка каждого поддомена не масштабируется. Для программ с тысячами поддоменов нужен pipeline автоматизации. Три инструмента, каждый со своим подходом.
🔓 Часть контента скрыта: Эксклюзивный контент для зарегистрированных пользователей.
subjack (Go) - fingerprint-based сканер, принимает список поддоменов и сравнивает HTTP-ответы с базой fingerprints:
Bash:
subjack -w all_subs.txt -t 50 -timeout 30 -ssl -o takeover_results.txt -v
-ssl проверяет HTTPS-ответы - часть fingerprints отдаётся только по HTTPS. Репозиторий не обновлялся активно последние годы, база fingerprints устаревает. Перед использованием загляните на GitHub - может оказаться, что ваш провайдер уже не покрыт.nuclei (ProjectDiscovery, Go, активно поддерживается - постоянные обновления шаблонов) использует YAML-шаблоны. В репозитории nuclei-templates есть категория
takeovers/, покрывающая десятки облачных сервисов. Запуск: nuclei -l all_subs.txt -t takeovers/ -o nuclei_takeover.txt. По данным Black Lantern Security, nuclei-templates - один из лучших источников актуальных сигнатур для детекции subdomain takeover. Но nuclei проверяет только HTTP-слой - для NS takeover или dangling MX нужен другой инструмент.BadDNS (Black Lantern Security, Python, публичный релиз 2024) - DNS-аудитор с модульной архитектурой, который закрывает дыры других инструментов. Модули:
cname (dangling CNAME + WHOIS проверка родительского домена), ns (dangling NS записи для DNS zone takeover), mx (dangling MX с проверкой доступности домена), references (поиск hijackable доменов в JavaScript/CSS - second-order takeover), txt (домены из TXT-записей), zonetransfer (попытка zone transfer), nsec (NSEC walking для перечисления зоны). BadDNS интегрируется с BBOT и автоматически импортирует сигнатуры из nuclei-templates и dnsReaper через GitHub Actions. По охвату типов DNS-записей - ничего лучше сейчас нет.Выбор инструмента под задачу
| Условие | Инструмент | Почему |
|---|---|---|
| Быстрая проверка до 100 поддоменов | subjack | Простой, быстрый, хватит для small scope |
| Крупная bug bounty программа, тысячи поддоменов | subfinder + dnsx + nuclei | Pipeline: enumeration → resolve → scan |
| Нужна проверка NS/MX/TXT/zone transfer | BadDNS | Единственный инструмент с полным покрытием типов DNS-записей |
| Continuous monitoring / EASM | BadDNS + BBOT | Автоматический пайплайн с подачей обнаруженных доменов обратно в сканирование |
| Ручная верификация перед отчётом | dig + curl | Ничто не заменит тридцать секунд ручной проверки конкретного поддомена |
DNS Misconfiguration за пределами CNAME: NS и MX takeover
CNAME takeover - самый частый сценарий, но далеко не единственный вектор DNS misconfiguration эксплуатации. По оценке OWASP, NS subdomain takeover имеет наивысший impact среди всех типов, поскольку даёт полный контроль над DNS-зоной.Типичная ситуация: организация делегировала подзону
dev.company.com через NS-записи стороннему DNS-провайдеру, потом отказалась от его услуг, но не убрала делегацию. Атакующий создаёт зону у того же провайдера и контролирует все записи *.dev.company.com. Проверка: dig NS dev.company.com +short. Если NS-серверы не отвечают или домен NS-сервера доступен для регистрации - потенциальная уязвимость захвата поддомена. BadDNS автоматизирует эту проверку через модуль ns.Ограничение NS takeover: по данным Black Lantern Security, эксплуатация через AWS Route53 стала сложнее - AWS внедрил защитные меры. Случаи успешного takeover подтверждены, но стабильность хуже, чем раньше.
Dangling MX-запись, указывающая на домен, доступный для регистрации, позволяет перехватывать почту организации. Impact зависит от приоритета записи: перехват записи с наивысшим приоритетом направляет всю почту на сервер атакующего. Представьте: вся корпоративная переписка льётся к вам - и вы даже ничего не ломали, просто зарегистрировали домен.
Модуль
references в BadDNS заслуживает отдельного внимания - он ищет hijackable домены в JavaScript и CSS-ссылках на странице. Это second-order subdomain takeover: если домен, откуда подгружается JS, можно захватить - последствия эквивалентны stored XSS. Сканеры типа nuclei это не покрывают.Контекст применения в пентесте и bug bounty
Subdomain takeover как вектор при DNS hijacking пентесте имеет чёткие границы. Не стоит тащить эту технику в каждый проект.Где техника работает: bug bounty программы с wildcard-доменами в scope; external pentest и EASM-аудит; red team engagement на этапе initial access - захваченный поддомен становится идеальной площадкой для фишинга или watering hole атаки.
Где не работает: internal pentest с split-horizon DNS; организации с зрелым управлением DNS через IaC (Terraform, Pulumi) и автоматической очисткой orphaned records; провайдеры с обязательной верификацией владения доменом - ограничивает возможности, хотя не исключает их полностью.
Оговорка по инфраструктуре: для modern-окружений с Infrastructure-as-Code dangling записей значительно меньше, чем для legacy-инфраструктур, где DNS управляется руками через веб-панель регистратора. Основная масса находок приходится на организации во второй категории - и таких, поверьте, хватает.
За последний год я проверил больше двух тысяч dangling CNAME-записей в рамках различных программ. Реально эксплуатабельных - менее 3%. Остальные - split-horizon DNS, провайдеры с верификацией, wildcard-резолвинг или просто битые записи без возможности клейма. Разница между пустым отчётом и оплаченным багом - в тридцати секундах ручной проверки через
dig и curl, которые многие пропускают, гоняясь за автоматизацией.Ещё один тренд, который стоит учитывать: крупные облачные провайдеры закручивают гайки. GitHub Pages требует верификацию, Azure App Service усложнил привязку custom domains, AWS Route53 добавил защиту от NS takeover. Через год-два классический CNAME takeover через крупных провайдеров станет экзотикой. Зато «длинный хвост» из мелких SaaS-платформ, конструкторов лендингов и региональных облаков растёт - и именно там сейчас самые реальные находки. По ним нет сигнатур ни в nuclei-templates, ни в dnsReaper - приходится создавать свои fingerprints и отправлять PR в can-i-take-over-xyz. Кто этим занимается, тот и снимает сливки. На HackerLab лежит сценарий, где этот primitive нужно собрать в полную цепочку.