Понедельник, 10:40 - на red team-проекте для финтех-компании я зарегистрировал OAuth-приложение «HR Document Portal» в стороннем тенанте Azure AD. 10:55 - отправил три письма с ссылкой на login.microsoftonline.com. 11:20 - первый сотрудник нажал «Принять» на экране согласия. К полудню через Microsoft Graph API я читал переписку CFO и выгружал документы из SharePoint.
MFA включена. Conditional Access настроен. Фишинговые тренинги проведены. Ни один алерт не сработал - потому что пароль никто не крал и MFA никто не обходил. Пользователь сам выдал разрешения, а OAuth-токен сделал остальное.
По данным CrowdStrike Global Threat Report 2025, 75% вторжений в 2024 году использовали действительные учётные данные для первоначального доступа, а рост облачных инцидентов составил 26% год к году. Consent phishing OAuth атаки - один из драйверов этой статистики. И большинство SOC до сих пор мониторят не тот слой.
Место consent phishing OAuth атак в цепочке атаки
Consent phishing - не точечная техника, а полноценный attack path. Одна фишинговая ссылка разворачивается в цепочку, покрывающую семь тактик MITRE ATT&CK: Подробнее - в нашем руководстве по атаки на аутентификацию.| Этап kill chain | MITRE ATT&CK | Техника | Что происходит |
|---|---|---|---|
| Initial Access | T1566.002 | Spearphishing Link | Жертва получает ссылку с OAuth authorization URL |
| Credential Access | T1528 | Steal Application Access Token | Атакующий получает access и refresh token |
| Lateral Movement | T1550.001 | Application Access Token | Токен используется для доступа к ресурсам |
| Persistence | T1078.004 | Cloud Accounts | Refresh token обеспечивает долгосрочный доступ |
| Persistence | T1098.002 | Additional Email Delegate Permissions | Настройка пересылки или делегирования почты |
| Collection | T1114.002 | Remote Email Collection | Выгрузка писем через Graph API |
| Privilege Escalation | T1098.003 | Additional Cloud Roles | Назначение ролей через скомпрометированный токен |
Вот что тут принципиально для SOC-команды: атакующий работает на уровне authorization (что приложению разрешено), а не authentication (кто пользователь). MFA, passkeys, phishing-resistant authenticators - всё это защищает аутентификацию. Авторизацию - нет. По данным Obsidian Security, после получения consent ни MFA, ни сброс пароля не отзывают OAuth-токены - доступ живёт до явного revoke. На практике это недели и месяцы.
Следствие простое: мониторинг sign-in events недостаточен. Нужен мониторинг consent grants и API-активности - принципиально другой detection layer.
Как работает OAuth consent phishing: атака по шагам
Разберём типичный attack flow - так, как его реализуют с ROADtools и GraphRunner на red team-проектах.Шаг 1 - регистрация приложения. Атакующий регистрирует OAuth-приложение в своём тенанте Azure AD. Название - что-нибудь скучное и доверительное: «Secure Document Viewer», «IT Helpdesk Portal». Запрашиваемые permission scopes:
Mail.Read, Mail.Send, Files.ReadWrite.All, offline_access. Последний scope - ключ к persistence: он обеспечивает выдачу refresh token.Шаг 2 - формирование OAuth URL. Authorization URL содержит:
client_id приложения, scope с нужными permissions, redirect_uri на контролируемый атакующим endpoint, login_hint с email жертвы (адрес предзаполнен - порог подозрительности ниже). Как отмечает команда Elastic Security Labs, параметры кастомизируемы - атакующий подставляет нужный client_id, scope и redirect_uri под конкретную операцию.Шаг 3 - доставка. Фишинговое письмо с лурой - «Документ требует вашего подтверждения» - содержит ссылку. Жертва кликает, видит настоящий login.microsoftonline.com. Проходит MFA, затем видит consent screen с запросом разрешений. Страница входа легитимная. Фейковой landing page нет. Именно поэтому стандартные антифишинговые решения молчат.
Шаг 4 - consent и получение токена. Пользователь нажимает «Принять». Authorization code улетает на redirect_uri атакующего. С помощью ROADtools код обменивается на access token и refresh token через POST к token endpoint Microsoft.
Шаг 5 - post-exploitation. Access token открывает Microsoft Graph API: чтение почты (
GET /me/messages), файлы OneDrive, отправка от имени жертвы. Refresh token обновляет доступ без участия пользователя - тихо, в фоне. GraphRunner автоматизирует эту фазу: email dumping, поиск по ключевым словам, выгрузка SharePoint.По данным Verizon DBIR 2025, 68% утечек связаны с человеческим фактором. Consent phishing бьёт в привычку нажимать «Принять» на consent-экранах - а это штатная часть рабочего дня с облачными сервисами. Люди привыкли.
Три варианта consent phishing и их detection-характеристики
Классический consent phishing (Illicit Consent Grant)
Описанный выше сценарий: стороннее вредоносное OAuth приложение, consent prompt, redirect на URI атакующего. Работает против тенантов, где user consent разрешён - а это дефолтная настройка во многих организациях.Применимость: внешний red team, bug bounty, тенанты с дефолтными настройками consent. Блокируется настройкой «Do not allow user consent» в Entra admin center. Одна галочка - и вектор закрыт. Но эту галочку ставят единицы.
Device code phishing
Эксплуатирует OAuth 2.0 Device Authorization Grant - поток для устройств без браузера (Smart TV, CLI). Атакующий инициирует device code flow для first-party приложения Microsoft, получает код и verification URL, затем убеждает жертву ввести код на легитимной страницеmicrosoft.com/devicelogin.Публично известны несколько open-source инструментов для device code phishing (TokenTactics - самый популярный), а коммерциализация подобных тулкитов наблюдается исследователями. Порог входа для атакующих снижается с каждым годом.
Применимость: работает даже при запрете user consent - device code flow использует pre-consented first-party приложения Microsoft (Azure CLI, PowerShell). Детект сложнее: пользователь фокусируется на вводе кода и не анализирует, какое приложение авторизуется.
ConsentFix: эволюция техники
В 2025 году исследователи (в том числе Volexity) описывали технику, скрещивающую ClickFix-стиль социальной инженерии с OAuth 2.0, применяемую группой UTA0352 (ConsentFix - авторская категоризация в этой статье, не устоявшийся термин). Жертва проходит легитимную аутентификацию для first-party приложения (Azure CLI, App ID04b07795-8ddb-461a-bbee-02f9e1bf7b46). Браузер перенаправляется на localhost URI с authorization code в параметрах. Фишинговая страница инструктирует жертву скопировать или перетащить URL с кодом - якобы для «исправления ошибки». Ранние варианты требовали copy-paste, улучшенные позволяют drag-and-drop.Для SOC: ConsentFix не вызывает consent prompt. First-party приложения pre-trusted в каждом тенанте Entra ID, им не нужен дополнительный consent для базовых scopes. Политики ограничения user consent тут бесполезны.
Внутренние вредоносные приложения (in-tenant malicious OAuth app)
Отдельная история - in-tenant malicious OAuth app: атакующий сначала компрометирует учётную запись с правами регистрации приложений, затем создаёт вредоносное OAuth-приложение внутри тенанта жертвы. Такое приложение выглядит как внутренний инструмент - знакомый брендинг, доменное имя организации. Пользователи доверяют ему больше, а политики блокировки внешних приложений не срабатывают.Применимость: внутренний пентест, post-compromise persistence, insider threat. Детект: мониторинг App Registration в Audit logs.
| Вариант | Consent prompt | Обход user consent policy | Ключевая телеметрия | Сложность детекта |
|---|---|---|---|---|
| Классический | Да | Нет | Consent to application в Audit logs | Средняя |
| Device code | Минимальный | Да | deviceCode в Sign-in logs | Высокая |
| ConsentFix | Нет | Да | Localhost redirect, аномальный IP redemption | Высокая |
| In-tenant malicious app | Зависит от настроек | Нет (приложение внутри тенанта) | App Registration в Audit logs | Средняя |
Detection: телеметрия, правила корреляции, слепые зоны
Требования к окружению
- Microsoft Entra ID P1/P2 (для полных Sign-in и Audit logs)
- Forwarding логов в SIEM: Microsoft Sentinel, Elastic 8.x+, Splunk через Diagnostic Settings
- Defender for Cloud Apps лицензия (для OAuth-политик)
- Для Elastic detection rules: версия 8.x+ с модулем Azure integration
Что искать в Azure AD
Audit logs - событие «Consent to application».
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Правила корреляции для SIEM
KQL-запрос для Microsoft Sentinel - подозрительные consent grants:
Код:
AuditLogs
| where OperationName == "Consent to application"
| extend appName = tostring(TargetResources[0].displayName)
| extend userUPN = tostring(InitiatedBy.user.userPrincipalName)
| mv-expand modProp = TargetResources[0].modifiedProperties
| where tostring(modProp.displayName) == "ConsentAction.Permissions"
| extend perms = tostring(modProp.newValue)
| where perms has_any ("Mail.Read","Mail.Send","Files.ReadWrite")
| project TimeGenerated, userUPN, appName, perms
Код:
SigninLogs
| where AuthenticationProtocol == "deviceCode"
| where ResultType == 0
| where ResourceDisplayName == "Microsoft Graph"
| where IPAddress !in (known_corporate_ips)
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress
Defender for Cloud Apps: встроенные OAuth-политики
Defender for Cloud Apps содержит ряд встроенных шаблонов OAuth-политик (не все включены по умолчанию - состав зависит от тенанта и лицензии):- Malicious OAuth app consent - сканирование через Microsoft Threat Intelligence
- Suspicious OAuth app file download activities - аномальная активность скачивания файлов
- Unusual addition of credentials to an OAuth app - добавление новых credentials к приложению
- Unusual ISP for an OAuth App - API-вызовы с нетипичного провайдера
- Misleading OAuth app name - приложение с названием, мимикрирующим под легитимное
- Misleading publisher name for OAuth app - имя издателя, похожее на крупного вендора
Слепые зоны detection-стека
Device code flow создаёт минимум отличительных сигналов - авторизация на легитимных доменах Microsoft, без фейковых страниц. Выглядит как обычный логин.First-party apps (Azure CLI, VSCode, PowerShell) часто исключены из Conditional Access - слепая зона для многих конфигураций. Администраторы боятся сломать DevOps-пайплайны и добавляют исключения. Атакующие это знают.
API-активность через OAuth-токены не генерирует интерактивных sign-in событий - стандартные правила аномальных логинов не срабатывают.
Refresh token позволяет атакующему месяцами обновлять access token без единого алерта, если начальный consent не был замечен.
Отсутствие baseline для OAuth consent - большинство организаций не знают, какие приложения имеют consent и какие scopes выданы. Сложно детектить аномалию, если нет нормы.
Detection consent phishing требует мониторинга authorization layer, а не только authentication layer. Для большинства SOC-команд это означает пересмотр detection-стратегии.
Чеклист харденинга: защита от вредоносных OAuth приложений Azure AD
Готовый список для администратора Entra ID - каждый пункт закрывает конкретный вектор. Можно копировать в отчёт или тикет.- Запретить user consent. Entra admin center → Enterprise Applications → Consent and permissions → «Do not allow user consent». Маршрутизирует все consent-запросы на администратора.
- Включить admin consent workflow. Enterprise Applications → User Settings → «Users can request admin consent» → Enabled. Назначить ревьюеров из ролей Global Admin / Cloud App Admin / Application Admin.
- Исключить только сервисные аккаунты с подтверждённой потребностью.
- Ограничить first-party apps. Conditional Access policy для App ID Azure CLI (
04b07795-8ddb-461a-bbee-02f9e1bf7b46) и Azure PowerShell (1950a258-227b-4e31-a9cf-717495945fc2): require compliant device. Да, DevOps будут жаловаться. Но без этого device code phishing и ConsentFix работают из коробки. - Включить Token Protection. Conditional Access → Session → Token Protection → Enabled. Привязывает access token к устройству аутентификации. Требует Entra ID P1/P2.
- Активировать CAE (Continuous Access Evaluation). Отзыв токенов в near-real-time при смене IP, блокировке учётной записи. Работает для Exchange Online, SharePoint, Teams.
- Настроить publisher verification. Разрешить consent только для verified publishers. Настроить Permission Classifications для low-risk permissions.
- Провести ревизию существующих OAuth-приложений. Enterprise Applications → фильтр «User consent». Отозвать consent для приложений с избыточными scopes. Периодичность: раз в квартал. (Спойлер: на первой ревизии вы найдёте много интересного.)
- Активировать OAuth-политики Defender for Cloud Apps. Убедиться, что все шесть политик включены. Настроить алерты на SOC-email.
- Forwarding логов в SIEM. Azure AD Diagnostic Settings → Audit Logs и Sign-in Logs → Microsoft Sentinel / Elastic / Splunk. Создать detection rules (KQL-запросы выше).
Большинство SOC-команд уверены, что MFA и Conditional Access закрывают вопрос компрометации облачных аккаунтов. Consent phishing ломает это допущение: атакующий получает токен, работающий независимо от всех аутентификационных мер.
На моей практике - несколько red team-проектов в финтехе и ритейле - время до обнаружения consent-based компрометации составляло от трёх до шести недель. За это время через Graph API уходят тысячи писем и документов, настраиваются правила пересылки (T1098.002, Persistence), а если жертва - администратор, атакующий назначает себе роли (T1098.003) и получает контроль над тенантом.
Регуляторные последствия тоже конкретные: утечка почты с персональными данными через OAuth-токен - нарушение 152-ФЗ и потенциально GDPR, с оборотными штрафами и обязательным уведомлением регулятора.
IBM X-Force фиксирует рост атак с использованием действительных учётных данных на 71% год к году за 2024. CrowdStrike независимо указывает 75% вторжений с valid credentials - это разные метрики (рост vs доля), но обе подтверждают один тренд. Consent phishing питает эту статистику.
Проблема не в технологиях: Token Protection и CAE существуют. Проблема в том, что настройки consent в большинстве тенантов стоят в дефолте, device code flow не заблокирован, а ревизия OAuth-приложений проводилась последний раз - никогда. Это не уязвимость, это misconfiguration, превращающая каждого сотрудника в точку входа. Тематический тред с playbook по этой группе TTP - на codeby.net.