AutoWarp 是 Azure 自动化服务中的一个严重漏洞,允许未经授权访问使用该服务的其他 Azure 客户帐户。原文地址:https://orca.security/resources/blog/autowarp-microsoft-azure-automation-service-vulnerability/
影响
AutoWarp 是 Azure 自动化服务中的一个严重漏洞,允许未经授权访问使用该服务的其他 Azure 客户帐户。这种攻击可能意味着完全控制属于目标帐户的资源和数据,具体取决于客户分配的权限。
若您为对漏洞进行修复之前,在一下情况下,很容易受到 AutoWarp 的攻击:
- 你一直在使用 Azure 自动化服务
- 您的自动化帐户中的托管身份功能已启用(默认情况下已启用)
Microsoft Azure 自动化服务
Microsoft Azure 自动化允许客户以托管方式执行自动化代码。您可以安排作业、提供输入和输出等。每个客户的自动化代码在沙箱内运行,与在同一虚拟机上执行的其他客户代码隔离。
AutoWarp:Azure 自动化安全漏洞
我们发现了一个严重的缺陷,它允许我们与管理其他客户沙箱的内部服务器进行交互。我们设法通过该服务器获取其他客户帐户的身份验证令牌。怀有恶意的人可能会不断获取令牌,并利用每个令牌将攻击范围扩大到更多 Azure 客户。
完整细节
在浏览 Azure 服务列表时,看到“管理与治理”类别下的“自动化账户”,猜测这是一种允许我通过自动化控制 Azure 帐户的服务。
在创建我的第一个自动化帐户后,我意识到 Azure 自动化是自动化脚本的非常标准的服务。您可以上传 Python 或 PowerShell 脚本以在 Azure 上执行。
首先尝试查看文件系统,,便从自动化脚本中启动了一个反向 shell,成功连接,但是当执行一些常用的命令(如tasklist)时,提示:找不到。显然,负责定义操作系统应尝试执行哪些文件扩展名的PathExt环境变量被设置为一个奇怪的值。通常,它包含.exe文件扩展名,但在我们的例子中不包含。只有.CPL是存在的,它是 Windows 控制面板项目的文件扩展名。
当我查看 C:\ 驱动器时,首先引起我注意的两件事是“Orchestrator”和“temp”目录。Orchestrator 目录包含许多 DLL 和 EXE。我看到带有“sandbox”的文件名,直觉上我明白这个目录包含我们正在运行的沙箱。临时目录包含另一个名为“diags”的目录,并且有一个“trace.log”文件。
查看日志文件:
Orchestrator.Sandbox.Diagnostics Critical:
0 : [2021-12-06T12:08:04.5527647Z]
Creating asset retrieval web service.
[assetRetrievalEndpoint=
http://127.0.0.1:40008]
根据文件内容,发现使用了高端口,这个便十分让人怀疑是否“掩耳盗铃”。
我使用 cURL 向 URL 发出了 HTTP 请求。它有效,但没有提供太多关于正在发生的事情的信息。我还尝试访问下一个端口(40009、40010 等),其中一些端口进行了反馈,这便证实了当初的怀疑。
日志清楚地表明,Web 服务是由我之前看到的协调器管理的,所以我必须了解发生了什么。这是什么网络服务?
深入了解 Azure 自动化代码
下载编排器的文件后,我启动了 ILSpy(.NET 反编译器)并开始寻找他们称之为“资产检索 Web 服务”的代码。我查看了设置 HTTP 路由的方法,真正弹出的是“/oauth2/token”和“/metadata/identity/oauth2/token”映射到一个名为“MSIController”的控制器。
我之前并没有真正做过太多 .NET Web 开发或研究,所以我从代码中推断这些路由映射到“MSIController”类,如果您熟悉 MVC(Model-View)的概念,这非常简单。 -控制器)。还值得注意的是,在审查源代码时,一些软件开发经验非常有帮助——它有助于在更复杂的情况下“阅读字里行间”。
我开始向 /oauth2/token 发出 HTTP 请求,我将请求调整为看起来像元数据请求(添加“Metadata: True”HTTP 标头)并添加资源参数。我希望令牌可供 Azure 管理 API 使用,因此我使用了“resource= https://managment.azure.com/ ”。该请求仅返回一个 JWT(JSON Web 令牌)。
我解码了令牌并看到了我的订阅 ID、租户 ID 和我的自动化帐户资源 ID。我在网上查了“Azure 自动化标识”,发现每个自动化账户都有一个“系统分配的托管标识”,这基本上意味着您可以为您的自动化脚本分配角色,并且该标识由服务管理。
漏洞点
因此,链接到托管标识的令牌本身并不是问题。您应该能够为自己的托管身份获取令牌。但是,如果您一直在关注,则可以在本地访问其他端口。每次我运行自动化作业时,我都会看到端口发生变化,但仍保持在相同的范围内。
我编写了一个快速的 Python 脚本来向从 40,000 开始的 20 个端口发出 HTTP 请求。这样做很简单:
import requests
PORT_RANGE_START = 40000
PORTS_TO_SCAN = 1000
print("Making requests to ports 40000 and up...")
for port in range(PORT_RANGE_START, PORT_RANGE_START + PORTS_TO_SCAN):
try:
resp = requests.post(f"http://127.0.0.1:{port}/oauth2/token",
timeout=0.5, headers={'Metadata': 'True'}, data={'resource':
'https://management.azure.com/'})
print(f"Port {port}: {resp.json()}")
except Exception as e:
continue
随机端口给了我 JWT 令牌。我又执行了几次脚本,不同的端口给了我不同的令牌!对我来说很明显,我实际上是在访问其他人的身份端点。我已经证明,如果给予足够的权限,这些令牌可以用于管理 Azure 帐户,因此无需访问其他租户的数据。