[New Rule] OIDC Discovery URL Changed in Entra ID (#4908)

* new rule OIDC Discovery URL Changed in Entra ID

* added references

* removed indexes

* Update rules/integrations/azure/persistence_entra_id_oidc_discovery_url_change.toml

* adjusted for ESQL standardization
This commit is contained in:
Terrance DeJesus
2025-07-18 10:26:02 -04:00
committed by GitHub
parent a3a2fcdff5
commit c2880afa06
@@ -0,0 +1,104 @@
[metadata]
creation_date = "2025/07/14"
integration = ["azure"]
maturity = "production"
updated_date = "2025/07/14"
[rule]
author = ["Elastic"]
description = """
Detects a change to the OpenID Connect (OIDC) discovery URL in the Entra ID Authentication Methods Policy. This behavior
may indicate an attempt to federate Entra ID with an attacker-controlled identity provider, enabling bypass of
multi-factor authentication (MFA) and unauthorized access through bring-your-own IdP (BYOIDP) methods.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "OIDC Discovery URL Changed in Entra ID"
note = """## Triage and analysis
### Investigating OIDC Discovery URL Changed in Entra ID
This rule detects when the OIDC `discoveryUrl` is changed within the Entra ID Authentication Methods policy. Adversaries may leverage this to federate Entra ID with a rogue Identity Provider (IdP) under their control, allowing them to authenticate users with attacker-owned credentials and bypass MFA. This misconfiguration allows an attacker to impersonate valid users by issuing tokens via a third-party OIDC IdP while still passing validation in Entra ID. This technique has been publicly demonstrated and has critical implications for trust in federated identity.
### Possible investigation steps
- Review `azure.auditlogs.properties.initiated_by.user.userPrincipalName` and `ipAddress` to identify who made the change and from where.
- Examine the `old_oidc_discovery` and `new_oidc_discovery` to confirm if the new `discoveryUrl` points to an unexpected or untrusted IdP.
- Check that the discovery URLs have `.well-known/openid-configuration` endpoints, which are standard for OIDC providers.
- Use `azure.auditlogs.properties.correlation_id` to pivot to related changes and activity from the same session.
- Review any subsequent sign-in activity that may have originated from the new IdP.
- Pivot to additional logs associated with the user or application that made the change to identify any further suspicious activity.
### False positive analysis
- Entra ID administrators may intentionally reconfigure OIDC trust relationships to support new business requirements.
- Validate any changes with the identity or security operations team before taking action.
### Response and remediation
- If the change is unauthorized, immediately revert the discovery URL to the trusted IdP via the Entra ID portal.
- Revoke tokens or sessions issued after the configuration change.
- Investigate how the unauthorized change occurred (e.g., compromised account or over-privileged app).
- Apply conditional access policies and change control procedures to protect IdP configuration changes.
"""
references = ["https://dirkjanm.io/persisting-with-federated-credentials-entra-apps-managed-identities/"]
risk_score = 73
rule_id = "498e4094-60e7-11f0-8847-f661ea17fbcd"
severity = "high"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Data Source: Azure",
"Data Source: Microsoft Entra ID",
"Data Source: Microsoft Entra ID Audit Logs",
"Use Case: Identity and Access Audit",
"Tactic: Persistence",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
FROM logs-azure.auditlogs-*
| WHERE event.action == "Authentication Methods Policy Update"
| EVAL Esql.azure.auditlogs.properties.target_resources.modified_properties.new_value.replace = REPLACE(`azure.auditlogs.properties.target_resources.0.modified_properties.0.new_value`, "\\\\", "")
| EVAL Esql.azure.auditlogs.properties.target_resources.modified_properties.old_value.replace = REPLACE(`azure.auditlogs.properties.target_resources.0.modified_properties.0.old_value`, "\\\\", "")
| DISSECT Esql.azure.auditlogs.properties.target_resources.modified_properties.new_value.replace "%{}discoveryUrl\":\"%{Esql.azure.auditlogs.properties.auth.oidc.discovery.url.new}\"}%{}"
| DISSECT Esql.azure.auditlogs.properties.target_resources.modified_properties.old_value.replace "%{}discoveryUrl\":\"%{Esql.azure.auditlogs.properties.auth.oidc.discovery.url.old}\"}%{}"
| WHERE Esql.azure.auditlogs.properties.auth.oidc.discovery.url.new IS NOT NULL and Esql.azure.auditlogs.properties.auth.oidc.discovery.url.old IS NOT NULL
| WHERE Esql.azure.auditlogs.properties.auth.oidc.discovery.url.new != Esql.azure.auditlogs.properties.auth.oidc.discovery.url.old
| KEEP
@timestamp,
event.action,
event.outcome,
azure.tenant_id,
azure.correlation_id,
azure.auditlogs.properties.activity_datetime,
azure.auditlogs.properties.operation_type,
azure.auditlogs.properties.initiated_by.user.userPrincipalName,
azure.auditlogs.properties.initiated_by.user.displayName,
azure.auditlogs.properties.initiated_by.user.ipAddress,
source.geo.city_name,
source.geo.region_name,
source.geo.country_name,
Esql.azure.auditlogs.properties.auth.oidc.discovery.url.new,
Esql.azure.auditlogs.properties.auth.oidc.discovery.url.old
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"
[[rule.threat.technique.subtechnique]]
id = "T1556.009"
name = "Conditional Access Policies"
reference = "https://attack.mitre.org/techniques/T1556/009/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"