# GCP - Artifact Registry Privesc

{{#include ../../../banners/hacktricks-training.md}}

## Artifact Registry

For more information about Artifact Registry check:

{{#ref}}
../gcp-services/gcp-artifact-registry-enum.md
{{#endref}}

### artifactregistry.repositories.uploadArtifacts

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

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

> [!CAUTION]
> 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.

<details>

<summary>Upload a Python library</summary>

**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.

    ```bash
    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:

    ```python
    # 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.

    ```python
    # 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:

    ```sh
    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/*
```
````

3. **Clean the build**

```bash
rm -rf dist build hello_world.egg-info
```

</details>

> [!CAUTION]
> 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)`**:**
>
> ```sh
> 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:

```sh
# 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:

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

- What happens if a remote and a standard registries are mixed in a virtual one and a package exists in both? Check this page:

{{#ref}}
../gcp-persistence/gcp-artifact-registry-persistence.md
{{#endref}}

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

```bash
# 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.

### Pivoting to other Services through Artifact Registry Read & Write

- **Cloud Functions**

When a Cloud Function is created a new docker image is pushed to the Artifact Registry of the project. I tried to modify the image with a new one, and even delete the current image (and the `cache` image) and nothing changed, the cloud function continue working. Therefore, maybe it **might be possible to abuse a Race Condition attack** like with the bucket to change the docker container that will be run but **just modifying the stored image isn't possible to compromise the Cloud Function**.

- **App Engine**

Even though App Engine creates docker images inside Artifact Registry. It was tested that **even if you modify the image inside this service** and removes the App Engine instance (so a new one is deployed) the **code executed doesn't change**.\
It might be possible that performing a **Race Condition attack like with the buckets it might be possible to overwrite the executed code**, but this wasn't tested.

{{#include ../../../banners/hacktricks-training.md}}



