Skip to content

Cet outil n'est ni affilié à Google LLC, ni approuvé, ni sponsorisé par Google LLC. Google Cloud et Google Cloud Platform sont des marques de Google LLC. Les autres noms sont des marques de leurs propriétaires respectifs.

Clé de compte de service GCP divulguée : enquêter

Clé de compte de service fuitée dans un dépôt ou un log de CI ? Trouvez son ID, les IP qui l'ont utilisée, ses actions via serviceAccountKeyName.

Publié le 7 min de lecture

En bref. Chaque appel d'API authentifié avec une clé de compte de service gérée par l'utilisateur porte protoPayload.authenticationInfo.serviceAccountKeyName, qui se termine par /keys/<KEY_ID>. Filtrez sur cet ID de clé, listez les IP d'appel et les user agents dans l'ordre chronologique, et cherchez la première IP publique que vous ne savez pas expliquer. Ensuite, suivez cette IP : énumération (rafales de PERMISSION_DENIED), SetIamPolicy, nouvelles clés, nouveaux comptes de service. Désactivez la clé d'abord, enquêtez ensuite.

Les clés JSON téléchargeables sont la façon la plus courante d'ouvrir un projet Google Cloud depuis l'extérieur. Elles n'expirent pas par défaut, finissent dans des dépôts Git, des variables de CI, des images Docker et des portables, et celui qui détient le fichier est le compte de service. Les bonnes pratiques de gestion des clés de Google recommandent de s'en passer ; en attendant, il faut savoir enquêter sur une clé.

Étape 1 : identifier la clé

On part généralement de l'un de ces éléments :

  • le fichier de clé lui-même, dont le champ private_key_id est l'ID de la clé ;
  • une notification de Google indiquant qu'une clé a été exposée publiquement ;
  • un constat sur un compte de service qui fait des choses qu'il ne fait jamais.

Listez les clés du compte de service avec gcloud iam service-accounts keys list --iam-account=SA_EMAIL et notez, pour chaque clé gérée par l'utilisateur, son ID et sa date de création. Retrouvez ensuite l'entrée de création dans les journaux Admin Activity :

protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"

Le créateur figure dans authenticationInfo.principalEmail, le nom de la nouvelle clé dans protoPayload.response.name. Une clé créée par une personne depuis l'IP du bureau des semaines avant l'incident raconte une fuite par erreur. Une clé créée pendant l'incident, par l'attaquant, raconte une persistance : MITRE ATT&CK T1098.001, identifiants cloud supplémentaires. Cherchez aussi google.iam.admin.v1.UploadServiceAccountKey : une clé publique importée signifie que quelqu'un, à l'extérieur, détient la moitié privée.

Étape 2 : retrouver chaque utilisation de la clé

Les exemples de journaux pour les comptes de service de Google montrent que les appels effectués avec une clé contiennent :

"serviceAccountKeyName": "//iam.googleapis.com/projects/PROJECT/serviceAccounts/SA_EMAIL/keys/KEY_ID"

La requête est donc simple :

protoPayload.authenticationInfo.serviceAccountKeyName:"KEY_ID"

Classez les résultats par date et construisez un petit tableau : première et dernière apparition, IP d'appel, user agent, nombre d'appels. Ce que vous cherchez :

MotifLecture
Une seule IP, votre runner de CI ou le bureau, user agent stableUsage normal
Une nouvelle IP publique, un user agent différent (gcloud là où il n'y avait que Terraform)La clé a été copiée
Une rafale de code d'état 7 (PERMISSION_DENIED) sur de nombreux servicesQuelqu'un teste ce que la clé permet : T1580 / T1526
SetIamPolicy, CreateServiceAccountKey, CreateServiceAccount depuis cette IPÉlévation de privilèges et persistance

Rappelez-vous que les appels en lecture (GetIamPolicy, storage.objects.get, ListServiceAccounts) sont des journaux Data Access. Sans journalisation Data Access, vous ne verrez que les écritures de la clé. Pour les lectures refusées avec PERMISSION_DENIED, Google peut masquer l'e-mail de l'appelant, mais pas lorsqu'il s'agit d'un compte de service (identités des appelants dans les journaux d'audit) : les lectures refusées d'une clé divulguée restent donc attribuables.

Étape 3 : distinguer la CI de l'attaquant

Le plus difficile n'est pas de trouver des IP externes, c'est que les clés légitimes sont elles aussi utilisées hors de Google Cloud. Un runner GitHub Actions, le serveur d'un partenaire, le portable d'un développeur : ce sont toutes des « IP publiques ». Quelques critères discriminants :

  • User agent : Terraform et les bibliothèques clientes portent des chaînes versionnées ; une CLI gcloud sous Linux en interactive/True depuis un VPS n'est pas votre pipeline.
  • Horaires : la CI tourne sur des commits et des planifications ; une session d'attaquant est une rafale dense à une heure inhabituelle.
  • Erreurs : un pipeline rencontre rarement des dizaines d'appels refusés en quelques minutes ; une énumération, si.
  • Méthodes : un pipeline répète les mêmes méthodes ; un attaquant appelle GetIamPolicy sur l'organisation, liste les secrets, la facturation et les configurations de notification de Security Command Center.

Étape 4 : suivre l'IP de l'attaquant, pas seulement la clé

Une fois l'IP de l'attaquant connue, retirez le filtre sur la clé et cherchez l'IP seule :

protoPayload.requestMetadata.callerIp="203.0.113.66"

Les attaquants changent d'identité dès qu'ils le peuvent : ils accordent Owner à un compte qu'ils contrôlent (souvent une adresse Gmail) et continuent sous ce compte depuis la même machine. L'IP relie les deux phases. Voir l'abus de SetIamPolicy pour la seconde phase, et l'emprunt d'identité de comptes de service si la clé a servi à émettre des jetons pour d'autres comptes de service.

Étape 5 : contenir dans le bon ordre

Le guide de Google pour les identifiants compromis et la page désactiver et activer des clés décrivent la mécanique. L'ordre que j'applique :

  1. Désactiver la clé (réversible, immédiat). Si le compte de service lui-même est compromis au-delà de la clé, désactiver le compte de service.
  2. Retirer ce que l'attaquant a ajouté avec : liaisons IAM, clés, comptes de service, clés HMAC.
  3. Déployer un identifiant de remplacement pour la charge de travail légitime, de préférence pas une clé : la fédération d'identité de charge de travail pour la CI.
  4. Supprimer l'ancienne clé une fois que l'enquête a tout consigné à son sujet.
  5. Considérer comme exposé tout ce que le compte de service pouvait lire : secrets, buckets, jeux de données. Renouveler ces secrets.

Traitez ensuite la cause : purgez le fichier de l'historique du dépôt et des logs de CI, et cherchez d'autres copies.

La prévention qui fonctionne vraiment

  • Règle d'administration iam.disableServiceAccountKeyCreation : plus de nouvelles clés gérées par l'utilisateur.
  • iam.serviceAccountKeyExposureResponse réglée sur DISABLE_KEY : Google détecte les clés exposées dans des lieux publics et les désactive, en prévenant propriétaires et contacts de sécurité (blog Google Cloud).
  • Une expiration pour les clés inévitables, et un inventaire de celles qui restent.

Ce que l'analyseur signale

Sur un export déposé dans l'analyseur, l'histoire d'une clé produit jusqu'à cinq constats :

RègleSévéritéSe déclenche quand
sa_key_createdMoyenneCreateServiceAccountKey a réussi
sa_key_uploadedHauteUploadServiceAccountKey a réussi
sa_key_used_externalMoyenneUn compte de service s'est authentifié avec une clé gérée par l'utilisateur depuis une IP publique (quel que soit le résultat)
sa_key_new_ipHauteUne clé a été utilisée depuis une IP publique autre que la première vue pour elle dans les journaux
permission_denied_burstMoyenne20 appels refusés pour un même principal en 10 minutes

L'onglet Entités liste chaque clé avec son créateur et toutes les IP qui l'ont utilisée. Une limite à garder en tête : « nouvelle IP » est relatif à l'export. Si l'export commence après la première utilisation par l'attaquant, l'IP de l'attaquant devient la référence. Exportez une période plus longue quand c'est possible.

Questions fréquentes

Comment savoir si une clé de compte de service divulguée a été utilisée ?

Cherchez dans les journaux d'audit protoPayload.authenticationInfo.serviceAccountKeyName se terminant par l'ID de la clé. Chaque appel effectué avec la clé le porte. Des appels depuis des adresses IP que vous ne reconnaissez pas, surtout après la date de la fuite, signifient que quelqu'un d'autre a utilisé la clé.

Google désactive-t-il automatiquement les clés de compte de service divulguées ?

Google analyse les dépôts publics à la recherche de clés exposées. Avec la règle d'administration iam.serviceAccountKeyExposureResponse réglée sur DISABLE_KEY, les clés détectées sont désactivées automatiquement et les propriétaires du projet ainsi que les contacts de sécurité sont prévenus.

Faut-il supprimer la clé immédiatement ?

Désactivez-la d'abord : la désactivation est réversible et arrête l'attaquant. Consignez l'ID de la clé et les détails de sa création, puis supprimez-la quand l'enquête n'en a plus besoin et que les charges de travail légitimes disposent d'un remplacement.

Pour aller plus loin

Articles liés

Cet outil n'est ni affilié à Google LLC, ni approuvé, ni sponsorisé par Google LLC. Google Cloud et Google Cloud Platform sont des marques de Google LLC. Les autres noms sont des marques de leurs propriétaires respectifs.