GCP - Artifact Registry Privesc

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Artifact Registry

For more information about Artifact Registry check:

pageGCP - Artifact Registry Enum

artifactregistry.repositories.uploadArtifacts

With this permission an attacker could upload new versions of the artifacts with malicious code like Docker images:

# 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>

It was checked that it's possible to upload a new malicious docker image with the same name and tag as the one already present, so the old one will lose the tag and next time that image with that tag is downloaded the malicious one will be downloaded.

Upload a Python library

Start by creating the library to upload (if you can download the latest version from the registry you can avoid this step):

  1. Set up your project structure:

    • Create a new directory for your library, e.g., hello_world_library.

    • Inside this directory, create another directory with your package name, e.g., hello_world.

    • Inside your package directory, create an __init__.py file. This file can be empty or can contain initializations for your package.

    mkdir hello_world_library
    cd hello_world_library
    mkdir hello_world
    touch hello_world/__init__.py
  2. Write your library code:

    • Inside the hello_world directory, create a new Python file for your module, e.g., greet.py.

    • Write your "Hello, World!" function:

    # hello_world/greet.py
    def say_hello():
        return "Hello, World!"
  3. Create a setup.py file:

    • In the root of your hello_world_library directory, create a setup.py file.

    • This file contains metadata about your library and tells Python how to install it.

    # 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
        ],
    )

Now, lets upload the library:

  1. Build your package:

    • From the root of your hello_world_library directory, run:

    python3 setup.py sdist bdist_wheel
  2. Configure authentication for twine (used to upload your package):

    • Ensure you have twine installed (pip install twine).

    • Use gcloud to configure credentials:

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

rm -rf dist build hello_world.egg-info

It's not possible to upload a python library with the same version as the one already present, but it's possible to upload greater versions (or add an extra .0 at the end of the version if that works -not in python though-), or to delete the last version an upload a new one with (needed artifactregistry.versions.delete):

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

artifactregistry.repositories.downloadArtifacts

With this permission you can download artifacts and search for sensitive information and vulnerabilities.

Download a Docker image:

# 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>

Download a python library:

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
  • What happens if a remote and a standard registries are mixed in a virtual one and a package exists in both? Check this page:

pageGCP - Artifact Registry Persistence

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

Delete artifacts from the registry, like docker images:

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

artifactregistry.repositories.delete

Detele a full repository (even if it has content):

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

artifactregistry.repositories.setIamPolicy

An attacker with this permission could give himself permissions to perform some of the previously mentioned repository attacks.

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated