Breaking The Barriers

Challenge Description

The challenge provides credentials for a malicious OAuth application and tasks us with deploying it to a victim Azure tenant to gain access to a protected flag.

Table of Contents

Solution Overview

This challenge demonstrates an Entra ID privilege escalation attack chain through OAuth application abuse and dynamic group manipulation:

  1. Initial Access - Exploit vulnerable web application to create Global Administrator user

  2. CAP Bypass Discovery - Identify authentication restrictions through MFA/CAP enumeration

  3. OAuth Deployment - Deploy malicious OAuth app via admin consent grant with MFA setup

  4. Graph API Access - Authenticate as service principal with limited permissions

  5. Dynamic Group Analysis - Discover group with flag access using dynamic membership rules

  6. Guest User Exploitation - Invite crafted guest user to satisfy dynamic group conditions

  7. Flag Access - Authenticate as guest user to download flag from Azure Blob Storage

Key Vulnerability: The challenge exploits insecure dynamic group membership rules combined with OAuth app consent permissions to escalate from limited service principal access to full flag retrieval through a crafted guest user invitation.


Initial Reconnaissance

Environment Variables Analysis

The challenge provides us with initial credentials and endpoints:

Malicious OAuth App Credentials:

Victim Tenant Web Application:

Web Application Enumeration

The web application exposes a user creation endpoint that appears to automatically assign Global Administrator privileges.

Creating a test user:

Created User Credentials:


uthentication Testing

Initial Login Attempts

Attempting direct authentication with Azure PowerShell fails despite having Global Administrator privileges:

This suggests Conditional Access Policies are restricting authentication methods.

MFA and Conditional Access Policy Enumeration

Step 1: Using findmeaccess for MFA enumeration

We'll use the findmeaccess tool to enumerate which authentication methods bypass MFA and Conditional Access Policies:

Analysis:

Most authentication endpoints are blocked by Conditional Access Policies. However, searching for successful authentications reveals a potential bypass:

Step 2: Extracting authentication parameters

Identified Parameters:

Parameter
Value

Azure Graph API

https://graph.windows.net

Editor Browser Extension

1a20851a-696e-4c7e-96f4-c282dfe48872

Windows 10 Chrome

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36

Step 3: Attempting token retrieval

Result: Still blocked by CAP. Testing alternative client IDs also fails:

Key findings:

  • Direct user authentication heavily restricted

  • CAP blocks most API access methods

  • Need alternative approach: OAuth consent grant


OAuth App Deployment

Since direct authentication is blocked, we'll leverage the OAuth app credentials to deploy a malicious application via admin consent grant.

Step 1: Crafting the consent URL

Parameters explained:

  • /common/adminconsent - Admin consent endpoint for multi-tenant apps

  • client_id - The malicious OAuth app ID provided in the challenge

Step 2: MFA requirement

Visiting the consent URL triggers an MFA setup requirement for the Global Administrator account:

This is different from the previous CAP errors, indicating the consent flow has different access requirements.

Step 3: Completing MFA registration

Note: Use a temporary email for backup verification (never use your real personal email in CTF challenges)

Step 4: Granting admin consent

After completing MFA setup, revisit the consent URL:

Requested Permissions:

  • Read all groups (Group.Read.All)

  • Invite guest users (User.Invite.All)

  • Sign in and read user profile (User.Read)

Accepting the consent grants these permissions to our malicious OAuth app in the victim tenant.

Key findings:

  • Successfully deployed malicious OAuth app to victim tenant

  • Obtained service principal with group read and guest invite permissions

  • Ready to enumerate and exploit with service principal

Service Principal Authentication

Step 1: Obtaining victim tenant ID

Retrieve the tenant ID from the OpenID configuration endpoint:

Complete Credential Set:

Step 2: Authenticating as service principal

Parameters explained:

  • -u - Service principal client ID

  • -p - Client secret

  • -t - Target tenant ID (victim tenant)

  • --allow-no-subscription - Authenticate without Azure subscription access

Success! We now have authenticated access to the victim tenant as the service principal.


Graph API Enumeration

Obtaining Access Token

With the service principal authenticated, we can request Graph API tokens:

Token Permissions:

  • Group.Read.All - Read all group information

  • User.Invite.All - Invite guest users to the tenant

Security Note: These permissions, while seemingly limited, can be powerful when combined. Guest invitation + group visibility = potential privilege escalation vector.

4.2 Discovering Dynamic Groups

Step 1: Enumerating groups with graph_viewer

Using the Graph API token with a tool like graph_viewerarrow-up-right (shameless plug), we can enumerate all groups:

Step 2: Identifying suspicious group

One group immediately stands out:

Group Name: Users assigned access to flag

Step 3: Analyzing group properties

Group Type: Dynamic Membership

Dynamic Membership Rule:

Key findings:

  • Found target group with flag access

  • Group uses dynamic membership (automatic assignment)

  • Multiple OR conditions for membership

  • Exploitable condition: displayName starts with "CTF" AND userType is "Guest"


Dynamic Group Exploitation

Analyzing Membership Rules

The dynamic membership rule has three OR conditions. Users are automatically added if they meet any of these criteria:

Condition 1:

  • user.department = "Finance" AND user.jobTitle = "Manager"

Condition 2 (Exploitable):

  • user.displayName starts with "CTF" AND user.userType = "Guest"

Condition 3:

  • user.city = "Seattle"

Attack Vector: Since we have User.Invite.All permission, we can invite a guest user with a display name starting with "CTF" to automatically gain membership!

Security Note: Dynamic groups with guest user conditions are risky. Attackers with guest invitation permissions can craft users to satisfy membership rules, especially when based on user-controlled attributes like displayName.

Guest User Invitation

Step 1: Preparing guest user

Create a user in a personal Azure tenant with a display name starting with "CTF":

Prepared User:

Step 2: Inviting guest user to victim tenant

Parameters explained:

  • invitedUserEmailAddress - Email of user to invite

  • inviteRedirectUrl - URL user will see after accepting invitation

  • sendInvitationMessage - Set to false to get the redemption URL in response (not via email)

  • invitedUserDisplayName - Display name starting with "CTF" to match dynamic rule

Important: Setting sendInvitationMessage to false returns the inviteRedeemUrl in the API response, allowing us to complete the invitation process immediately.

Step 3: Redeeming guest invitation

Extract the inviteRedeemUrl from the response and visit it in an incognito browser:

Step 4: Verifying group membership

After accepting the invitation, verify the guest user now has access to two directories:

In the victim tenant's Azure Portal, confirm the guest user was automatically added to the target group:

Success! The dynamic membership rule automatically added our crafted guest user to the Users assigned access to flag group.

Key findings:

  • Guest user successfully invited to victim tenant

  • Dynamic group rule automatically granted membership

  • Guest user now has flag access permissions

  • Ready to retrieve the flag


Flag Retrieval

Step 1: Discovering flag location

In the Azure Portal's app dashboard, a flag resource is now visible:

Flag URL:

Step 2: Attempting direct access

Clicking the URL results in an error:

Error: PublicAccessNotPermitted

This indicates the blob storage requires authenticated access via Azure AD (not public access).

Step 3: Authenticating as guest user

Authenticate to Azure CLI as the guest user:

**** **Step 4: Downloading the flag**

Parameters explained:

  • --account-name - Azure storage account name

  • -c - Container name (grab-the-flag)

  • -n - Blob name (ctf_flag.txt)

  • --auth-mode login - Use Azure AD authentication (not storage keys)

Success!

Summary:

  1. The guest user is a member of Users assigned access to flag group

  2. This group has been granted Storage Blob Data Reader role on the storage account

  3. Azure RBAC allows the guest user to download blobs using Azure AD authentication

  4. The dynamic membership rule automatically granted access without manual approval

Flag: WIZ_CTF{EntraID_Sensitive_Privileges_Breaking_Barriers}

Last updated