Статья OAuth Abuse в Azure AD: анатомия ConsentFix-атак и обнаружение в SIEM

Разорванная восковая печать с символом Azure AD и диалогом OAuth лежит на тёмном коврике. Между половинками — латунный ключ, подсвеченный настольной лампой.


Понедельник, 9:17. SOC-аналитик видит sign-in в Azure CLI с IP, который ни разу не мелькал в логах tenant'а. Пользователь - финансовый контроллер. Azure CLI за ним не числится. MFA пройдена штатно, Conditional Access policy не сработала. Через 40 минут тот же IP вытягивает переписку через Microsoft Graph API.

Credential phishing? Нет - пароль цел, MFA не перехвачена, passkey не клонирован. Атакующий получил OAuth authorization code напрямую от жертвы, а дефолтные detection-правила пропустили всё.

Это ConsentFix - browser-native техника consent phishing Microsoft, которая скрещивает ClickFix-стиль социальной инженерии с OAuth 2.0 authorization code flow. По данным CrowdStrike Global Threat Report 2025, 75% вторжений используют действительные учётные данные, а облачные intrusion выросли на 26% за год. ConsentFix - чистое воплощение этого тренда: атака не ломает аутентификацию, а обходит её на уровне авторизации.

Kill chain ConsentFix: от поисковой выдачи до OAuth token hijacking​

Технику обнаружила и задокументировала команда Push Security, перехватив активную кампанию на инфраструктуре нескольких клиентов. Атрибуция на момент публикации не установлена - Push Security описывает кампанию как unattributed, но anti-analysis техники в ней заслуживают отдельного разбора. Ниже - полный kill chain с MITRE ATT&CK-маппингом, привязанный к конкретным артефактам для detection. Подробнее - в нашем руководстве по атаки на аутентификацию.

Фаза 1 - доставка и conditional targeting​

В задокументированных кампаниях жертва попадает на вредоносную страницу через Google Search. Push Security подчёркивает: подавляющее большинство сайтов - легитимные ресурсы с высокой доменной репутацией, в которые инжектирован malicious payload. Страница имитирует Cloudflare Turnstile и запрашивает email-адрес. Это не CAPTCHA - это conditional loading.

Логика targeting:
  • Если домен email не входит в целевой список - атака прекращается, пользователь видит оригинальный контент
  • Если домен совпадает с целевой организацией - загружается фишинговый flow
  • IP-адрес блокируется после первого визита - повторный заход с того же IP не активирует фишинг ни на одном из связанных сайтов
Последний пункт - самый неприятный для аналитиков. Синхронизированная IP-блокировка между всеми площадками кампании. Проверил URL вручную, решил перепроверить - а там уже чистая страница. Push Security отмечает, что это одна из наиболее продвинутых anti-analysis техник в реальных кампаниях, с которыми они сталкивались. На этом этапе атака маппится на Spearphishing Link (T1566.002, Initial Access) и Malicious Link (T1204.001, Execution).

Фаза 2 - OAuth-поток через pre-trusted приложение Microsoft​

Фишинговая страница конструирует OAuth authorization URL для first-party приложения Microsoft - в наблюдавшейся кампании это Azure CLI (App ID: 04b07795-8ddb-461a-bbee-02f9e1bf7b46). URL ведёт на настоящий login.microsoftonline.com. Жертва видит штатную страницу входа. Если пользователь уже авторизован в браузере (в рабочей среде - практически всегда), достаточно выбрать свой аккаунт. MFA проходит штатно, потому что это реальная аутентификация Microsoft.

После успешного входа браузер перенаправляется на http://localhost:<port>/?code=<authorization_code> - стандартное поведение для native-приложений. Жертва видит пустую страницу. Дальше начинается социальная инженерия.

Первое поколение ConsentFix: фишинговая страница просит скопировать URL из адресной строки localhost в поле «верификации».

Второе поколение (автор - John Hammond, собрал через несколько дней после публикации Push Security): popup-окно с Microsoft URL, элемент которого перетаскивается drag-and-drop на фишинговую страницу. Порог подозрительности падает кратно - drag-and-drop ощущается как безобидное действие.

В обоих случаях жертва передаёт authorization code атакующему. Это Steal Application Access Token (T1528, Credential Access).

Фаза 3 - token redemption и post-exploitation​

Authorization code в Entra ID краткоживущий (порядка 10 минут по наблюдениям Mitiga и общей документации Microsoft). Атакующий выполняет POST-запрос к https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token. Azure CLI - public client, секрет приложения для обмена не требуется. Результат: access token и refresh token с делегированными правами жертвы.

С этого момента атакующий действует от имени жертвы без дальнейшего взаимодействия - Application Access Token (T1550.001, Lateral Movement) и Cloud Accounts (T1078.004, Persistence):
  • Чтение почты через Graph API (Mail.Read)
  • Доступ к SharePoint и OneDrive
  • Перечисление ресурсов Azure через ARM API
  • Эскалация привилегий при наличии административных ролей - Additional Cloud Roles (T1098.003)
Refresh token обеспечивает persistent access. Новые access-токены выпускаются без повторной аутентификации. И вот что важно: сброс пароля жертвой не отзывает OAuth-токены автоматически - это отдельная операция, которую SOC должен выполнить вручную. Многие об этом узнают уже после инцидента.

First-party приложения - слепое пятно Azure AD Conditional Access​

Традиционные меры против Azure app consent abuse (ограничение consent, блокировка unverified publishers, admin consent workflow) работают исключительно против third-party приложений. ConsentFix намеренно целится в first-party apps, для которых эти controls бесполезны.

ХарактеристикаFirst-party (Azure CLI)Third-party
Consent в каждом tenantПредварительно одобреноТребует явного consent
Блокировка через Entra admin centerНельзя удалить или заблокировать стандартноБлокируется через Enterprise Apps
Admin consent workflowНе применяетсяПрименяется
Conditional Access exclusionsPre-authorized во многих CA-конфигурациях; часто исключается из baseline policies для admin workflowПолностью покрывается CA
Localhost redirectРазрешён для native flowsНастраивается, не доверен по умолчанию

Fabian Bader (Glueck Kanja) и Dirk-jan Mollema (Outsider Security) идентифицировали 11 first-party приложений, уязвимых к ConsentFix и имеющих известные исключения из Conditional Access:

ПриложениеApp ID
Microsoft Azure CLI04b07795-8ddb-461a-bbee-02f9e1bf7b46
Microsoft Azure PowerShell1950a258-227b-4e31-a9cf-717495945fc2
Microsoft Teams1fec8e78-bce4-4aaf-ab1b-5451cc387264
Microsoft Whiteboard Client57336123-6e14-4acc-8dcf-287b6088aa28
Microsoft Flow Mobile57fcbcfa-7cee-4eb1-8b25-12d2030b4ee0
Enterprise Roaming and Backup60c8bde5-3167-4f92-8fdb-059f6176dc0f
Visual Studio872cd9fa-d31f-45e0-9eab-6e460a02d1f1
Aadrm Admin PowerShell90f610bf-206d-4950-b61d-37fa6fd1b224
SharePoint Online Management Shell9bc3ab49-b65d-410a-85ad-de819febfddc
Microsoft Power Query for Excela672d62c-fc7b-4e81-a576-e60dc46e951d
Visual Studio Codeaebc6443-996d-45c2-90f0-388ff96faa56

11 приложений. Каждое - pre-trusted. Каждое - потенциальный вектор.

Push Security отмечает дополнительную проблему: ConsentFix-кампании используют legacy scopes, не покрытые дефолтным логированием. Событие OAuth abuse может не попасть в audit log без предварительной настройки Diagnostic Settings. Отдельно Microsoft Security Blog документирует кампанию Storm-2949 - credential-based cloud breach без malware, демонстрирующую, как скомпрометированная identity превращается в масштабную утечку данных (прямой связи с ConsentFix не установлено, но паттерн тот же). Identity-based атаки в облаке - это не тренд на горизонте, это то, что прилетает в SOC прямо сейчас.

Обнаружение ConsentFix в Microsoft Sentinel: KQL-запросы и корреляция​

Все действия до момента token redemption проходят через легитимные Microsoft-эндпоинты. Аутентификация настоящая, consent не запрашивается, MFA пройдена. Детектировать нужно по поведенческим аномалиям в post-authentication активности. Здесь нет серебряной пули - только корреляция нескольких слабых сигналов.

Базовый сигнал - аномальный sign-in в CLI-приложения​

Первый индикатор:
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

Корреляция - первое использование токена с нового IP​

Более сильный сигнал. После передачи authorization code атакующий обменивает его на токен и начинает использовать refresh token со своего IP-адреса. Обмен authorization code на токен фиксируется как часть interactive sign-in в SignInLogs. Последующие refresh flows генерируют отдельные события в AADNonInteractiveUserSignInLogs, где IP может отличаться от исходного. В Sentinel это выглядит как non-interactive sign-in с IP, не совпадающим с IP первоначальной аутентификации.
Код:
let interactive = SignInLogs
| where AppId == "04b07795-8ddb-461a-bbee-02f9e1bf7b46"
| where ResultType == 0
| project UserPrincipalName, AuthIP=IPAddress,
    AuthTime=TimeGenerated
| summarize AuthTime=max(AuthTime) by UserPrincipalName, AuthIP;
AADNonInteractiveUserSignInLogs
| where AppId == "04b07795-8ddb-461a-bbee-02f9e1bf7b46"
| where ResultType == 0
| project UserPrincipalName, TokenIP=IPAddress,
    TokenTime=TimeGenerated
| join kind=inner interactive on UserPrincipalName
| where TokenTime between (AuthTime .. AuthTime + 4h)  // refresh flow может произойти позже, чем через 15 мин
| where TokenIP != AuthIP
Interactive sign-in и последующий non-interactive sign-in (refresh flow) с разных IP в окне до 4 часов - высокоприоритетный алерт. Для более точного обнаружения момента token use рекомендую дополнительно коррелировать с MicrosoftGraphActivityLogs, где IP запросов к Graph API можно сравнить с AuthIP. В штатном сценарии токен используется с того же устройства - расхождение IP между аутентификацией и использованием токена почти всегда означает проблему.

Elastic Security Labs в своём исследовании описывают дополнительные detection-сигналы: аномальную регистрацию устройств через Azure Device Registration Service (ADRS), переход от Refresh Token к Primary Refresh Token для одного пользователя и устройства, нетипичное использование PRT с недавно зарегистрированного устройства. Каждый сигнал по отдельности шумный, но в корреляции с sign-in в first-party CLI-приложение - формируют надёжную цепочку.

Hardening-чеклист: закрываем вектор ConsentFix​

Конкретные действия, пригодные для передачи администратору или включения в IR playbook. Приоритизированы по impact на ConsentFix.
  1. Token Protection в Conditional Access - привязывает access-токены к originating device/session. Атакующий, обменявший authorization code на своём устройстве, получит непригодный токен. Требует Entra ID Premium P1/P2. Путь: Entra admin center → Conditional Access → New policy → Session controls → Token Protection. Применить ко всем пользователям или высокорисковым группам. Из всего чеклиста это единственная мера, которая ломает kill chain ConsentFix на уровне протокола.
  2. Ограничение доступа к first-party CLI-приложениям - через Conditional Access создать policy с target на конкретные App ID из таблицы выше. Требовать device compliance или managed network. Рядовым пользователям Azure CLI не нужен - если бухгалтерия стучится в Azure CLI, что-то пошло не так задолго до ConsentFix.
  3. Расширенное логирование OAuth-событий - в Diagnostic Settings для Entra ID включить все категории: SignInLogs, NonInteractiveUserSignInLogs, ServicePrincipalSignInLogs, AuditLogs - и настроить forwarding в SIEM. Без этого ConsentFix-события могут не попасть в лог. На аудитах я регулярно вижу, что NonInteractiveUserSignInLogs просто не включены - а именно там живут refresh flow события.
  4. Continuous Access Evaluation (CAE) - near-real-time revocation токенов при смене условий (IP, risk level). Не блокирует ConsentFix напрямую, но сокращает окно эксплуатации с часов до минут.
  5. Мониторинг новых Device Registration - ConsentFix может использоваться для регистрации rogue-устройства и получения PRT. Алерт на каждую новую регистрацию с корреляцией по UserPrincipalName и времени sign-in.
  6. Phishing-симуляции с ConsentFix-сценарием - объяснить пользователям: localhost-URL после Microsoft-логина никогда не нужно копировать, вставлять или перетаскивать куда-либо. Это единственный момент, где человеческий фактор может разорвать цепочку. Простое правило: «Увидел localhost в адресной строке - закрой вкладку».
Obsidian Security документирует целое семейство смежных техник OAuth abuse - device code phishing, CoPhish (регистрация malicious app в tenant жертвы из скомпрометированного аккаунта), автоматизированные тулкиты Graphish и SquarePhish. Но ConsentFix выделяется тем, что целится в pre-trusted first-party приложения и не требует ни consent prompt, ни admin approval. Из всего семейства OAuth abuse это самый сложный вектор для обнаружения штатными средствами Microsoft Entra ID.

Большинство Conditional Access конфигураций, которые я видел на аудитах, построены по Microsoft-baseline и не учитывают first-party app abuse. Token Protection включён у единиц. Расширенное логирование OAuth - у немногих больше. При этом Verizon DBIR 2025 фиксирует фишинг как начальный вектор примерно в 36% инцидентов, а IBM X-Force отмечает рост атак с действительными учётными данными на 71% за год. ConsentFix попадает точно в эту статистику: формально - фишинг, фактически - OAuth abuse в Azure AD, который прозрачен для всех контролей, выстроенных вокруг парольной аутентификации.

Скорость эволюции техники показательна: John Hammond собрал улучшенную версию за дни после публикации Push Security, Glueck Kanja нашли 11 уязвимых приложений, а красные команды и криминальные группировки неизбежно возьмут ConsentFix на вооружение (если ещё не взяли). Три действия - Token Protection, ограничение CLI-приложений, KQL-правила из этой статьи - существенно сокращают поверхность атаки для задокументированных вариантов ConsentFix. Оставшиеся 10% - это варианты, о которых ещё не написали. Если интересно, как другие команды выстраивают detection для identity-based атак в облаке - на codeby.net идёт обсуждение cloud TTP и OAuth abuse.
 
Мы в соцсетях:

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

Похожие темы

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

HackerLab