Summary
Secureworks® Counter Threat Unit™ (CTU) researchers identified a vulnerability within Azure multi-tenant applications where the application's redirect URI (also known as reply URL) contains a subdomain entry that is registered to the application but not to an Azure resource. These redirect URI endpoints are used to facilitate authorization code flow and can be abused by threat actors to steal users' authorization codes and ID tokens. The threat actors can then use the stolen authorization code to obtain access tokens on behalf of the victim, providing access to the multi-tenant application and the backend Azure APIs while impersonating the victim's account. CTU™ researchers developed code to help administrators identify this vulnerability in their applications.
OAuth 2.0 authorization code flow
The OAuth 2.0 authorization (auth) code flow enables a client application to obtain authorized access to protected resources such as web APIs (see Figure 1).
Figure 1. OAuth 2.0 authorization code flow. (Source: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow)
- A client application tries to access a resource server protected by OAuth 2.0.
- The resource server redirects the client application to the identity provider (e.g., Entra ID).
- The user supplies their credentials to the identity provider.
- The identity provider authenticates the user and returns an authorization code to the client application's redirect URI. The redirect URI defines where the identity provider sends the authorization code (via redirection) after authenticating the user.
- The client application exchanges the authorization code for an access token (and optionally a refresh token).
- The client application passes the access token to the resource server to access protected resources.
In development scenarios, this value is typically set to http://localhost. In production, the value can be an Azure resource or a subdomain hosted by the organization outside of Azure.
Subdomain takeovers
A subdomain takeover occurs when an attacker gains control over a subdomain of a target domain. Organizations can be vulnerable to these takeovers if they lose control over a subdomain by forgetting to renew a service such as Azure or by changing their service provider.
The attacker can then publish malicious content on a subdomain that the organization no longer controls but is still linked to the organization's reputation. The threat actor could conduct phishing against the organization's employees or customers because the previous legitimate use of the subdomain disguises the malicious transition.
Redirect URI takeover
There are many Azure services that allow an organization to create subdomains of a Microsoft-owned domain. Azure App Service allows an organization to create a web application with a unique subdomain in the 'azurewebsites . com' domain. Other services that allow an organization to create subdomains include Azure Traffic Manager profiles and Microsoft Power BI.
When an organization creates an application and that application is used by the OAuth 2.0 authorization code flow, the organization needs to ensure that the redirect URIs remain live and owned by the organization. In some cases, the organization might have lost the subdomain because the resource group where the Azure application resides might have been deleted. As a result, the threat actor could register the compromised organization's multi-tenant application in the attacker's tenant and register the compromised organization's unregistered redirect URI in the appropriate Azure resource. They could deploy code to that Azure resource that intercepts the victim's authorization code and then use the authorization code to obtain access tokens and refresh tokens as the victim.
After taking control of an organization's redirect URI, a threat actor could conduct the following attack:
- The attacker sends a phishing link to an employee of the organization. The link is a Microsoft URL where the redirect_uri or replyUrl parameter contains the compromised redirect URI.
- The employee clicks the link and is prompted to log into Azure (see Figure 2).
Figure 2. Prompt for user credentials. (Source: Secureworks) - The employee is logged into Azure without issue or error, but the threat actor has stolen the employee's authorization code (see Figure 3) to exchange for access tokens.
Figure 3. Stolen authorization code. (Source: Secureworks)
Detecting unregistered redirect URIs
Organizations can use the following process to detect unregistered redirect URIs:
- Identify multi-tenant applications owned by your organization.
- Dump the redirect URIs for each of these applications.
- Strip the URL schemas and ports to retain only the fully qualified domain name (FQDN) for the redirect URI.
- Perform a DNS A record lookup for each FQDN to determine if any of the FQDNs are missing DNS records. An FQDN that does not have an associated DNS record is a prime target for attackers.
CTU researchers wrote a bash script that leverages the Azure CLI Linux tool to help organizations identify unregistered redirect URIs:
#!/bin/bash # Set your organization's tenant ID tenantId="<Your Tenant ID>" # Function to strip URL scheme and port from FQDN strip_scheme_and_port() { local fqdn=$1 echo "$fqdn" | sed -e 's|^[^/]*//||' -e 's|:[^/]*$||' } # Function to print in green color print_green() { echo -e "\e[32m$1\e[0m" } # Get all multi-tenant applications owned by your organization apps=$(az ad app list --query "[?appRoles && (publicClient || identifierUris) && ownerId=='$tenantId']" --output json) # Extract and perform DNS A record lookup for each application echo "Performing DNS A record lookup for multi-tenant applications:" echo for row in $(echo "${apps}" | jq -c '.[]'); do appId=$(echo "${row}" | jq -r '.appId') replyUrls=$(echo "${row}" | jq -r '.replyUrls[]') echo "Application ID: ${appId}" echo "Original ReplyUrls: ${replyUrls}" # Strip URL scheme and port from each replyUrl for url in $replyUrls; do stripped_url=$(strip_scheme_and_port "$url") echo "Stripped URL: ${stripped_url}" # Perform DNS A record lookup using host command if host "$stripped_url" >/dev/null 2>&1; then echo "DNS record found for $stripped_url." else # Print message in green for unregistered URLs print_green "[ + ] Unregistered URL Found: $stripped_url" fi echo done echo done
After identifying all potential unregistered redirect URIs, organizations need to go into Azure resources and claim these subdomains so threat actors cannot abuse them. The following root domains are common sources of unregistered redirect URIs:
- If the root domain is azurewebsites . com, the Azure resource is Azure App Service. Other root domains tied to Azure App Service are also vulnerable to this kind of attack, so the Azure resource should be inspected for additional root domains.
- If the root domain is trafficmanager . com, the Azure resource is Traffic Manager profiles.
Conclusion
Redirect URI takeover is a form of subdomain takeover. The difference is that a redirect URI takeover could allow an attacker to obtain access tokens and refresh tokens and then perform actions in your tenant while masquerading as users within your organization. By reviewing your application redirect URIs and claiming unregistered subdomains, you have a better chance of preventing these types of attacks.