Techniques
Sample rules
Suspicious Microsoft OAuth Flow via Auth Broker to DRS
- source: elastic
- technicques:
- T1078
- T1528
- T1566
Description
Identifies separate OAuth authorization flows in Microsoft Entra ID where the same user principal and session ID are observed across multiple IP addresses within a 5-minute window. These flows involve the Microsoft Authentication Broker (MAB) as the client application and the Device Registration Service (DRS) as the target resource. This pattern is highly indicative of OAuth phishing activity, where an adversary crafts a legitimate Microsoft login URL to trick a user into completing authentication and sharing the resulting authorization code, which is then exchanged for an access and refresh token by the attacker.
Detection logic
from logs-azure.signinlogs-* metadata _id, _version, _index
| where
event.dataset == "azure.signinlogs" and
event.outcome == "success" and
azure.signinlogs.properties.user_type == "Member" and
azure.signinlogs.identity is not null and
azure.signinlogs.properties.user_principal_name is not null and
source.address is not null and
azure.signinlogs.properties.app_id == "29d9ed98-a469-4536-ade2-f981bc1d605e" and // MAB
azure.signinlogs.properties.resource_id == "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9" // DRS
| eval
Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp),
Esql.azure_signinlogs_properties_session_id = azure.signinlogs.properties.session_id,
Esql.is_browser_case = case(
to_lower(azure.signinlogs.properties.device_detail.browser) rlike "(chrome|firefox|edge|safari).*", 1, 0
)
| stats
Esql_priv.azure_signinlogs_properties_user_display_name_values = values(azure.signinlogs.properties.user_display_name),
Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id),
Esql.azure_signinlogs_properties_unique_token_identifier_values = values(azure.signinlogs.properties.unique_token_identifier),
Esql.source_geo_city_name_values = values(source.geo.city_name),
Esql.source_geo_country_name_values = values(source.geo.country_name),
Esql.source_geo_region_name_values = values(source.geo.region_name),
Esql.source_address_values = values(source.address),
Esql.source_address_count_distinct = count_distinct(source.address),
Esql.source_as_organization_name_values = values(source.`as`.organization.name),
Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol),
Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive),
Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type),
Esql.azure_signinlogs_properties_token_protection_status_details_sign_in_session_status_values = values(azure.signinlogs.properties.token_protection_status_details.sign_in_session_status),
Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id),
Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
Esql.azure_signinlogs_properties_app_owner_tenant_id_values = values(azure.signinlogs.properties.app_owner_tenant_id),
Esql.azure_signinlogs_properties_resource_owner_tenant_id_values = values(azure.signinlogs.properties.resource_owner_tenant_id),
Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
Esql.azure_signinlogs_properties_risk_level_aggregated_values = values(azure.signinlogs.properties.risk_level_aggregated),
Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser),
Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system),
Esql.user_agent_original_values = values(user_agent.original),
Esql.is_browser_case_max = max(Esql.is_browser_case),
Esql.event_count = count(*)
by
Esql.time_window_date_trunc,
azure.signinlogs.properties.user_principal_name,
azure.signinlogs.properties.session_id
| keep
Esql.time_window_date_trunc,
Esql_priv.azure_signinlogs_properties_user_display_name_values,
Esql_priv.azure_signinlogs_properties_user_principal_name_values,
Esql.azure_signinlogs_properties_session_id_values,
Esql.azure_signinlogs_properties_unique_token_identifier_values,
Esql.source_geo_city_name_values,
Esql.source_geo_country_name_values,
Esql.source_geo_region_name_values,
Esql.source_address_values,
Esql.source_address_count_distinct,
Esql.source_as_organization_name_values,
Esql.azure_signinlogs_properties_authentication_protocol_values,
Esql.azure_signinlogs_properties_authentication_requirement_values,
Esql.azure_signinlogs_properties_is_interactive_values,
Esql.azure_signinlogs_properties_incoming_token_type_values,
Esql.azure_signinlogs_properties_token_protection_status_details_sign_in_session_status_values,
Esql.azure_signinlogs_properties_session_id_count_distinct,
Esql.azure_signinlogs_properties_app_display_name_values,
Esql.azure_signinlogs_properties_app_id_values,
Esql.azure_signinlogs_properties_resource_id_values,
Esql.azure_signinlogs_properties_resource_display_name_values,
Esql.azure_signinlogs_properties_app_owner_tenant_id_values,
Esql.azure_signinlogs_properties_resource_owner_tenant_id_values,
Esql.azure_signinlogs_properties_conditional_access_status_values,
Esql.azure_signinlogs_properties_risk_state_values,
Esql.azure_signinlogs_properties_risk_level_aggregated_values,
Esql.azure_signinlogs_properties_device_detail_browser_values,
Esql.azure_signinlogs_properties_device_detail_operating_system_values,
Esql.user_agent_original_values,
Esql.is_browser_case_max,
Esql.event_count
| where
Esql.source_address_count_distinct >= 2 and
Esql.azure_signinlogs_properties_session_id_count_distinct == 1 and
Esql.is_browser_case_max >= 1 and
Esql.event_count >= 2