# GCP - Privesc de l'Artifact Registry

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

## Artifact Registry

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

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

### 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 :
```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]
> Il a été vérifié qu'il est **possible de télécharger une nouvelle image docker malveillante** avec le même nom et tag que celle déjà présente, donc l'**ancienne perdra le tag** et la prochaine fois que cette image avec ce tag sera **téléchargée, la malveillante** sera téléchargée.

<details>

<summary>Télécharger une bibliothèque Python</summary>

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

```bash
mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
```

2.  **É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!" :

```python
# hello_world/greet.py
def say_hello():
return "Hello, World!"
```

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

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

```sh
python3 setup.py sdist bdist_wheel
```

2.  **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/*
```
````
3. **Nettoyer la construction**
```bash
rm -rf dist build hello_world.egg-info
```
</details>

> [!CAUTION]
> 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écessite `artifactregistry.versions.delete)`**:**
>
> ```sh
> gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
> ```

### `artifactregistry.repositories.downloadArtifacts`

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

Téléchargez une **image** **Docker** :
```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>
```
Téléchargez une bibliothèque **python** :
```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
```
- 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 :

{{#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`)

Supprimez des artefacts du registre, comme des images docker :
```bash
# 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`), mais 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é.

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