GCP - Artifact Registry Privesc

支持 HackTricks

Artifact Registry

有关 Artifact Registry 的更多信息,请查看:

artifactregistry.repositories.uploadArtifacts

通过此权限,攻击者可以上传带有恶意代码的新版本工件,例如 Docker 镜像:

# Configure docker to use gcloud to authenticate with Artifact Registry
gcloud auth configure-docker <location>-docker.pkg.dev

# tag the image to upload it
docker tag <local-img-name>:<local-tag> <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>

# Upload it
docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>

已检查到可以上传一个新的恶意docker镜像,名称和标签与已存在的相同,因此旧的镜像将失去标签,下次下载带有该标签的镜像时,将会下载到恶意镜像。

上传一个Python库

首先创建要上传的库(如果可以从注册表下载最新版本,可以跳过此步骤):

  1. 设置项目结构

  • 为您的库创建一个新目录,例如 hello_world_library

  • 在此目录中,创建另一个目录,命名为您的包名,例如 hello_world

  • 在您的包目录中,创建一个 __init__.py 文件。此文件可以为空,也可以包含您包的初始化内容。

mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
  1. 编写库代码

  • hello_world 目录中,创建一个新的Python文件作为您的模块,例如 greet.py

  • 编写您的“Hello, World!”函数:

# hello_world/greet.py
def say_hello():
return "Hello, World!"
  1. 创建 setup.py 文件

  • hello_world_library 目录的根目录中,创建一个 setup.py 文件。

  • 此文件包含有关您库的元数据,并告诉Python如何安装它。

# setup.py
from setuptools import setup, find_packages

setup(
name='hello_world',
version='0.1',
packages=find_packages(),
install_requires=[
# 您的库所需的任何依赖项
],
)

现在,上传库:

  1. 构建您的包

  • hello_world_library 目录的根目录运行:

python3 setup.py sdist bdist_wheel
  1. 为twine配置身份验证(用于上传您的包):

  • 确保您已安装 twinepip install twine)。

  • 使用 gcloud 配置凭据:

```sh
twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://<location>-python.pkg.dev/<project-id>/<repo-name>/ dist/*
```
  1. 清理构建

rm -rf dist build hello_world.egg-info

无法上传与已存在版本相同的python库,但可以上传更高版本(或者在版本末尾添加一个额外的**.0** - 但在python中不适用),或者删除最后一个版本并上传一个新的版本(需要artifactregistry.versions.delete:

gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>

artifactregistry.repositories.downloadArtifacts

拥有此权限后,您可以下载工件并搜索敏感信息漏洞

下载一个Docker镜像:

# Configure docker to use gcloud to authenticate with Artifact Registry
gcloud auth configure-docker <location>-docker.pkg.dev

# Dowload image
docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>

下载一个 python 库:

pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth print-access-token)@<location>-python.pkg.dev/<project-id>/<repo-name>/simple/" --trusted-host <location>-python.pkg.dev --no-cache-dir
  • 如果在一个虚拟注册表中混合了远程和标准注册表,并且一个包同时存在于两者中,会发生什么?请查看此页面:

artifactregistry.tags.delete, artifactregistry.versions.delete, artifactregistry.packages.delete, (artifactregistry.repositories.get, artifactregistry.tags.get, artifactregistry.tags.list)

从注册表中删除工件,例如 docker 镜像:

# Delete a docker image
gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>

artifactregistry.repositories.delete

删除一个完整的仓库(即使它有内容):

gcloud artifacts repositories delete <repo-name> --location=<location>

artifactregistry.repositories.setIamPolicy

拥有此权限的攻击者可以授予自己执行一些先前提到的存储库攻击的权限。

通过 Artifact Registry 读写进行其他服务的转移

  • Cloud Functions

当创建 Cloud Function 时,一个新的 docker 镜像会被推送到项目的 Artifact Registry。我尝试用一个新的镜像修改该镜像,甚至删除当前镜像(和 cache 镜像),但没有任何变化,Cloud Function 继续工作。因此,可能 可以利用竞争条件攻击,就像使用存储桶一样,来更改将要运行的 docker 容器,但 仅仅修改存储的镜像无法破坏 Cloud Function

  • App Engine

尽管 App Engine 在 Artifact Registry 内部创建 docker 镜像。测试表明,即使您在此服务中修改镜像并删除 App Engine 实例(以便部署一个新的实例),执行的代码不会改变。 可能通过执行 类似于存储桶的竞争条件攻击,可能可以覆盖执行的代码,但这尚未测试。

Support HackTricks

Last updated