OffensAI Logo

RogueOIDC: AWS Persistence and Evasion through attacker-controlled OIDC Identity Provider

This research shows what an attacker can achieve after creating a malicious OIDC identity provider in AWS and how they can do it. The article presents novel techniques and tools for persistence and evasion.

Eduard Agavriloae
Eduard Agavriloae - Director of Cloud R&D
RogueOIDC: AWS Persistence and Evasion through attacker-controlled OIDC Identity Provider

Security research often follows a reactive pattern. New attack techniques are discovered after malicious actors have already developed and deployed them against victims. By then, the damage is done, usually for more than one victim.

This research takes a proactive approach by exploring potential OIDC provider abuse vectors in AWS environments before they are exploited in the wild. You will see a lot of this, here at OffensAI.

The findings and tools shared in this article aim to eliminate the "first victim" scenario by getting ahead of attackers and hardening systems against these previously undocumented vectors.

Introduction

What is OIDC in AWS

OpenID Connect (OIDC) is an improvement on how organizations can handle authentication in AWS and authorization over resources, offering a more secure approach to identity management. This allows organizations to move away from traditional credential-based access and follow the latest security recommendations for going "keyless".

At its core, OIDC enables AWS to trust external identity providers, creating a bridge between existing authentication systems and AWS services. When an application or user needs to access AWS resources, they first authenticate with their identity provider, receive a cryptographically signed token, and present this token to AWS as proof of their identity.

What makes OIDC particularly valuable in AWS environments is its ability to enable temporary, automatically rotating credentials. Rather than dealing with long-lived access keys, organizations can implement secure, time-bound access that automatically expires. This aligns perfectly with security best practices and significantly reduces the operational overhead of credential management.

For cloud architects and security teams, OIDC integration with AWS represents a shift toward more manageable and secure authentication patterns. Whether you're building cloud-native applications, implementing CI/CD pipelines, or managing cross-account access, OIDC provides a standardized way to handle identity verification while maintaining strong security controls. The diagram below exemplifies how Terraform Cloud authenticates and obtains the temporary access credentials from an IAM role configured for OIDC.

Authentication flow between Terraform and OIDC in AWS
Authentication flow between Terraform and OIDC in AWS

The weak point of OIDC

While OIDC offers a straightforward way to integrate third-party authentication in AWS, this doesn't make it just as straightforward to understand. The weakness we noticed doesn't lie in the protocol itself, but in how AWS IAM roles are configured to trust these OIDC providers.

Organizations often struggle to fully understand the security implications of the trust relationship they're establishing. When configuring IAM roles to accept OIDC authentication, it's easy to focus on making the integration work rather than carefully constraining what the identity provider can do. This frequently results in overly permissive configurations where administrators fail to properly scope the conditions under which OIDC tokens are accepted or don't adequately restrict the permissions granted to authenticated identities.

The security importance of securely implementing OIDC is reflected in the industry's recent focus over this issue. Researchers and security companies took the time to analyze and report their perspective on the matter. The implications and security recommendations are different based on the identity provider. Some of the most relevant articles based on the OIDC provider:

  • GitHub first reported by Rojan Rijal, Johnny Nipper and Tanner EmekTinder from Tinder
  • Terraform Cloud reported by Eduard Agavriloae from OffensAI (me)
  • GitLab reported by Nick Frichette on hackingthe.cloud
  • AWS Amplify reported by Nick Frichette from Datadog
  • An analysis over multiple OIDC providers done by Scott Piper from Wiz

Seeing this coverage on misconfigured third-party OIDC integrations we asked ourselves what if the OIDC provider is controlled by an attacker. A similar question was asked by Adan Álvarez Vilchez, but for SAML with a focus on persistence. As you will see shortly, the OIDC itself permits more from an offensive perspective than what SAML can offer.

Rogue OIDC provider

The web server

We started by developing an OIDC implementation in Python3, exposing four endpoints:

  • /.well-known/openid-configuration (Required: provides OIDC configuration metadata)
  • /jwks (Required: exposes the public keys for validating signed JWTs)
  • /auth (For convenience: endpoint for authentication that redirects back with an authorization code)
  • /token (For convenience: endpoint for exchanging the code for a JWT)

The /auth and /token endpoints are normally mandatory parts of an OIDC Their role is to authenticate clients and return signed JWTs that can be used in the end to assume an AWS role. However, since we are in this case both the client and the identity provider, we could have signed locally the JWTs ourselves because we have access to the required information to do so.

When configuring OIDC federation in AWS, you're delegating authentication authority to a third-party identity provider. While this offers convenience, it also means the provider can generate and sign tokens that AWS will trust implicitly. Any malicious or compromised provider can craft JWT tokens with arbitrary claims, and with knowledge about the federated role for the affected OIDC provider, these tokens could be used to assume the role within your AWS account.

AWS accepts as identity providers that use HTTPS with valid certificate. To satisfy this we started an EC2 instance, created a DNS record for oidc.offensai.com that pointed to the instance, and generated a certificate with Let's Encrypt.

Cloud configurations

With the OIDC provider running we can now create an identity provider with an audience configured in the web server.

Identity provider based on OIDC created in AWS
Rogue OIDC added as Identity Provider in AWS

When the identity provider is created, two GET requests are made by AWS to our server:

  • First one to /.well-known/openid-configuration
  • Second one to /jwks
  • Both from AWS Security Token Service (AWS STS)
Identity provider based on OIDC created in AWS
Rogue OIDC added as Identity Provider in AWS

Because the configuration was right, now we can create a federated role for our OIDC identity provider.

Identity provider based on OIDC created in AWS
Rogue OIDC added as Identity Provider in AWS

Almost always you must specify the aud condition to prevent unauthorized clients from the same OIDC provider to assume your role. The present configuration is insecure and should not be replicated.

All the prerequisites are in place in the victim account. Let's get some access credentials!

Assuming the federated role

We'll start with a simple flow and then we'll look into a more advanced scenario for evasion. To assume the role we need a signed JWT from our Rogue OIDC provider.

In the image below we can see the next flow:

  • We ask the OIDC for an authorization code
  • We exchange the authorization code for a JWT
  • We provide to AWS the JWT for and we get a set of temporary credentials
Script execution for assume an AWS federated role
Assuming the federated OIDC role

Persistence achieved! 🤝

If you want to use AWS CLI for assuming a federated OIDC role you can use "aws sts assume-role-with-web-identity --role-arn $role_arn --role-session-name $session_name --web-identity-token $jwt"

Checking the HTTP requests our OIDC server received, after the first 3 requests we can see the same two GET requests made by AWS STS.

Logs with HTTP requests made to the OIDC provider
HTTP requests made to the Rogue OIDC

Evasion

Technique #1

The next question we asked was how close can we impersonate a legitimate OIDC provider like Terraform Cloud that might already be present in the AWS account.

We compared a CloudTrail event entry for the same AWS API call (STS GetCallerIdentity) between a legitimate Terraform Cloud OIDC role and the Rogue OIDC role.

diff command executed over two cloudtrail log files
Initial differences between CloudTrail logs for the two identities

We can see a lot of differences. Just to name a few:

  • Session name
  • Principal ID
  • Role ARN
  • Federated Provider
  • User Agent

A big part of them can be fixed with trivial tweaking. However, to get the closest to a legitimate OIDC identity we will have to add our rogue OIDC provider in the trust relationship of the Terraform role.

edit panel for AWS trust role relationship
Terraform role with Rogue OIDC federated trust relationship

Since we are talking about evasion, we will try to better blend it by using the same "aud" and "sub" conditions as for Terraform. For using the same user agent we used our internal evasion engine interleave. There are however documented techniques to achieve this, like the one documented in this article by Nick Frichette.

Here is the result achieved:

diff command executed over cloudtrail logs after applying evasion techniques
Final differences between CloudTrail logs for the two identities

The only relevant difference is on the OIDC provider, about which we couldn't find a solution to impersonate (we are glad we couldn't).

You might ask, since you have the permission to edit the trust relationship of a legitimate federated role, why not replace the "aud" condition or make it more lax to assume the role from the legitimate OIDC provider?

  • Depending on the OIDC provider, you might not be able to exfiltrate the access credentials to use them programmatically (the case for Terraform Cloud). Using your own OIDC provider provides more flexibility and control over the access credentials.
  • Because OIDC is more niched and complex, it might bypass detection controls

To summarize, is it possible to use a Rogue OIDC provider to closely blend in between legitimate AWS API calls if there is another OIDC provider present in the environment. The technique can be used at its maximum value if we can backdoor the trust relationship of the legitimate role.

Technique #2

This technique might work best against behavior and AI-based detection solutions. For these types of detection, the identity's activity is analyzed before raising an alert. The reason is simple. Everyone wants a reduced percent of false positives. Well, what if execute every AWS API call with a new and different session?

In the next image the output is redirected to /dev/null for the simplicity of the PoC.

script for assuming role ran multiple times with different usernames
Obtaining sessions under different usernames
cloudtrail dashboard showing the same AWS API call done by different usernames
Different usernames for each AWS API call

This can also be done through normal IAM roles, but doing it through federated roles might add just enough extra complexity that would bypass detection solutions.

This technique might be countered by monitoring for suspicious AssumeRoleWithWebIdentity events.

Both evasion techniques are implemented in our evasion engine interleave.

Mitigations

Here are some general good practices when it comes to legitimate OIDC providers as well specific mitigations for Rogue OIDC providers:

  • Apply Least Privilege Principle and monitor closely the users that can add new identity providers or modify role trust relationships
  • Implement strict audience (aud) and subject (sub) conditions in IAM role trust relationships to limit which identities can assume roles
  • Monitor changes to IAM role trust relationships, especially modifications that add new identity providers
  • Regularly audit OIDC provider configurations in your AWS accounts and remove unused providers
  • Consider implementing detective controls for unusual patterns like multiple role assumptions with different session names
  • Review CloudTrail logs for suspicious AWS STS AssumeRoleWithWebIdentity API calls

These controls won't prevent all OIDC-based attacks, but they will help detect and limit their impact.

Conclusions

This research demonstrates the risks associated with OIDC federation in AWS when attackers control the identity provider. The key findings include:

  • OIDC providers can be weaponized for AWS persistence through malicious token generation
  • Trust relationships of legitimate OIDC roles can be backdoored to accept tokens from attacker-controlled providers
  • Evasion is possible by either mimicking legitimate OIDC provider behavior or using unique sessions for each API call
  • The complexity of OIDC implementations may help bypass traditional detection mechanisms

Organizations should carefully review their OIDC configurations, monitor trust relationship changes, and implement strict conditions for token acceptance to mitigate these risks.

During this research multiple techniques were tried against the AWS APIs, features and logging related to IAM OIDC identity provider, but no vulnerabilities were identified.

Something that I want to especially highlight is the fact that no customer information is sent to the OIDC provider. This means that even if the OIDC is compromised, the attacker will not know about the AWS customers that are using the provider just from the new AWS HTTP requests.

Tools

You can find the tools used for this research at the next repository:

We'll wait two weeks for cloud detection solutions to respond and then we'll publish an step-by-step article on hackingthe.cloud on how to deploy and use the RogueOIDC scripts.

References

Embrace Autonomous Cloud Red Teaming

Proactively discover and remediate cloud attacks present in your infrastructure. Ready to get started?