Статья Пентест Azure AD: разведка, обход Conditional Access и эскалация привилегий в Entra ID

Сергей Попов

Администратор
30.12.2015
4 888
6 591
Специализация
  1. OSINT
  2. Веб-безопасность
Статус верификации
  1. ✓ Verified
Юбикей и Flipper Zero на тёмном антистатическом коврике, за ними светится экран ноутбука с зелёным терминалом. Янтарный свет лампы выхватывает устройства из глубокой тени.


Когда классический пентестер впервые смотрит на Azure-среду, он по привычке ищет открытые порты, уязвимые сервисы, непропатченные хосты. И находит... практически ничего. Потому что в облаке Microsoft атакуемая поверхность определяется не софтом, а конфигурацией identity-слоя. Мискофигурированный Storage Account с анонимным доступом к blob или перепривилегированный Service Principal наносят больше ущерба, чем непропатченный RCE в on-premise инфраструктуре. Другой мир - другие правила.

Эта статья - практическое руководство по пентесту Azure AD (Microsoft Entra ID) от человека, который ломал такие среды в реальных engagement'ах. Разберём полный kill chain: от внешней разведки без единого пароля до эскалации привилегий через цепочки Application Administrator → Service Principal → Global Admin. Каждый шаг - с конкретными командами и объяснением, почему это работает.

Разведка Azure AD без единого пароля​

Первая фаза любого пентеста Entra ID - разведка tenant'а. Даже без аутентификации можно собрать достаточно для формирования вектора атаки. По MITRE ATT&CK это техники , Discovery) и Cloud Groups (T1069.003, Discovery).

Определение Tenant ID и типа аутентификации​

Каждый tenant имеет уникальный GUID и ассоциированный домен вида contoso.onmicrosoft.com. Tenant ID вытаскивается одним запросом:
Bash:
curl "https://login.microsoftonline.com/targetdomain.com/.well-known/openid-configuration"
В ответе поле issuer содержит Tenant ID, вшитый в URL. Дальше проверяем тип аутентификации - managed (облако) или federated (AD FS):
Bash:
curl "https://login.microsoftonline.com/getuserrealm.srf?login=user@targetdomain.com&json=1"
Ответ содержит NameSpaceType (Managed или Federated), имя tenant'а и информацию о федерации. Это критическая развилка: если домен federated - появляются дополнительные векторы через AD FS и Golden SAML. Если managed - фокусируемся на прямых атаках на облачные учётки.

Глубокая разведка через AADInternals​

AADInternals - рабочая лошадка фазы reconnaissance. Одна команда даёт больше, чем десяток ручных запросов:
Код:
# Установка модуля
Install-Module AADInternals

# Внешняя разведка без учётных данных
Invoke-AADIntReconAsOutsider -DomainName "targetdomain.com"
Команда возвращает верифицированные домены tenant'а, типы аутентификации для каждого домена, статус Desktop SSO и Seamless SSO. Последнее особенно интересно - если Seamless SSO включён, это гибридная среда с Entra Connect, а значит, потенциальные цепочки атак между on-premise AD и облаком. Два мира - двойная поверхность атаки.

Поиск публичных Azure-ресурсов​

Следующий шаг - обнаружение публично доступных storage account'ов. MicroBurst перебирает типичные naming conventions:
Код:
# Поиск открытых blob-контейнеров
Invoke-EnumerateAzureBlobs -Base targetcompanyname
Публично доступные blob-контейнеры - одна из самых частых и жирных мисконфигураций в Azure. На практике в них валяются бэкапы баз данных, конфигурационные файлы с credentials и даже экспорты Active Directory. Лично находил полный дамп SQL-базы с паролями в plaintext - и это был не стартап, а компания с SOC.

Перечисление пользователей​

Для password spraying нужен список валидных учёток. Инструменты используют тонкие различия в ответах API - при запросе логина для существующего и несуществующего аккаунта Azure возвращает разные ответы. Эффективность энумерации зависит от конфигурации tenant'а: Microsoft постепенно ограничивает информативность ответов. На практике стоит проверять несколько endpoint'ов (GetCredentialType, autodiscover, Teams API) и сравнивать результаты - один может молчать, а другой сливает.

Получение начального доступа к Entra ID​

Начальный доступ в Azure - это почти всегда валидные credentials или токены. По MITRE ATT&CK - техника Cloud Accounts (T1078.004, Initial Access). Забудьте про эксплойты на уровне ОС - здесь другая игра.

Password spraying против Azure AD​

Password spraying - один пароль проверяется на большом количестве учёток. Обходит политики lockout, которые срабатывают на множественные попытки для одного пользователя:
Код:
Import-Module MSOLSpray.ps1
Invoke-MSOLSpray -UserList users.txt -Password "Winter2024!" -OutFile spray-results.txt
Спрей проводится аккуратно - с задержками между попытками. Эффективность шокирует: в средах, где MFA не навязан повсеместно, процент успеха на реальных engagement'ах вполне ощутим. Организации часто не видят эти попытки в логах, особенно если атака идёт с анонимизированной инфраструктуры. Winter2024!, Company123!, Welcome1! - стандартный набор, и он работает чаще, чем хотелось бы.

Device Code phishing - обход MFA без пароля​

Техника, которая может сработать даже против MFA, если в tenant'е не заблокирован device code flow. Device Code authentication - легитимный поток OAuth 2.0 для устройств без браузера. Атакующий генерирует device code и отправляет жертве ссылку. Но сначала проверьте: Conditional Access позволяет блокировать device code flow через политику «Block authentication flows». Microsoft рекомендует организациям блокировать этот flow - если политика настроена, вектор не сработает.
Код:
Import-Module TokenTactics.ps1
Get-AzureToken -Client MSGraph
Команда генерирует device code. Жертва переходит на microsoft.com/devicelogin, вводит код и проходит полную аутентификацию включая MFA. Атакующий получает access token и refresh token для Microsoft Graph API - без знания пароля, с обойдённым MFA. Жертва сама прошла все проверки за вас. По MITRE ATT&CK это пересекается с Spearphishing Link (T1566.002, Initial Access) для доставки и , Credential Access) для результата.

Кража токенов - Steal Application Access Token​

Entra ID целиком построен на токенах, так что кража валидного токена эквивалентна получению учётных данных. Техника Steal Application Access Token (T1528, Credential Access). Access-токены живут 60-90 минут, но refresh-токены могут сохраняться днями и неделями в зависимости от политик.

Кража refresh-токена через AiTM-фишинг (Evilginx2) или с скомпрометированного endpoint'а позволяет генерировать новые access-токены для разных сервисов Microsoft:
Код:
# Оригинальный TokenTactics (rotten-apples/TokenTactics):
Import-Module .\TokenTactics.ps1
Invoke-RefreshToMSGraphToken -domain "contoso.com" -refreshToken "<stolen_refresh_token>"

# TokenTacticsV2 (f-bader/TokenTacticsV2) - альтернативный синтаксис:
# Invoke-RefreshToToken -refreshToken "<stolen_refresh_token>" -resource "https://graph.microsoft.com"

# Запрос данных пользователя
Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} `
  -Uri "https://graph.microsoft.com/v1.0/me"
MFA полностью обходится, потому что токен уже был выпущен после аутентификации. Именно поэтому Continuous Access Evaluation (CAE) и token binding - критичные контроли, а не «nice to have».

Для анализа содержимого токена - декодируем JWT:
Bash:
echo "<token_value>" | cut -d'.' -f2 | base64 --decode 2>/dev/null | python3 -m json.tool
В claims видны audience (aud), scope (scp), tenant ID (tid), object ID пользователя (oid) - всё что нужно для определения дальнейшего вектора.

Обход Conditional Access политик при тестировании безопасности Entra ID​

Conditional Access - политический движок Entra ID, который оценивает сигналы (identity, device compliance, location, sign-in risk) перед предоставлением доступа. В MITRE ATT&CK атаки на Conditional Access описаны как техника Conditional Access Policies (T1556.009) - одновременно Credential Access, Defense Evasion и Persistence.

IMG_7699.webp


На реальных engagement'ах я раз за разом вижу одно и то же: между тем, что показано в Entra Portal, и тем, что реально происходит на уровне MS Graph API - пропасть. Красивые галочки в портале, а под капотом - дыры.

Аудит политик через Graph API​

Начинаем с получения полной картины:
Bash:
curl -X GET "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json"
Парсим вывод и ищем:
  • Политики со state: disabled - выключенные политики, которые администратор «собирался включить» (и забыл, конечно)
  • Политики с пустыми users или applications assignments - дыры в покрытии
  • Отсутствие политик для service principal sign-in'ов

Service Principal sign-in - слепая зона Conditional Access​

Вот ключевой момент, который многие пропускают. По данным исследования AppGovScore, sign-in'ы service principal'ов не покрываются традиционными Conditional Access политиками. По сути - Basic Authentication без ограничений. Для применения CA к workload identities требуется отдельная лицензия Microsoft Entra Workload ID, которую покупают далеко не все.

На практике это значит: если вы скомпрометировали service principal с секретом или сертификатом - Conditional Access для вас не существует. Ни геолокация, ни device compliance, ни sign-in risk не проверяются. Заходи кто хочешь.

Bypass через legacy authentication protocols​

Устаревшие протоколы аутентификации (IMAP, POP3, SMTP AUTH) не поддерживают MFA. С октября 2022 года Microsoft принудительно отключает обычную аутентификацию (логин+пароль) для Exchange Online, и в новых tenant'ах legacy auth по умолчанию недоступен. Однако в legacy-средах, при наличии явных исключений в политиках и для non-Exchange сервисов (например, сторонние SMTP-коннекторы) этот вектор может оставаться актуальным. Проверяйте Authentication Methods policies. На практике исключения встречаются с завидной регулярностью: «для этой переговорки нужен legacy-принтер», «для этого ERP-коннектора нужен SMTP AUTH». Каждое такое исключение - дырка в CA.

Анализ gaps в покрытии​

Типичные gaps, которые находим на engagement'ах:

Тип gapОписаниеИмпакт
Отсутствие CA для workload identitiesSP sign-in без политикПолный обход CA
Исключённые группы«Break glass» аккаунты в exclusion listЗахват через excluded identity
Нет блока legacy authIMAP/POP3 доступныОбход MFA
Неполное покрытие приложенийCA только для Office 365, не для Azure ManagementДоступ к Azure Portal без MFA
Нет device compliance checkЛюбое устройство допускаетсяДоступ с скомпрометированных хостов

Privilege escalation через identity-слой Azure AD​

Эскалация привилегий в Azure - это не kernel exploit. Это мисконфигурации ролей, злоупотребление Service Principal'ами и эксплуатация automation account'ов. По MITRE ATT&CK ключевые техники - , Persistence и Privilege Escalation) и , Defense Evasion и Privilege Escalation).

Маппинг путей эскалации через AzureHound​

AzureHound - Azure-аналог BloodHound, который строит граф связей между identity-объектами и ресурсами:
Bash:
# Синтаксис AzureHound v2.x (проверьте актуальную версию: azurehound --help)
azurehound start --username "compromised@targetdomain.com" --password "password" --tenant "tenantid" -o output.json
Результат загружается в BloodHound и визуализирует пути эскалации, которые вручную искать часами. На одном engagement'е AzureHound показал цепочку из четырёх хопов от рядового пользователя до Global Admin - администраторы клиента были в шоке, потому что каждое отдельное назначение выглядело «нормальным».

Цепочка Application Administrator → Service Principal → Global Admin​

Классический путь эскалации привилегий Azure AD, подтверждённый множественными исследованиями. Конкретный вектор через Office 365 Exchange Online first-party app был устранён Microsoft в августе 2025 года (подробности ниже). Общий принцип - SP с Application.ReadWrite.All → credential injection в другие apps - остаётся актуальным, но перед использованием конкретного PoC проверяйте, доступен ли целевой first-party application для модификации credentials. Согласно исследованию Datadog Security Labs (2025), Service Principal'ы с ролью Cloud Application Administrator, Application Administrator или permission Application.ReadWrite.All могут эскалировать привилегии до Global Administrator.

Механика атаки:
  1. Атакующий получает контроль над SP с ролью Application Administrator
  2. Использует эту роль для добавления credential'а к first-party Microsoft application (в исследовании Datadog - Office 365 Exchange Online)
  3. Аутентифицируется как этот application и получает permission Domain.ReadWrite.All
  4. Добавляет новый federated domain в tenant
  5. Использует сертификат federated domain'а для подделки SAML-токена от имени любого hybrid-пользователя, включая Global Administrator
Код:
# Перечисление текущих role assignments
az role assignment list --assignee compromised@targetdomain.com --all --output table

# Поиск всех role assignments в subscription
az role assignment list --all --include-inherited --output table
Нюанс из исследования Datadog: атака работала только от имени Service Principal, а не от пользовательской identity - из-за специфических контролей на Office 365 Exchange Online application. Microsoft квалифицировал это как «misconfiguration, not a security bypass» и, по данным Datadog Security Labs, начал устранение вектора в 2025 году - актуальность конкретного PoC проверяйте перед тестированием. При пентесте: попробуйте добавить credentials к целевому first-party app (Get-MgServicePrincipal + Add-MgServicePrincipalPassword). Если Microsoft заблокировал операцию - ищите другие first-party apps с аналогичными привилегированными permissions.

Аудит постоянных привилегированных назначений​

Любая identity с постоянной (не eligible) ролью Global Administrator вне документированных break-glass аккаунтов - красный флаг:
Код:
Connect-MgGraph -Scopes "RoleManagement.Read.Directory"

# Получение постоянных назначений роли Global Administrator
$roleId = (Get-MgDirectoryRole | Where-Object { $_.DisplayName -eq "Global Administrator" }).Id
Get-MgDirectoryRoleMember -DirectoryRoleId $roleId | Select-Object DisplayName, UserPrincipalName, Id
Каждая запись здесь, кроме break-glass аккаунтов, должна быть переведена на eligible-назначение через PIM с approval workflow. На практике вижу по 5-10 постоянных Global Admin'ов - «ну а как иначе, нам же работать надо». Вот так и надо, только через PIM.

Злоупотребление Managed Identity​

Managed Identity - механизм, безопасность которого сильно переоценивают. Если VM или Function App имеет назначенную Managed Identity с привилегированной ролью - это прямой путь эскалации:
Bash:
# Запрос токена через endpoint Managed Identity (изнутри VM)
curl "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" -H "Metadata: true"
Если Managed Identity имеет роль Owner или Contributor на subscription - этот токен даёт полный контроль над всеми ресурсами. На engagement'ах видим это регулярно: разработчики назначают Contributor «чтобы точно работало», и забывают. А потом удивляются, откуда у атакующего доступ ко всей подписке.

Federated domain backdoor - персистенция через Trust Modification​

Техника Trust Modification (T1484.002) - одна из самых опасных для персистенции. Атакующий с достаточными привилегиями добавляет новый federated domain в tenant и может подделывать SAML-токены для любого hybrid-пользователя. Согласно исследованию Datadog Security Labs, цепочка выглядит так:
  1. Добавление домена в tenant
  2. Верификация домена (через DNS TXT record)
  3. Конфигурация домена как federated с контролируемым сертификатом
  4. Подделка SAML-токенов от имени любого synced-пользователя
Эта техника использовалась в реальных атаках - задокументирована в кампании StellarParticle (по данным CrowdStrike) и в атаке Midnight Blizzard. Не теоретическая угроза, а боевой приём.

Инструменты для пентеста Entra ID - рабочий арсенал​

Инструментарий для Azure AD red team существенно отличается от классического пентеста. Вот набор, который реально используется на engagement'ах:

ИнструментНазначениеФаза
AADInternalsРазведка tenant, энумерация, атаки на federationReconnaissance, Exploitation
MicroBurstОбнаружение публичных Azure-ресурсовReconnaissance
ROADtoolsДамп и анализ Azure AD через Graph APIPost-compromise enumeration
AzureHoundМаппинг привилегий и путей эскалацииPrivilege escalation
GraphRunnerВзаимодействие с MS Graph после компрометацииPost-compromise, Data access
TokenTacticsМанипуляции с OAuth-токенамиInitial access, Lateral movement
MSOLSprayPassword sprayingInitial access
HawkForensic-анализ компрометации M365Detection, IR

GraphRunner - работа с данными после компрометации​

GraphRunner вытаскивает данные через Microsoft Graph, когда стандартный Azure Portal заблокирован. После компрометации учётки M365 инструмент даёт доступ к email, файлам, Teams-сообщениям - даже если прямой доступ к порталу закрыт Conditional Access. Портал закрыт, а API - нет. Классика мисконфигурации.

ROADtools - полный дамп directory​

ROADtools делает полный дамп Azure AD directory через Graph API и предоставляет локальную базу данных для офлайн-анализа. Можно спокойно ковырять связи между объектами без риска повторных запросов к API, которые могут вызвать alert'ы. Стянул один раз - анализируешь хоть неделю.

Атаки на гибридную инфраструктуру Azure AD

Гибридная среда - пересечение on-premise AD и облачного Entra ID - расширяет атакуемую поверхность в обе стороны. Соединение между on-premise AD и Entra ID через Entra Connect - одна из самых распространённых слабых точек, и атаки через него стабильно попадают в отчёты.

Ключевые компоненты для атак​

Microsoft Entra Connect Sync - основной инструмент синхронизации. Компрометация сервера с Entra Connect позволяет проводить DCSync-атаки, манипулировать синхронизируемыми данными, использовать PHS (Password Hash Synchronization) для извлечения хешей. Один сервер - и у вас ключи от обоих миров.

AD FS - если организация использует федерацию вместо PHS, компрометация AD FS сервера позволяет подделывать security-токены (Golden SAML) и получать доступ к облачным ресурсам без валидного пароля.

Application Proxy - публикует on-premise веб-приложения в облако. Компрометация сервера с Application Proxy agent'ом даёт foothold во внутренней сети.

Рекомендация Microsoft - не синхронизировать учётные записи с высокими привилегиями в on-premise AD (Domain Admins, Enterprise Admins) с Entra ID. По умолчанию Entra Connect исключает только встроенный Administrator (RID 500) - остальные привилегированные аккаунты нужно исключать явно через OU-based или attribute-based filtering. На практике это делают далеко не всегда.

Практический чеклист: что рекомендовать клиенту​

После проведения пентеста Azure AD формируем рекомендации. Приоритизированный список на основе реальных находок:

Защита привилегированных ролей​

Согласно рекомендациям Microsoft по защите engineering systems, активация роли Global Administrator должна требовать approval workflow через PIM. Без этого скомпрометированные credentials дают мгновенную эскалацию. После активации атакующий может создавать новые привилегированные аккаунты, модифицировать Conditional Access политики и ставить backdoor'ы через Service Principal'ы или federation.

Ограничение создания приложений​

Если непривилегированные пользователи могут создавать App Registration и Service Principal'ы - это открытый вектор для начального доступа и персистенции. Атакующие используют эти аккаунты для установки валидных credentials в среде и обхода security-контролей. В документации написано, что по умолчанию это разрешено. Однако на заборе тоже написано.

Мониторинг Service Principal credentials​

Ключевая рекомендация из исследования Datadog: мониторьте добавление credentials к application'ам и Service Principal'ам. Это основной индикатор SP backdooring атаки. Особое внимание - credentials, добавленные к first-party Microsoft application'ам. Они вообще не должны модифицироваться.

Аудит неактивных приложений​

По данным Microsoft, неактивные приложения с привилегированными Microsoft Graph API permission'ами или built-in ролями - лакомые цели для атакующих. Такие приложения позволяют получить начальный доступ без привлечения внимания, потому что они легитимные. Никто не смотрит на app, который «уже два года работает».

Мониторинг trusted domains​

Добавление или изменение federated domain'ов в tenant - критический event, который должен генерировать alert. Federated domain backdoor обеспечивает персистенцию, которая переживает сброс паролей и ротацию секретов. Если у вас нет алерта на Add-MgDomainFederationConfiguration - считайте, что бэкдор уже стоит.

Маппинг атак на MITRE ATT&CK​

Для отчёта по результатам пентеста Azure AD полезно маппить находки на MITRE ATT&CK:

Фаза пентестаТехника ATT&CKТактика
Энумерация пользователейCloud Account (T1087.004)Discovery
Энумерация групп и ролейCloud Groups (T1069.003)Discovery
Password sprayingPassword Spraying (T1110.003)Credential Access
Использование валидных облачных учётокCloud Accounts (T1078.004)Initial Access, Defense Evasion, Persistence, Privilege Escalation
Добавление ролей через SPAdditional Cloud Roles (T1098.003)Privilege Escalation, Persistence
Обход Conditional AccessConditional Access Policies (T1556.009)Credential Access, Defense Evasion, Persistence
MFA fatigueMFA Request Generation (T1621)Credential Access
Device Code phishingSpearphishing Link (T1566.002) + Steal Application Access Token (T1528)Initial Access, Credential Access
Кража OAuth-токеновSteal Application Access Token (T1528)Credential Access
Federated domain backdoorTrust Modification (T1484.002)Privilege Escalation, Defense Evasion

Этот маппинг превращает пентест-отчёт из списка находок в документ, который security-команда клиента может использовать для приоритизации защитных мер.

Пентест Azure AD - это не «сканирование Nessus'ом облачных IP». Это методичная работа с identity-слоем, где каждая мисконфигурация роли, каждый забытый Service Principal, каждый gap в Conditional Access - потенциальный путь к Global Admin. Разница между поверхностной проверкой и реальным engagement'ом - в понимании того, как связаны объекты в Entra ID на уровне Graph API, а не на уровне красивых иконок в портале.

Попробуйте прогнать AzureHound на своём тестовом tenant'е и посмотреть, сколько путей до Global Admin он найдёт. Спорим, результат вас удивит.
 
Последнее редактирование модератором:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab