From c2880afa065a948ca3da4cc78d4a8b26107d50d5 Mon Sep 17 00:00:00 2001 From: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> Date: Fri, 18 Jul 2025 10:26:02 -0400 Subject: [PATCH] [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 --- ...ce_entra_id_oidc_discovery_url_change.toml | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 rules/integrations/azure/persistence_entra_id_oidc_discovery_url_change.toml diff --git a/rules/integrations/azure/persistence_entra_id_oidc_discovery_url_change.toml b/rules/integrations/azure/persistence_entra_id_oidc_discovery_url_change.toml new file mode 100644 index 000000000..beca73539 --- /dev/null +++ b/rules/integrations/azure/persistence_entra_id_oidc_discovery_url_change.toml @@ -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/" +