Заказчик — небольшая региональная финансовая организация — попросил обычный аудит доступов: кто и куда ходит, отключены ли уволенные, стоит ли MFA на критичных системах. Штатная гигиена. Но, как обычно в таких проектах, первым шагом было не «смотреть на людей», а посмотреть на инфраструктуру снаружи — глазами атакующего. И там нашлась история совсем другого масштаба: класс атак, который в отрасли давно называют subdomain takeover, а конкретную волну инцидентов последних лет — Danglegeddon.
Суть проблемы: доменное имя без хозяина
Несколько лет назад под рекламную акцию сделали лендинг вида promo.bank-example.ru. Разместили его не на своей инфраструктуре, а на внешнем конструкторе сайтов — по CNAME. Акция закончилась, страницу отключили, а вот запись в DNS осталась висеть:
promo.bank-example.ru. 3600 IN CNAME clientname.builderservice.com.
Аренда имени clientname.builderservice.com на стороне конструктора истекла — и это имя стало свободным. Любой человек в интернете мог зарегистрировать его заново на том же сервисе. DNS-запись банка при этом продолжает честно указывать «сюда» — просто «сюда» теперь принадлежит не банку.
Как это эксплуатируется
Атака на dangling DNS почти никогда не требует эксплойтов в классическом смысле — это чистая разведка и терпение. Вот типичный путь атакующего.
1. Массовый сбор поддоменов
subfinder -d bank-example.ru -all -silent -o subs.txt
amass enum -passive -d bank-example.ru -o amass.txt
cat subs.txt amass.txt | sort -u > all_subs.txt
wc -l all_subs.txt
# 187 all_subs.txt
Источники — Certificate Transparency логи, пассивный DNS, поисковые движки. Полезно смотреть и историю выпуска сертификатов:
curl -s "https://crt.sh/?q=%25.bank-example.ru&output=json" | jq -r '.[].name_value' | sort -u
2. Разрешение записей и поиск «висячих» CNAME
dnsx -l all_subs.txt -cname -resp -o resolved.txt
promo.bank-example.ru [CNAME] [clientname.builderservice.com]
old-partners.bank-example.ru [CNAME] [bankexample.herokuapp.com]
test-crm.bank-example.ru [CNAME] [bankexample.blob.core.windows.net]
Дальше — фильтрация по сигнатурам известных «сиротских» сервисов (существуют публичные базы вроде can-i-take-over-xyz, содержащие паттерны ответов для GitHub Pages, Heroku, Azure, AWS S3, Shopify, Zendesk, Fastly и десятков других провайдеров):
httpx -l resolved.txt -status-code -title -mc 404 -silent
https://promo.bank-example.ru [404] [NXDOMAIN — No such app]
Ответ вроде No such app, There isn't a GitHub Pages site here или NoSuchBucket — классический индикатор: имя на другом конце свободно и его можно занять.
3. Захват имени на стороне провайдера
Атакующий просто регистрируется на том же конструкторе/хостинге и создаёт проект с ровно тем же алиасом, что был прописан в CNAME банка:
После регистрации на builderservice.com
создать сайт с адресом: clientname.builderservice.com
загрузить index.html — клон формы входа в интернет-банк
DNS-запись promo.bank-example.ru → clientname.builderservice.com банк не менял — она была не нужна и забыта. Через минуту-две после распространения DNS страница promo.bank-example.ru начинает открывать чужой контент — визуально неотличимый от официального сайта, потому что домен настоящий.
4. Автоматизация массового сканирования
В реальных атаках такие поиски не делаются вручную по одному банку — сканируют целые реестры доменов пачками, используя nuclei с шаблонами takeover:
nuclei -l all_subs.txt -t subdomain-takeover/ -severity high,critical
[subdomain-takeover:heroku] [http] [high] promo.bank-example.ru
[subdomain-takeover:github-pages] [http] [medium] old-blog.bank-example.ru
Это ровно тот же инструментарий, которым я пользовался при аудите — разница только в намерениях.
Что и почему сработало бы дальше
Захват поддомена сам по себе — не финал, а плацдарм. Дальше атака развивается предсказуемо:
- TLS-сертификат без подозрений. Домен принадлежит банку по DNS, поэтому Let's Encrypt или любой другой CA выпустит валидный сертификат по HTTP-01/DNS-01 challenge — браузер покажет зелёный замок, а не предупреждение.
- Фишинг с нулевым недоверием. Ссылку
https://promo.bank-example.ru/loginлегко продвигать через рассылки, SMS, контекстную рекламу — антифрод-фильтры почтовых провайдеров реже блокируют легитимный домен второго уровня. - SEO- и репутационный захват. Старые ссылки на акцию из соцсетей, партнёрских сайтов, поисковой выдачи продолжают вести на этот адрес годами — трафик приходит бесплатно и без усилий атакующего.
- Кража сессионных cookie. Если у банка выставлен широкий scope cookie (
Domain=.bank-example.ru) для SSO между сервисами, скомпрометированный поддомен теоретически может читать/устанавливать cookie в общем домене — путь к перехвату сессии в основном интернет-банке. - Складирование учёток для credential stuffing. Даже если форма — просто копия логина без реального банкинга за ней, собранные пары логин/пароль масштабно проверяются на других сервисах и в самом интернет-банке через автоматизированные скрипты (или тот же hydra, если бы фронт банка допускал брутфорс без rate-limit).
Во сколько это могло обойтись
Даже осторожная оценка: 50 скомпрометированных счетов со средним остатком 300 тыс. рублей — это потенциальный отток вкладов на 15 млн рублей. Плюс расследование инцидента, уведомление регулятора, возможные штрафы за утечку персональных данных и, главное, репутационный урон — «банк, у которого воруют пароли», расходится за день, а доверие возвращается годами.
Как закрыть
Работа заняла пару дней и стоила несопоставимо меньше, чем компенсация одному пострадавшему клиенту.
- Полная инвентаризация DNS. Выгрузить зону целиком и сверить с реестром регистратора/DNS-провайдера:
dig axfr bank-example.ru @ns1.registrar.ru # либо через API DNS-провайдера, если AXFR закрыт (правильно, что закрыт) - Проверка живости каждого CNAME/A-адреса.
for h in $(cat all_subs.txt); do echo -n "$h -> "; dig +short cname "$h" done | tee cname_map.txt httpx -l cname_map.txt -status-code -title -fc 200 - Удаление записей на мёртвые и истёкшие сервисы — просто снести из зоны всё, что указывает на закрытые проекты, а не оставлять «на всякий случай».
- Регламент жизненного цикла поддомена. Закрытие акции = обязательное удаление DNS-записи как часть чек-листа, а не «выключили сайт и забыли».
- Ограничение scope cookie и явная политика Same-Site/Domain, чтобы даже гипотетический захваченный поддомен не мог участвовать в SSO-схемах основного банкинга.
- CAA-запись, ограничивающая, какие удостоверяющие центры вправе выпускать сертификаты для домена — снижает риск «тихого» валидного TLS на захваченном поддомене:
bank-example.ru. IN CAA 0 issue "letsencrypt.org" bank-example.ru. IN CAA 0 issuewild ";" - Постоянный мониторинг вместо разового аудита. Еженедельный прогон subfinder/dnsx/nuclei с шаблонами takeover и алертом в мессенджер ответственному, плюс отслеживание новых сертификатов через Certificate Transparency (crt.sh, Cert Spotter API) — новый неожиданный поддомен виден в течение часов, а не лет.
Самые опасные дыры в защите — это не сложные взломы, а то, что компания сама забыла удалить за собой.
Такие истории повторяются у самых разных организаций: сайты акций, старые интернет-магазины, тестовые окружения — всё это со временем превращается в забытые двери, о которых помнит только DNS. Разница лишь в том, кто найдёт их первым — свой аудитор с nuclei и списком поддоменов или кто-то, кому эти пароли нужны совсем для другого.
