译文声明
本文是翻译文章,原作者 Karl Fosaaen
原文地址:https://blog.netspi.com/attacking-acrs-with-compromised-credentials/
译文仅作参考,具体内容表达请见原文
Azure Container Registries(Azure容器注册表)是Microsoft用于管理云上Docker镜像的解决方案(以下简称ACR)。Azure官方对其相关解释如下:
容器注册表是一项存储和分发容器映像的服务 。 Docker Hub 是一个公共容器注册表,支持开放源社区并充当映像的通用目录。 Azure 容器注册表为用户提供映像直接控制、集成身份验证、支持全局分发和网络邻近部署可靠性的异地复制、标记锁定以及其他许多增强功能。除了 Docker 容器映像以外,Azure 容器注册表还支持相关的内容项目,包括开放容器计划 (OCI) 映像格式。
该服务允许使用 AzureAD单次登录 或 ACR管理员账户(Admin user) 来进行身份验证。该账户默认关闭,详情请见此。
在这篇文章中,我们假设你已经获得了ACR的某些管理员账户(Admin user)凭据。这些凭据可能被意外上传到Github、Jenkins服务或在一个能找到该凭证的任意地址。又或者是,你可能已经使用Get-AzPasswords的最新版来从Azure订阅中转储ACR管理员账户凭据。如果你有权执行此操作的话,可跳转到文章末尾来查看可以利用的Azure CLI命令。
获取到的管理员账户凭据大部分为 用户名/密码 的格式,并附加了ACR URL(例子:exampleacr.azurecr.io)
在此,假设已经拥有了这些管理员账户凭据,接下来将逐步完成访问ACR和在Azure订阅中的权限提升操作。
在以下 Docker命令中输入用户名,ACR URL和密码:
docker login -u USER_NAME -p PASSWORD EXAMPLEACR.azurecr.io
如果管理员账户凭据正确便可成功登录
为了访问容器镜像,我们将需要枚举容器名称及其版本信息。通常情况下可以通过一个经过身份验证的Azure CLI会话来执行此操作(请参阅下文),但是由于我们只有ACR管理员账户凭据,因此我们将必须使用Docker Registry API来完成此操作。
首先,我们将使用 _catalog API列出该ACR的所有容器信息。该操作需要身份验证,因此我们将在HTTP Basic认证(Base64 [USER:PASS])标头中使用ACR管理员账户凭据来完成操作。
简要 Powershell 代码如下:
现在我们有了容器列表,接下来我们将要查找每个容器其对应的版本信息。这可以通过如下URL来完成(其中 IMAGE_NAME 是你想要获得版本信息的容器名称)
https://EXAMPLEACR.azurecr.io/v2/IMAGE_NAME/tags/list
简要Powershell代码如下:
为了高效利用,我将上述Powershell代码进行了函数封装(GET-AzACR),工具地址为 MicroBurst
使用效果如下:
PS C:\> Get-AzACR -username EXAMPLEACR -password A_$uper_g00D_P@ssW0rd -registry EXAMPLEACR.azurecr.io docker pull EXAMPLEACR.azurecr.io/arepository:4 docker pull EXAMPLEACR.azurecr.io/dockercore:1234 docker pull EXAMPLEACR.azurecr.io/devabcdefg:2020 docker pull EXAMPLEACR.azurecr.io/devhijklmn:4321 docker pull EXAMPLEACR.azurecr.io/imagetester:10 docker pull EXAMPLEACR.azurecr.io/qatestimage:1023 ...
该脚本会输出拉取过的每个容器名称以及版本信息
说明:工具返回的版本信息可能不是容器的最新版本。该工具并不能获取关于特定版本的全部元数据。如果要查看所有容器的以及对应的所有版本,只需在工具的Get-AzACR命令上添加 -all 参数。
将工具的输出添加到 .ps1 文件,然后运行它以将所有容器镜像拉到本地测试系统(务必注意磁盘空间)。另外,您也可以选择要指定拉取的容器:
PS C:\> docker pull EXAMPLEACR.azurecr.io/dockercore:1234 1234: Pulling from dockercore [Truncated] 6638d86fd3ee: Download complete 6638d86fd3ee: Pull complete Digest: sha256:2c[Truncated]73 Status: Downloaded image for EXAMPLEACR.azurecr.io/dockercore:1234 EXAMPLEACR.azurecr.io/dockercore:1234
一旦我们本地的测试系统上成功拉取到容器镜像,我们便可以运行它。如下的命令示例用于在名为“dockercore”容器开启一个交互式shell( 以 /bin/bash 终端为例):
docker run -it --entrypoint /bin/bash EXAMPLEACR.azurecr.io/dockercore:1234
通过该交互式shell,我们可以开始查看容器任意本地文件,并可能在其中找到敏感信息。
这里有一个最近的 Azure云测试的例子,过程如下:
如果你已经可以访问Azure订阅,并且你在ACR上拥有读权限,则Azure CLI是枚举容器名称和版本信息的最优方法。
在经过身份验证的Azure CLI会话中(这里的身份认证指Azure AD单次登录,也就是 az acr login),可以在订阅中列出注册表信息:
PS C:\> az acr list [ { "adminUserEnabled": true, "creationDate": "2019-09-17T20:42:28.689397+00:00", "id": "/subscriptions/d4[Truncated]b2/resourceGroups/ACRtest/providers/Microsoft.ContainerRegistry/registries/netspiACR", "location": "centralus", "loginServer": "netspiACR.azurecr.io", "name": "netspiACR", [Truncated] "type": "Microsoft.ContainerRegistry/registries" } ]
选择要攻击的注册表(netspiACR),然后使用以下命令列出容器名称:
PS C:\> az acr repository list --name netspiACR [ "ACRtestImage" ]
列出容器的版本信息(ACRtestImage):
PS C:\> az acr repository show-tags --name netspiACR --repository ACRtestImage [ "latest" ]
通过Docker认证:
PS C:\> docker login docker login EXAMPLEACR.azurecr.io
Login Succeeded
通过身份验证后,很容易就可以查询到容器名称和标识符,容器拉取过程将与上面相同。
ACR是管理Azure基础结构中Docker镜像的好方案,但是请谨慎使用管理员账户凭据。此外,如果你在ACR使用了高级SKU,请限制ACR对特定网络的访问。即便管理员账户凭据被泄露,这将有助于降低ACR的可用性。最后,注意ACR的读权限。该权限可列出和提取ACR中的任何容器,因此他们可能具有比你预期更多的访问权限。