Entra ID Concurrent Sign-in with Suspicious Properties

Identifies concurrent azure signin events for the same user and from multiple sources, and where one of the authentication event has some suspicious properties often associated to DeviceCode and OAuth phishing. Adversaries may steal Refresh Tokens (RTs) via phishing to bypass multi-factor authentication (MFA) and gain unauthorized access to Azure resources.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2025/04/28"
  3integration = ["azure"]
  4maturity = "production"
  5updated_date = "2026/09/18"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies concurrent azure signin events for the same user and from multiple sources, and where one of the
 11authentication event has some suspicious properties often associated to DeviceCode and OAuth phishing. Adversaries may
 12steal Refresh Tokens (RTs) via phishing to bypass multi-factor authentication (MFA) and gain unauthorized access to
 13Azure resources.
 14"""
 15false_positives = [
 16    """
 17    Users authenticating from multiple devices and using the deviceCode protocol or the Visual Studio Code client.
 18    """,
 19]
 20from = "now-60m"
 21language = "esql"
 22license = "Elastic License v2"
 23name = "Entra ID Concurrent Sign-in with Suspicious Properties"
 24note = """## Triage and analysis
 25
 26### Investigating Entra ID Concurrent Sign-in with Suspicious Properties
 27
 28### Possible investigation steps
 29
 30- Review the sign-in logs to assess the context and reputation of the source.ip address.
 31- Investigate the user account associated with the successful sign-in to determine if the activity aligns with expected behavior or if it appears suspicious.
 32- Check for any recent changes or anomalies in the user's account settings or permissions that could indicate compromise.
 33- Review the history of sign-ins for the user to identify any patterns or unusual access times that could suggest unauthorized access.
 34- Assess the device from which the sign-in was attempted to ensure it is a recognized and authorized device for the user.
 35
 36### Response and remediation
 37
 38- Immediately revoke the compromised Primary Refresh Tokens (PRTs) to prevent further unauthorized access. This can be done through the Azure portal by navigating to the user's account and invalidating all active sessions.
 39- Enforce a password reset for the affected user accounts to ensure that any credentials potentially compromised during the attack are no longer valid.
 40- Implement additional Conditional Access policies that require device compliance checks and restrict access to trusted locations or devices only, to mitigate the risk of future PRT abuse.
 41- Conduct a thorough review of the affected accounts' recent activity logs to identify any unauthorized actions or data access that may have occurred during the compromise.
 42- Escalate the incident to the security operations team for further investigation and to determine if there are any broader implications or additional compromised accounts.
 43- Enhance monitoring by configuring alerts for unusual sign-in patterns or device code authentication attempts from unexpected locations or devices, to improve early detection of similar threats.
 44- Coordinate with the incident response team to perform a post-incident analysis and update the incident response plan with lessons learned from this event."""
 45references = [
 46    "https://learn.microsoft.com/en-us/entra/identity/",
 47    "https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-ins",
 48    "https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/reference-azure-monitor-sign-ins-log-schema",
 49    "https://www.volexity.com/blog/2025/04/22/phishing-for-codes-russian-threat-actors-target-microsoft-365-oauth-workflows/",
 50]
 51risk_score = 73
 52rule_id = "e3bd85e9-7aff-46eb-b60e-20dfc9020d98"
 53setup = """#### Required Azure Entra Sign-In Logs
 54This rule requires the Azure logs integration be enabled and configured to collect all logs, including sign-in logs from Entra. In Entra, sign-in logs must be enabled and streaming to the Event Hub used for the Azure logs integration.
 55"""
 56severity = "high"
 57tags = [
 58    "Domain: Cloud",
 59    "Domain: SaaS",
 60    "Data Source: Azure",
 61    "Data Source: Entra ID",
 62    "Data Source: Entra ID Sign-In",
 63    "Use Case: Identity and Access Audit",
 64    "Use Case: Threat Detection",
 65    "Tactic: Credential Access",
 66    "Resources: Investigation Guide",
 67    "Noise: High",
 68    "Performance: Normal",
 69    "Profile: Aggressive",
 70    "Threat: AiTM Phishing",
 71    "Rule Type: ES|QL",
 72    "Platform: Entra ID",
 73    "Domain: Identity",
 74]
 75timestamp_override = "event.ingested"
 76type = "esql"
 77
 78query = '''
 79from logs-azure.signinlogs-* metadata _id, _version, _index
 80
 81// Scheduled to run every hour, reviewing events from past hour
 82| where
 83  @timestamp > now() - 1 hours
 84  and data_stream.dataset == "azure.signinlogs"
 85  and source.ip is not null
 86  and azure.signinlogs.identity is not null
 87  and to_lower(event.outcome) == "success"
 88
 89// keep relevant raw fields
 90| keep
 91  @timestamp,
 92  azure.signinlogs.identity,
 93  source.ip,
 94  azure.signinlogs.properties.authentication_requirement,
 95  azure.signinlogs.properties.app_id,
 96  azure.signinlogs.properties.resource_display_name,
 97  azure.signinlogs.properties.authentication_protocol,
 98  azure.signinlogs.properties.app_display_name
 99
100// case classifications for identity usage
101| eval
102      Esql.azure_signinlogs_properties_authentication_device_code_case = case(
103      azure.signinlogs.properties.authentication_protocol == "deviceCode"
104      and azure.signinlogs.properties.authentication_requirement != "multiFactorAuthentication",
105      azure.signinlogs.identity,
106      null),
107
108    Esql.azure_signinlogs_auth_visual_studio_case = case(
109      azure.signinlogs.properties.app_id == "aebc6443-996d-45c2-90f0-388ff96faa56"
110      and azure.signinlogs.properties.resource_display_name == "Microsoft Graph",
111      azure.signinlogs.identity,
112      null),
113
114    Esql.azure_signinlogs_auth_other_case = case(
115      azure.signinlogs.properties.authentication_protocol != "deviceCode"
116      and azure.signinlogs.properties.app_id != "aebc6443-996d-45c2-90f0-388ff96faa56",
117      azure.signinlogs.identity,
118      null)
119
120// Aggregate metrics by user identity
121| stats
122    Esql.event_count = count(*),
123    Esql.azure_signinlogs_properties_authentication_device_code_case_count_distinct = count_distinct(Esql.azure_signinlogs_properties_authentication_device_code_case),
124    Esql.azure_signinlogs_properties_auth_visual_studio_count_distinct = count_distinct(Esql.azure_signinlogs_auth_visual_studio_case),
125    Esql.azure_signinlogs_properties_auth_other_count_distinct = count_distinct(Esql.azure_signinlogs_auth_other_case),
126    Esql.azure_signinlogs_properties_source_ip_count_distinct = count_distinct(source.ip),
127    Esql.azure_signinlogs_properties_source_ip_values = values(source.ip),
128    Esql.azure_signinlogs_properties_client_app_values = values(azure.signinlogs.properties.app_display_name),
129    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
130    Esql.azure_signinlogs_properties_auth_requirement_values = values(azure.signinlogs.properties.authentication_requirement)
131  by azure.signinlogs.identity
132
133// Detect multiple unique IPs for one user with signs of deviceCode or VSC OAuth usage
134| where
135  Esql.azure_signinlogs_properties_source_ip_count_distinct >= 2
136  and (
137    Esql.azure_signinlogs_properties_authentication_device_code_case_count_distinct > 0
138    or Esql.azure_signinlogs_properties_auth_visual_studio_count_distinct > 0
139  )
140'''
141
142
143[[rule.threat]]
144framework = "MITRE ATT&CK"
145
146[[rule.threat.technique]]
147id = "T1528"
148name = "Steal Application Access Token"
149reference = "https://attack.mitre.org/techniques/T1528/"
150
151[rule.threat.tactic]
152id = "TA0006"
153name = "Credential Access"
154reference = "https://attack.mitre.org/tactics/TA0006/"
155
156[[rule.threat]]
157framework = "MITRE ATT&CK"
158
159[[rule.threat.technique]]
160id = "T1566"
161name = "Phishing"
162reference = "https://attack.mitre.org/techniques/T1566/"
163
164[[rule.threat.technique.subtechnique]]
165id = "T1566.002"
166name = "Spearphishing Link"
167reference = "https://attack.mitre.org/techniques/T1566/002/"
168
169[rule.threat.tactic]
170id = "TA0001"
171name = "Initial Access"
172reference = "https://attack.mitre.org/tactics/TA0001/"
173
174[[rule.threat]]
175framework = "MITRE ATT&CK"
176
177[[rule.threat.technique]]
178id = "T1078"
179name = "Valid Accounts"
180reference = "https://attack.mitre.org/techniques/T1078/"
181
182[[rule.threat.technique.subtechnique]]
183id = "T1078.004"
184name = "Cloud Accounts"
185reference = "https://attack.mitre.org/techniques/T1078/004/"
186
187[[rule.threat.technique]]
188id = "T1550"
189name = "Use Alternate Authentication Material"
190reference = "https://attack.mitre.org/techniques/T1550/"
191
192[[rule.threat.technique.subtechnique]]
193id = "T1550.001"
194name = "Application Access Token"
195reference = "https://attack.mitre.org/techniques/T1550/001/"
196
197[rule.threat.tactic]
198id = "TA0005"
199name = "Defense Evasion"
200reference = "https://attack.mitre.org/tactics/TA0005/"

Triage and analysis

Investigating Entra ID Concurrent Sign-in with Suspicious Properties

Possible investigation steps

  • Review the sign-in logs to assess the context and reputation of the source.ip address.
  • Investigate the user account associated with the successful sign-in to determine if the activity aligns with expected behavior or if it appears suspicious.
  • Check for any recent changes or anomalies in the user's account settings or permissions that could indicate compromise.
  • Review the history of sign-ins for the user to identify any patterns or unusual access times that could suggest unauthorized access.
  • Assess the device from which the sign-in was attempted to ensure it is a recognized and authorized device for the user.

Response and remediation

  • Immediately revoke the compromised Primary Refresh Tokens (PRTs) to prevent further unauthorized access. This can be done through the Azure portal by navigating to the user's account and invalidating all active sessions.
  • Enforce a password reset for the affected user accounts to ensure that any credentials potentially compromised during the attack are no longer valid.
  • Implement additional Conditional Access policies that require device compliance checks and restrict access to trusted locations or devices only, to mitigate the risk of future PRT abuse.
  • Conduct a thorough review of the affected accounts' recent activity logs to identify any unauthorized actions or data access that may have occurred during the compromise.
  • Escalate the incident to the security operations team for further investigation and to determine if there are any broader implications or additional compromised accounts.
  • Enhance monitoring by configuring alerts for unusual sign-in patterns or device code authentication attempts from unexpected locations or devices, to improve early detection of similar threats.
  • Coordinate with the incident response team to perform a post-incident analysis and update the incident response plan with lessons learned from this event.

References

Related rules

to-top