Adversaries may modify OAuth application redirect URIs to intercept authorization codes and steal access tokens. SOC teams should proactively hunt for this behavior in Azure Sentinel to detect potential token theft and mitigate credential compromise risks.
KQL Query
let timeframe = 1d;
AuditLogs
| where TimeGenerated >= ago(timeframe)
| where OperationName =~ "Update application"
| where Result =~ "success"
| mv-expand ModProp = TargetResources[0].modifiedProperties
| where tostring(ModProp.displayName) =~ "ReplyUrls"
| extend OldReplyUrls = tostring(ModProp.oldValue)
| extend NewReplyUrls = tostring(ModProp.newValue)
| extend AppName = tostring(TargetResources[0].displayName)
| extend AppId = tostring(TargetResources[0].id)
| extend ActorUpn = tostring(InitiatedBy.user.userPrincipalName)
| extend ActorApp = tostring(InitiatedBy.app.displayName)
| extend ActorIp = iff(
isnotempty(tostring(InitiatedBy.user.ipAddress)),
tostring(InitiatedBy.user.ipAddress),
tostring(InitiatedBy.app.ipAddress))
| extend AccountName = iff(ActorUpn has "@",
tostring(split(ActorUpn, "@")[0]), "")
| extend AccountUPNSuffix = iff(ActorUpn has "@",
tostring(split(ActorUpn, "@")[1]), "")
| project
TimeGenerated,
AppName,
AppId,
OldReplyUrls,
NewReplyUrls,
ActorUpn,
ActorApp,
AccountName,
AccountUPNSuffix,
ActorIp,
CorrelationId
| sort by TimeGenerated desc
id: 32cf350a-01f8-4c84-9e47-4302e275eda3
name: OAuth application redirect URI modified
description: Identifies modifications to OAuth application redirect URIs in Entra ID. Adding a redirect URI controlled by an attacker allows interception of OAuth authorization codes, enabling token theft from users who authenticate against the application.
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
tactics:
- Persistence
- CredentialAccess
relevantTechniques:
- T1528
query: |
let timeframe = 1d;
AuditLogs
| where TimeGenerated >= ago(timeframe)
| where OperationName =~ "Update application"
| where Result =~ "success"
| mv-expand ModProp = TargetResources[0].modifiedProperties
| where tostring(ModProp.displayName) =~ "ReplyUrls"
| extend OldReplyUrls = tostring(ModProp.oldValue)
| extend NewReplyUrls = tostring(ModProp.newValue)
| extend AppName = tostring(TargetResources[0].displayName)
| extend AppId = tostring(TargetResources[0].id)
| extend ActorUpn = tostring(InitiatedBy.user.userPrincipalName)
| extend ActorApp = tostring(InitiatedBy.app.displayName)
| extend ActorIp = iff(
isnotempty(tostring(InitiatedBy.user.ipAddress)),
tostring(InitiatedBy.user.ipAddress),
tostring(InitiatedBy.app.ipAddress))
| extend AccountName = iff(ActorUpn has "@",
tostring(split(ActorUpn, "@")[0]), "")
| extend AccountUPNSuffix = iff(ActorUpn has "@",
tostring(split(ActorUpn, "@")[1]), "")
| project
TimeGenerated,
AppName,
AppId,
OldReplyUrls,
NewReplyUrls,
ActorUpn,
ActorApp,
AccountName,
AccountUPNSuffix,
ActorIp,
CorrelationId
| sort by TimeGenerated desc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: ActorUpn
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ActorIp
version: 1.0.0
metadata:
source:
kind: Community
author:
name: descambiado
support:
tier: Community
categories:
domains: [ "Security - Threat Protection", "Identity" ]
| Sentinel Table | Notes |
|---|---|
AuditLogs | Ensure this data connector is enabled |
Scenario: Scheduled Job Updates Redirect URI
Description: A legitimate scheduled job (e.g., Azure Automation) updates an OAuth application’s redirect URI as part of a routine configuration refresh.
Filter/Exclusion: Check for known scheduled job names or execution accounts (e.g., azureautomation, runas), and exclude updates made by service accounts or during maintenance windows.
Scenario: Admin Task to Update Redirect URI for Compliance
Description: An admin manually updates the redirect URI to align with new compliance requirements or domain changes.
Filter/Exclusion: Exclude changes made by admin accounts with elevated privileges (e.g., [email protected], AAD_Admin) or during known compliance update windows.
Scenario: CI/CD Pipeline Deploys New Application Configuration
Description: A CI/CD pipeline (e.g., Azure DevOps, GitHub Actions) deploys new application configurations, including OAuth redirect URIs.
Filter/Exclusion: Exclude changes made by CI/CD service accounts (e.g., azure-pipelines, github-actions) or during deployment windows.
Scenario: Third-Party SaaS Tool Integration
Description: A third-party SaaS tool (e.g., Salesforce, ServiceNow) integrates with Entra ID and dynamically updates redirect URIs during setup.
Filter/Exclusion: Exclude changes made by known third-party service principals (e.g., [email protected], [email protected]) or during integration setup phases.
Scenario: User-Driven Redirect URI Change for Personal App
Description: A user modifies the redirect URI for a personal application (e.g., a custom tool or script) without administrative oversight.
Filter/Exclusion: Exclude changes made by users with limited permissions (e.g., [email protected]) or where the redirect