GCP - Artifact Registry Privesc

Support HackTricks

Artifact Registry

Para más información sobre Artifact Registry, consulta:

GCP - Artifact Registry Enum

artifactregistry.repositories.uploadArtifacts

Con este permiso, un atacante podría subir nuevas versiones de los artefactos con código malicioso, como imágenes de 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>

Se verificó que es posible subir una nueva imagen docker maliciosa con el mismo nombre y etiqueta que la ya presente, por lo que la anterior perderá la etiqueta y la próxima vez que se descargue la imagen con esa etiqueta, se descargará la maliciosa.

Subir una biblioteca de Python

Comienza creando la biblioteca para subir (si puedes descargar la última versión del registro, puedes evitar este paso):

  1. Configura la estructura de tu proyecto:

  • Crea un nuevo directorio para tu biblioteca, por ejemplo, hello_world_library.

  • Dentro de este directorio, crea otro directorio con el nombre de tu paquete, por ejemplo, hello_world.

  • Dentro del directorio de tu paquete, crea un archivo __init__.py. Este archivo puede estar vacío o puede contener inicializaciones para tu paquete.

mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
  1. Escribe el código de tu biblioteca:

  • Dentro del directorio hello_world, crea un nuevo archivo de Python para tu módulo, por ejemplo, greet.py.

  • Escribe tu función "¡Hola, Mundo!":

# hello_world/greet.py
def say_hello():
return "Hello, World!"
  1. Crea un archivo setup.py:

  • En la raíz de tu directorio hello_world_library, crea un archivo setup.py.

  • Este archivo contiene metadatos sobre tu biblioteca y le dice a Python cómo instalarla.

# setup.py
from setuptools import setup, find_packages

setup(
name='hello_world',
version='0.1',
packages=find_packages(),
install_requires=[
# Cualquier dependencia que necesite tu biblioteca
],
)

Ahora, subamos la biblioteca:

  1. Construye tu paquete:

  • Desde la raíz de tu directorio hello_world_library, ejecuta:

python3 setup.py sdist bdist_wheel
  1. Configura la autenticación para twine (usado para subir tu paquete):

  • Asegúrate de tener twine instalado (pip install twine).

  • Usa gcloud para configurar las credenciales:

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

rm -rf dist build hello_world.egg-info

No es posible subir una biblioteca de python con la misma versión que la ya presente, pero es posible subir versiones mayores (o agregar un extra .0 al final de la versión si eso funciona -no en python, sin embargo-), o eliminar la última versión y subir una nueva con (necesario artifactregistry.versions.delete):

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

artifactregistry.repositories.downloadArtifacts

Con este permiso puedes descargar artefactos y buscar información sensible y vulnerabilidades.

Descargar una imagen de 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>

Descargar una python biblioteca:

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
  • ¿Qué sucede si se mezclan un registro remoto y un registro estándar en uno virtual y un paquete existe en ambos? Consulta esta página:

GCP - Artifact Registry Persistence

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

Elimina artefactos del registro, como imágenes de docker:

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

artifactregistry.repositories.delete

Elimina un repositorio completo (incluso si tiene contenido):

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

artifactregistry.repositories.setIamPolicy

Un atacante con este permiso podría otorgarse permisos para realizar algunos de los ataques de repositorio mencionados anteriormente.

Pivotando a otros Servicios a través de Artifact Registry Read & Write

  • Cloud Functions

Cuando se crea una Cloud Function, se envía una nueva imagen de docker al Artifact Registry del proyecto. Intenté modificar la imagen con una nueva, e incluso eliminar la imagen actual (y la imagen cache) y nada cambió, la función en la nube siguió funcionando. Por lo tanto, podría ser posible abusar de un ataque de Race Condition como con el bucket para cambiar el contenedor de docker que se ejecutará, pero simplemente modificando la imagen almacenada no es posible comprometer la Cloud Function.

  • App Engine

A pesar de que App Engine crea imágenes de docker dentro de Artifact Registry. Se probó que incluso si modificas la imagen dentro de este servicio y eliminas la instancia de App Engine (para que se despliegue una nueva), el código ejecutado no cambia. Podría ser posible que al realizar un ataque de Race Condition como con los buckets, podría ser posible sobrescribir el código ejecutado, pero esto no fue probado.

Support HackTricks

Last updated