Security Advisories
6 minutes

Behind the Breach: Cross-tenant Impersonation in Okta

In recent investigations, the Obsidian Threat Research team has observed multiple instances of cross-tenant impersonation used to establish persistence and escalate user privileges within Okta environments.

This technique poses a significant risk to organizations that rely on Okta for identity management, as it allows attackers to access and impersonate any legitimate user, accessing critical systems and exfiltrating sensitive data.

In this blog post, we’ll break down the steps associated with cross-tenant impersonation and provide guidance for detecting and responding to this technique within your organization’s SaaS environment. 

What is cross-tenant impersonation?

To perform cross-tenant impersonation, an attacker must first gain privileged access to an organization’s Okta Admin Console.

Once this access is established, the threat actor sets up a new SAML or OpenID Connect (OIDC) Identity Provider (IdP) in Okta. This allows them to authenticate as any user in the Okta environment without the need for credentials. Combined with a modified MFA policy, this technique bypasses all safeguards–enabling a complete takeover of the authentication system.

How can Okta be configured?

Okta can be configured in two ways: as the main IdP or as a service provider that relies on an external IdP for authentication (an inbound IdP). In the case of an inbound IdP, Okta doesn’t handle authentication on its own. Instead, it relies on the authentication provided by the inbound IdP and functions solely as a service provider.

What are the stages of cross-tenant impersonation?

Attackers typically follow these steps to secure unauthorized access to an Okta environment:

Gain administrator access. The attacker gains access to the administrator’s account, employing one of many techniques, such as phishing, token theft, or even social engineering of the helpdesk.

Configure a second IdP. The attacker creates and deploys their own IdP to act as an “impersonation app” so they can access applications within the Okta environment. Find out more by reading Adam Chester blog post on Okta for Red Teamers.

Define the new IdP in Okta. The attacker registers a new SAML or OIDC IdP in Okta.

Here’s an example of a malicious SAML IdP:

Establish account matching. To enable authentication attestation for Okta, the threat actor connects their IdP with user accounts.

Here’s an example to illustrate this.

Let’s assume the compromised user’s email address is the name from an inbound IdP. We’ll employ the user@victim.com for both the attacker and victim accounts. Our primary objective is to instruct Okta to link the IdP username to idpuser.userPrincipalName and align it with the Okta Username. This is possible because attackers can generate arbitrary identity assertions through a fully controlled and trusted inbound IdP:

When dealing with domains that are not entirely under our control, we may need to employ the Okta Expression Language to map the target account. For instance, if the provided username is “user@attacker.com,” we can reconstruct the full name using the formula provided below.

String.append(String.substringBefore(idpuser.userPrincipalName,”@”),”@victim.com”

We can also leverage just-in-time (JIT) provisioning, eliminating the manual process of user provisioning and account creation. Okta will automatically generate new users and assign them to a designated user group with administrative privileges, expanding their access to the environment.  

The following configuration showcases both of these methods:

Configure routing rules. The attacker implements a routing rule so their IdP can coexist with the legitimate Okta IdP–without disruption and free from detection.

Let’s explore an example that shows what this might look like:

Below is a configuration that will cause any authentication from an “Other mobile” device to be routed through our malicious IdP. As we can control what user agent we send to Okta, we can force our authentications to be processed through the IdP with a low chance of a valid user being sent to our malicious IdP.

Alter sign-on policies. Depending on the configuration, the current sign-on policies may continue to request Multi-Factor Authentication (MFA) even when authenticating from an inbound IdP. If MFA is reset during an Incident Response (IR) remediation or the attacker has never registered MFA for the target account, they could be locked out. To address this, we can implement a new rule that allows us to bypass MFA or modify existing rules to ensure authentication follows the default sign-on rule.

(Note: Okta requires the configuration of two sign-on policies – a global sign-on policy and a per-app sign-on policy. To successfully bypass Multi-Factor Authentication (MFA), an attacker must manipulate settings in both.)

Log in as the user. After configurations, the attacker can log in to a user’s account using their (IdP) without the need for credentials or MFA.

What do the logs for this attack look like?

Attack Stage: IdP Creation
Log Event: system.idp.lifecycle.create
Notes: Generated when an IdP is created. A newly created IdP is marked as activated automatically without needing activation. This event can be leveraged to create a detection rule for any IdP addition.

Attack Stage: IdP Modification
Log Event: system.idp.lifecycle.deactivate, system.idp.lifecycle.activate, system.idp.lifecycle.delete, system.idp.lifecycle.update
Notes: Depending on what action the attacker is performing, you will see system.idp.lifecycle.* events.

Attack Stage: User Login
Log Event: core.user_auth.idp.social.login_success, core.user_auth.idp.saml.login_success
Notes: If the attacker utilizes a pre-defined IdP, you will observe the SAML login event when a SAML IdP is employed.

If you are an Obsidian User, you will see similar activity in your console:

What can I do to detect this attack?

Detecting this sequence of events will depend on the tools available to you. 

If you’re using the Okta admin console to view logs, you can query for the following event: eventType eq “system.idp.lifecycle.create”

If you are an Obsidian Security customer, you will receive an alert for Okta: “New IdP Creation”, which will highlight user activity and risk factors.

Additionally, you can set up alerts for IdP-related activity with the following query:

(system.idp.lifecycle.deactivate OR system.idp.lifecycle.activate OR system.idp.lifecycle.delete OR system.idp.lifecycle.update) 

As IdPs are typically only configured at implementation, there should be a low volume of alerts to triage. With the impact of a malicious IdP installation being very high and the alert volume being very low, we recommend security teams review every IdP creation and modification.

Conclusion

A compromised superuser in your authentication environment can have devastating consequences for any organization. When preventative measures fall short, it’s crucial to promptly identify and address post-compromise activity. A timely, thorough response is imperative to minimize adversarial persistence and impact on your business.

Many threat actors are going so far as to set up their malicious IdPs, enabling them to maintain access even after remediation efforts have been made. By taking the necessary precautions, we can equip our environments to detect such activity and eliminate threat actors from our systems.