Несколько лет назад мне удалось захватить поддомены на сайтах компании Microsoft и получить доступ к почте и файлам пользователей Outlook и OneDrive, а также к данным профилей на Xbox.com. Я расскажу о том, что конкретно для этого потребовалось, а заодно посмотрим, как такая атака может выглядеть сейчас, в 2020 году.
Захват через забытый CNAME
Современные компании используют большое количество облачных сервисов. Для простоты подключения используются поддомены основного домена организации, а контент обслуживается облачным сервисом напрямую. В таком случае администраторам компании достаточно добавить DNS-запись вида CNAME (canonical name или, проще говоря, алиас) со ссылкой на облачный сервис.
Например, настройка GitHub Pages для домена wiki.company.com может выглядеть следующим образом:
Но что будет, если репозиторий удалят вместе с настройкой привязки к домену wiki.company.com? Вполне вероятно, что DNS-запись при этом останется, — добавляет эти записи обычно админ, а следить, чтобы их оперативно удаляли, чаще всего некому. Тут играет человеческий фактор.
В таком случае злоумышленник может создать репозиторий и привязать его к wiki.company.com. Поскольку CNAME wiki.company.com уже указывает на company-wiki.github.io, с этого момента содержимое wiki.company.com будет контролировать злоумышленник.
Угнанный поддомен компании может использоваться для похищения сессионных кук, фишинговых атак, обхода CORS и CSP.
Захват доменов на внешних ссылках
Возможен также вариант захвата доменов, которые не принадлежат организации, но ссылки на которые используются для загрузки внешних скриптов. Представим, что страница приложения выглядит так:
Если будет возможен захват поддомена subdomain.3rdparty.com по схеме CNAME, злоумышленник сможет контролировать содержимое и выполнить произвольный код в контексте app.company.com. А если домен 3rdparty.com истек и удален — злоумышленник может вновь зарегистрировать его и контролировать все его поддомены.
Угоняем сессии Outlook и OneDrive
Несколько лет назад мне удалось захватить множество поддоменов Microsoft, в том числе для Live.com. Это дало возможность беспрепятственно перехватывать сессии пользователей Outlook и OneDrive. Как это было? Сейчас расскажу.
При регистрации любого сервиса Azure (например, виртуального сервера или виртуального хостинга) указывается имя, по которому можно потом можно обращаться напрямую либо через CNAME. Например, веб-приложение будет доступно по адресу XYZ.azurewebsites.net, где XYZ — имя приложения.
Для различных сервисов Azure использует набор разных доменов, они также могут немного отличаться и иметь префикс региона размещения ресурса:
В Microsoft этот механизм применяют и для своих приложений, в тех же пространствах имен, что и остальные пользователи. При анализе легко увидеть, что множество поддоменов Microsoft.com используют сервисы Azure и указывают на набор доменов, приведенный выше.
Что происходит после того, как сервис перестает использоваться Microsoft и удаляется? Мы можем зарегистрировать сервис Azure на нашей учетной записи, но с тем же именем. Таким образом, существующая запись CNAME будет указывать уже на созданный нами сервис, который мы можем полностью контролировать.
Как это было на практике? Собрав списки поддоменов в логах Certificate Transparency, а также с помощью атак по словарям я нашел те из них, что ссылались на облачные сервисы Azure. Мое внимание привлек домен migreports.eduadmin.live.com. Он указывал (CNAME) на домен ncuprdmigreporting.cloudapp.net, но далее домен не разрешался (NXDOMAIN):
Я создал виртуальную машину c Ubuntu в Azure и зарегистрировал сервис с идентичным именем ncuprdmigreporting.cloudapp.net, без каких-либо ошибок и подводных камней.
Регистрация сервиса с именем ncuprdmigreporting
DNS-имя теперь за мной
Запустив виртуальную машину и на ней nginx, я открыл в браузере адрес migreports.eduadmin.live.com и увидел заветное «Welcome to nginx!». Домен был под моим контролем.
Сервисы Outlook и OneDrive размещаются на адресах outlook.live.com и onedrive.live.com соответственно. Быстрый анализ показал, что для обоих сервисов сессионные куки устанавливаются на весь домен live.com, а значит, я могу перехватывать сессии пользователей.
Анализ сессионных кук live.com
Но сессионные куки были защищены флагом Secure, и передаваться они будут только по HTTPS — для доступа к ним мне нужен SSL-сертификат. Сперва это казалось проблемой, но, поразмыслив пару минут, я беспрепятственно его получил с помощью Let’s Encrypt, с той же виртуальной машины. Бинго!
Мне повезло: я успешно получил сертификат. Часть доменов Microsoft находится в черном списке Let’s Encrypt и для них запросы на получение сертификата блокируются, но live.com к таким доменам не относился.
Let’s Encrypt блокирует выдачу сертификатов для *.outlook.com
Теперь я мог контролировать содержимое сайта по HTTPS и перехватывать сессионные куки. Я подготовил простую страницу с PoC и попробовал воспроизвести атаку на угон сессии. Простой подставки сессионных кук оказалось достаточно для того, чтобы попасть в сессию пользователя независимо от браузера или IP-адреса. Более того, смена пароля или завершение сессии пользователем никак не влияли на функциональность украденной сессии — ей по-прежнему можно было пользоваться!
Мне также удалось проделать такой трюк с xbox.com — и получить доступ к данным профиля пользователя. К тому же в логах веб-сервера я наблюдал большое количество консолей Xbox, обращавшихся к моему серверу, — не исключено, что в плохих руках они бы могли превратиться в ботнет.

Решить проблему в Microsoft могли бы, например, запретив указывать произвольное название в сервисе Azure. Вместо этого сервис мог бы генерировать такое имя полностью либо его постфикс. Я сообщил о проблеме в Microsoft по программе Bug Bounty и получил вознаграждение.
Таймлайн
Что теперь? Захват поддоменов в 2020 году
После этой истории прошло больше двух лет. Предлагаю рассмотреть, как может выглядеть поиск и захват поддоменов в 2020 году.
Искать домены можно активно либо скрытно. Во втором случае используются данные из публичных сервисов. Среди них:
Тихая разведка
Начнем со скрытого поиска. К нашим услугам много источников: поисковые системы, API сканеров интернета и прочие сервисы. К счастью, ручным сбором инфы заниматься вряд ли потребуется, равно как и изобретать свои средства автоматизации.
Amass
Amass — проект консорциума OWASP, неплохо выручает при сборе информации о поддоменах. Чтобы воспользоваться этой утилитой, достаточно написать что-то в таком духе:
Rapid7 DNS
Предлагаю дополнить наши результаты данными из Rapid7 Forward DNS (FDNS). Это архивы DNS-записей интернета.
Такие записи можно скачать и отфильтровать вручную, однако, учитывая, что размер архива больше 300 Гбайт, для экономии времени и места можно применить облачный сервис Athena, принадлежащий Amazon. Он позволяет делать SQL-запросы к данным в хранилище Rapid7, уже размещенном на S3.
Создадим новый Сrawler в сервисе AWS Glue. В качестве источника укажем S3-хранилище Rapid7.
Остальные настройки можно оставить по умолчанию.
После сохранения настроек запустим краулер вручную. Теперь мы можем выполнять поиск по данным через SQL-запросы.
Можем искать только интересующие нас CNAME.
Можно использовать и архивные данные за несколько месяцев, просто подключив более старые базы. Это особенно пригодится, ведь нас интересуют домены, которыми перестали пользоваться.
Перебор
Для атак методом перебора хорошо работают словари commonspeak2, sublazerwlst, all.txt за авторством jhaddix.
В качестве быстрого сканера можно использовать massdns. Будь аккуратен с интерпретацией результатов, особенно если ищешь забытые CNAME. В качестве резолверов для massdns используй надежные публичные DNS, которые не модифицируют запросы, например Google и CloudFlare.
AltDNS
Как еще можно дополнить список имен? С помощью пермутаций для найденных имен. Воспользуемся AltDNS. На вход подадим список доменов, про которые мы уже знаем:
Ищем забытые записи
Теперь, когда у нас есть списки поддоменов, нам нужно найти записи, которые остались от удаленных сервисов. Некоторые сервисы в таких случаях возвращают ошибку 404 при обращении. Например, так делает GitHub Pages.

Другие имеют тип CNAME, но не имеют итогового адреса (NXDOMAIN). Найти такие можно, разбирая логи amass либо вот такой функцией на Python.
Известно более 30 уязвимых сервисов, которые могут быть захвачены через забытый CNAME. Их краткое описание есть в документе «Can I take over XYZ?».
Выводы
Практика показывает, что компании недооценивают опасность этой атаки. Перед ней могут быть уязвимы любые клиенты облачных сервисов, будь то маленький стартап, известный банк или крупная технологическая компания. В ходе подготовки статьи стало понятно, что проблема все еще остается актуальной для Azure. Недавние новости это подтверждают.
Автор: cyberopus
twitter.com
взято с хакер.ру
Захват через забытый CNAME
Современные компании используют большое количество облачных сервисов. Для простоты подключения используются поддомены основного домена организации, а контент обслуживается облачным сервисом напрямую. В таком случае администраторам компании достаточно добавить DNS-запись вида CNAME (canonical name или, проще говоря, алиас) со ссылкой на облачный сервис.
Например, настройка GitHub Pages для домена wiki.company.com может выглядеть следующим образом:
Код:
$ dig wiki.company.com +nostats +nocomments +nocmd
wiki.company.com 1728 IN CNAME company-wiki.github.io.
company-wiki.github.io. 3529 IN A 185.199.110.153
В таком случае злоумышленник может создать репозиторий и привязать его к wiki.company.com. Поскольку CNAME wiki.company.com уже указывает на company-wiki.github.io, с этого момента содержимое wiki.company.com будет контролировать злоумышленник.
Угнанный поддомен компании может использоваться для похищения сессионных кук, фишинговых атак, обхода CORS и CSP.
Захват доменов на внешних ссылках
Возможен также вариант захвата доменов, которые не принадлежат организации, но ссылки на которые используются для загрузки внешних скриптов. Представим, что страница приложения выглядит так:
HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>app.company.com Application</title>
<link rel="stylesheet" href="css/application.css">
</head>
<body>
<script src="https://subdomain.3rdparty.com/script.js"></script>
...
</body>
</html>
Угоняем сессии Outlook и OneDrive
Несколько лет назад мне удалось захватить множество поддоменов Microsoft, в том числе для Live.com. Это дало возможность беспрепятственно перехватывать сессии пользователей Outlook и OneDrive. Как это было? Сейчас расскажу.
При регистрации любого сервиса Azure (например, виртуального сервера или виртуального хостинга) указывается имя, по которому можно потом можно обращаться напрямую либо через CNAME. Например, веб-приложение будет доступно по адресу XYZ.azurewebsites.net, где XYZ — имя приложения.
Для различных сервисов Azure использует набор разных доменов, они также могут немного отличаться и иметь префикс региона размещения ресурса:
Код:
*.cloudapp.net
*.cloudapp.azure.com
*.azurewebsites.net
*.blob.core.windows.net
*.cloudapp.azure.com
*.azure-api.net
*.azurehdinsight.net
*.azureedge.net
*.azurecontainer.io
*.database.windows.net
*.azuredatalakestore.net
*.search.windows.net
*.azurecr.io
*.redis.cache.windows.net
*.azurehdinsight.net
*.servicebus.windows.net
*.visualstudio.com
Что происходит после того, как сервис перестает использоваться Microsoft и удаляется? Мы можем зарегистрировать сервис Azure на нашей учетной записи, но с тем же именем. Таким образом, существующая запись CNAME будет указывать уже на созданный нами сервис, который мы можем полностью контролировать.
Как это было на практике? Собрав списки поддоменов в логах Certificate Transparency, а также с помощью атак по словарям я нашел те из них, что ссылались на облачные сервисы Azure. Мое внимание привлек домен migreports.eduadmin.live.com. Он указывал (CNAME) на домен ncuprdmigreporting.cloudapp.net, но далее домен не разрешался (NXDOMAIN):
Код:
$ dig migreports.eduadmin.live.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 16373
;; ANSWER SECTION:
migreports.eduadmin.live.com 3599 IN CNAME ncuprdmigreporting.cloudapp.net.
Регистрация сервиса с именем ncuprdmigreporting
DNS-имя теперь за мной
Запустив виртуальную машину и на ней nginx, я открыл в браузере адрес migreports.eduadmin.live.com и увидел заветное «Welcome to nginx!». Домен был под моим контролем.
Сервисы Outlook и OneDrive размещаются на адресах outlook.live.com и onedrive.live.com соответственно. Быстрый анализ показал, что для обоих сервисов сессионные куки устанавливаются на весь домен live.com, а значит, я могу перехватывать сессии пользователей.
Анализ сессионных кук live.com
Но сессионные куки были защищены флагом Secure, и передаваться они будут только по HTTPS — для доступа к ним мне нужен SSL-сертификат. Сперва это казалось проблемой, но, поразмыслив пару минут, я беспрепятственно его получил с помощью Let’s Encrypt, с той же виртуальной машины. Бинго!
Мне повезло: я успешно получил сертификат. Часть доменов Microsoft находится в черном списке Let’s Encrypt и для них запросы на получение сертификата блокируются, но live.com к таким доменам не относился.
Let’s Encrypt блокирует выдачу сертификатов для *.outlook.com
Теперь я мог контролировать содержимое сайта по HTTPS и перехватывать сессионные куки. Я подготовил простую страницу с PoC и попробовал воспроизвести атаку на угон сессии. Простой подставки сессионных кук оказалось достаточно для того, чтобы попасть в сессию пользователя независимо от браузера или IP-адреса. Более того, смена пароля или завершение сессии пользователем никак не влияли на функциональность украденной сессии — ей по-прежнему можно было пользоваться!
Мне также удалось проделать такой трюк с xbox.com — и получить доступ к данным профиля пользователя. К тому же в логах веб-сервера я наблюдал большое количество консолей Xbox, обращавшихся к моему серверу, — не исключено, что в плохих руках они бы могли превратиться в ботнет.

Решить проблему в Microsoft могли бы, например, запретив указывать произвольное название в сервисе Azure. Вместо этого сервис мог бы генерировать такое имя полностью либо его постфикс. Я сообщил о проблеме в Microsoft по программе Bug Bounty и получил вознаграждение.
Таймлайн
- 14.07.2017: я сообщил в Microsoft об уязвимости
- 20.07.2017: подтверждение от Microsoft
- 14.12.2017: проблему пофиксили
- 28.10.2018: выплата Bounty
Что теперь? Захват поддоменов в 2020 году
После этой истории прошло больше двух лет. Предлагаю рассмотреть, как может выглядеть поиск и захват поддоменов в 2020 году.
Искать домены можно активно либо скрытно. Во втором случае используются данные из публичных сервисов. Среди них:
- дорки поисковиков (подробнее — в статье «Google как средство взлома»);
- информация об используемых сертификатах SSL (SSL certificate transparency logs);
- сканеры интернета типа Shodan и Censys;
- сервисы с архивными данными DNS типа DNSdumpster, SecurityTrails;
- другие открытые данные, такие как DNS-архивы Rapid7.
- атаки на подбор, которые могут быть весьма эффективными при использовании хороших словарей;
- атаки AXFR, которые все еще зачастую возможны благодаря небезопасным конфигурациям DNS-серверов.
Тихая разведка
Начнем со скрытого поиска. К нашим услугам много источников: поисковые системы, API сканеров интернета и прочие сервисы. К счастью, ручным сбором инфы заниматься вряд ли потребуется, равно как и изобретать свои средства автоматизации.
Amass
Amass — проект консорциума OWASP, неплохо выручает при сборе информации о поддоменах. Чтобы воспользоваться этой утилитой, достаточно написать что-то в таком духе:
Код:
amass enum -passive -d company.com
Rapid7 DNS
Предлагаю дополнить наши результаты данными из Rapid7 Forward DNS (FDNS). Это архивы DNS-записей интернета.
Такие записи можно скачать и отфильтровать вручную, однако, учитывая, что размер архива больше 300 Гбайт, для экономии времени и места можно применить облачный сервис Athena, принадлежащий Amazon. Он позволяет делать SQL-запросы к данным в хранилище Rapid7, уже размещенном на S3.
Создадим новый Сrawler в сервисе AWS Glue. В качестве источника укажем S3-хранилище Rapid7.
Код:
s3://rapid7-opendata/fdns/any/v1/date=202002
Остальные настройки можно оставить по умолчанию.
После сохранения настроек запустим краулер вручную. Теперь мы можем выполнять поиск по данным через SQL-запросы.
Код:
SELECT *
FROM date_202002
WHERE name LIKE '%.company.com'
Код:
SELECT *
FROM date_202002
WHERE type = 'cname'
AND value LIKE '%.github.io';
Перебор
Для атак методом перебора хорошо работают словари commonspeak2, sublazerwlst, all.txt за авторством jhaddix.
В качестве быстрого сканера можно использовать massdns. Будь аккуратен с интерпретацией результатов, особенно если ищешь забытые CNAME. В качестве резолверов для massdns используй надежные публичные DNS, которые не модифицируют запросы, например Google и CloudFlare.
Код:
## Генерируем словарь для подбора на базе commonspeak2:
cat commonspeak2.txt | awk '{print $1".company.com"}' > subdomains.txt
## Сканируем с massdns
massdns -s 15000 -o J -r resolvers.txt company_commonspeak2.txt > subdomains_massdns.txt
AltDNS
Как еще можно дополнить список имен? С помощью пермутаций для найденных имен. Воспользуемся AltDNS. На вход подадим список доменов, про которые мы уже знаем:
Код:
## Генерируем пермутации
altdns -i subdomains_ok.txt -o subdomains_altdns.txt -w words.txt
## Сканируем с massdns
massdns -s 15000 -o J -r resolvers.txt subdomains_altdns.txt > subdomains_altdns_massdns.txt
Ищем забытые записи
Теперь, когда у нас есть списки поддоменов, нам нужно найти записи, которые остались от удаленных сервисов. Некоторые сервисы в таких случаях возвращают ошибку 404 при обращении. Например, так делает GitHub Pages.

Другие имеют тип CNAME, но не имеют итогового адреса (NXDOMAIN). Найти такие можно, разбирая логи amass либо вот такой функцией на Python.
Код:
import dns.resolver
def lookup(domain):
result = []
try:
myresolver = dns.resolver.Resolver()
myresolver.nameservers = ['8.8.8.8','8.8.4.4']
# Рекурсивно получаем CNAME
for rdata in myresolver.query(domain, 'CNAME'):
if hasattr(rdata, 'target'):
result.append("[CNAME]"+str(rdata.target))
result += lookup(str(rdata.target))
except dns.resolver.NoAnswer:
# Получаем A-запись для последнего CNAME
try:
for rdata in myresolver.query(domain, 'A'):
result.append("[A]"+rdata.address)
except dns.resolver.NoAnswer:
result.append("NoAnswer")
return result
except dns.resolver.NXDOMAIN:
result.append("NXDOMAIN")
return result
except:
pass
return result
Выводы
Практика показывает, что компании недооценивают опасность этой атаки. Перед ней могут быть уязвимы любые клиенты облачных сервисов, будь то маленький стартап, известный банк или крупная технологическая компания. В ходе подготовки статьи стало понятно, что проблема все еще остается актуальной для Azure. Недавние новости это подтверждают.
Автор: cyberopus
cyberopus (@cyberopus) | Twitter
Les tout derniers Tweets de cyberopus (@cyberopus) : "Yay, I was awarded a $500 bounty on @Hacker0x01! https://t.co/uDErCiaSbV #TogetherWeHitHarder"