GCP - Artifact Registry Privesc

Soutenir HackTricks

Artifact Registry

Pour plus d'informations sur l'Artifact Registry, consultez :

artifactregistry.repositories.uploadArtifacts

Avec cette permission, un attaquant pourrait télécharger de nouvelles versions des artefacts avec du code malveillant comme des images 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>

Il a été vérifié qu'il est possible de télécharger une nouvelle image docker malveillante avec le même nom et la même balise que celle déjà présente, donc l'ancienne perdra la balise et la prochaine fois que cette image avec cette balise sera téléchargée, la malveillante sera téléchargée.

Télécharger une bibliothèque Python

Commencez par créer la bibliothèque à télécharger (si vous pouvez télécharger la dernière version depuis le registre, vous pouvez éviter cette étape) :

  1. Configurez la structure de votre projet :

  • Créez un nouveau répertoire pour votre bibliothèque, par exemple, hello_world_library.

  • À l'intérieur de ce répertoire, créez un autre répertoire avec le nom de votre package, par exemple, hello_world.

  • À l'intérieur de votre répertoire de package, créez un fichier __init__.py. Ce fichier peut être vide ou contenir des initialisations pour votre package.

mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
  1. Écrivez le code de votre bibliothèque :

  • À l'intérieur du répertoire hello_world, créez un nouveau fichier Python pour votre module, par exemple, greet.py.

  • Écrivez votre fonction "Hello, World!" :

# hello_world/greet.py
def say_hello():
return "Hello, World!"
  1. Créez un fichier setup.py :

  • À la racine de votre répertoire hello_world_library, créez un fichier setup.py.

  • Ce fichier contient des métadonnées sur votre bibliothèque et indique à Python comment l'installer.

# setup.py
from setuptools import setup, find_packages

setup(
name='hello_world',
version='0.1',
packages=find_packages(),
install_requires=[
# Toute dépendance dont votre bibliothèque a besoin
],
)

Maintenant, téléchargeons la bibliothèque :

  1. Construisez votre package :

  • Depuis la racine de votre répertoire hello_world_library, exécutez :

python3 setup.py sdist bdist_wheel
  1. Configurez l'authentification pour twine (utilisé pour télécharger votre package) :

  • Assurez-vous d'avoir twine installé (pip install twine).

  • Utilisez gcloud pour configurer les identifiants :

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

rm -rf dist build hello_world.egg-info

Il n'est pas possible de télécharger une bibliothèque python avec la même version que celle déjà présente, mais il est possible de télécharger des versions supérieures (ou d'ajouter un .0 à la fin de la version si cela fonctionne - pas en python cependant -), ou de supprimer la dernière version et d'en télécharger une nouvelle avec (nécessaire artifactregistry.versions.delete):

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

artifactregistry.repositories.downloadArtifacts

Avec cette autorisation, vous pouvez télécharger des artefacts et rechercher des informations sensibles et des vulnérabilités.

Téléchargez une image 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>

Téléchargez une bibliothèque 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
  • Que se passe-t-il si des registres distants et standard sont mélangés dans un registre virtuel et qu'un package existe dans les deux ? Consultez cette page :

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

Supprimer des artefacts du registre, comme des images docker :

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

artifactregistry.repositories.delete

Supprimez un dépôt complet (même s'il contient du contenu) :

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

artifactregistry.repositories.setIamPolicy

Un attaquant avec cette permission pourrait se donner des permissions pour effectuer certaines des attaques de dépôt mentionnées précédemment.

Pivot vers d'autres services via la lecture et l'écriture de l'Artifact Registry

  • Cloud Functions

Lorsqu'une Cloud Function est créée, une nouvelle image docker est poussée vers l'Artifact Registry du projet. J'ai essayé de modifier l'image avec une nouvelle, et même de supprimer l'image actuelle (et l'image cache), et rien n'a changé, la fonction cloud continue de fonctionner. Par conséquent, il pourrait être possible d'abuser d'une attaque de condition de course comme avec le bucket pour changer le conteneur docker qui sera exécuté, mais il n'est pas possible de compromettre la Cloud Function juste en modifiant l'image stockée.

  • App Engine

Bien qu'App Engine crée des images docker à l'intérieur de l'Artifact Registry. Il a été testé que même si vous modifiez l'image à l'intérieur de ce service et supprimez l'instance App Engine (de sorte qu'une nouvelle soit déployée), le code exécuté ne change pas. Il pourrait être possible qu'en effectuant une attaque de condition de course comme avec les buckets, il pourrait être possible de remplacer le code exécuté, mais cela n'a pas été testé.

Support HackTricks

Last updated