Skip to content

Esta herramienta no está afiliada a Google LLC ni está respaldada ni patrocinada por Google LLC. Google Cloud y Google Cloud Platform son marcas comerciales de Google LLC. Los demás nombres son marcas comerciales de sus respectivos propietarios.

Clave de cuenta de servicio de GCP filtrada: cómo investigar

¿Clave de cuenta de servicio filtrada en un repositorio o un log de CI? Halle su ID, cada IP que la usó y qué hizo con serviceAccountKeyName.

Publicado el 7 min de lectura

En resumen. Cada llamada a la API autenticada con una clave de cuenta de servicio gestionada por el usuario lleva protoPayload.authenticationInfo.serviceAccountKeyName, terminado en /keys/<KEY_ID>. Filtre por ese ID de clave, liste las IP de origen y los user agents en orden cronológico y busque la primera IP pública que no sepa explicar. A partir de ahí, siga esa IP: enumeración (ráfagas de PERMISSION_DENIED), SetIamPolicy, claves nuevas, cuentas de servicio nuevas. Primero inhabilite la clave; después investigue.

Las claves JSON descargables son la forma más habitual de abrir un proyecto de Google Cloud desde fuera. No caducan por defecto, acaban en repositorios Git, variables de CI, imágenes Docker y portátiles, y quien tiene el archivo es la cuenta de servicio. Las prácticas recomendadas de gestión de claves de Google aconsejan evitarlas por completo; mientras tanto, hay que saber investigar una.

Paso 1: identificar la clave

Normalmente se parte de una de estas situaciones:

  • el propio archivo de clave, cuyo campo private_key_id es el ID de la clave;
  • un aviso de Google de que una clave se ha expuesto públicamente;
  • un hallazgo sobre una cuenta de servicio que hace cosas que nunca hace.

Liste las claves de la cuenta de servicio con gcloud iam service-accounts keys list --iam-account=SA_EMAIL y anote, para cada clave gestionada por el usuario, el ID y la fecha de creación. Luego busque la entrada de creación en los registros Admin Activity:

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

El creador está en authenticationInfo.principalEmail; el nombre de la nueva clave, en protoPayload.response.name. Una clave creada por una persona desde una IP de la oficina semanas antes del incidente cuenta una historia de «filtración por error». Una clave creada durante el incidente, por el atacante, cuenta una historia de persistencia: MITRE ATT&CK T1098.001, credenciales cloud adicionales. Busque también google.iam.admin.v1.UploadServiceAccountKey: una clave pública subida significa que alguien de fuera tiene la mitad privada.

Paso 2: encontrar cada uso de la clave

Los registros de ejemplo para cuentas de servicio de Google muestran que las llamadas hechas con una clave incluyen:

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

Así que la consulta es sencilla:

protoPayload.authenticationInfo.serviceAccountKeyName:"KEY_ID"

Ordene los resultados cronológicamente y construya una pequeña tabla: primera aparición, última aparición, IP de origen, user agent, número de llamadas. Lo que busca:

PatrónInterpretación
Una sola IP, su runner de CI o su oficina, user agent estableUso normal
Una IP pública nueva, otro user agent (gcloud donde solo había Terraform)La clave se ha copiado
Una ráfaga de código de estado 7 (PERMISSION_DENIED) en muchos serviciosAlguien prueba lo que la clave puede hacer: T1580 / T1526
SetIamPolicy, CreateServiceAccountKey, CreateServiceAccount desde esa IPEscalada de privilegios y persistencia

Recuerde que las llamadas de lectura (GetIamPolicy, storage.objects.get, ListServiceAccounts) son registros Data Access. Sin el registro Data Access solo verá las escrituras de la clave. En las llamadas de solo lectura que fallan con PERMISSION_DENIED, Google puede ocultar el correo de quien llama, pero no cuando es una cuenta de servicio (identidades de quien llama en los registros de auditoría), de modo que las lecturas fallidas de una clave filtrada siguen siendo atribuibles.

Paso 3: separar la CI del atacante

Lo difícil no es encontrar IP externas, sino que las claves legítimas también se usan desde fuera de Google Cloud. Un runner de GitHub Actions, el servidor de un socio, el portátil de un desarrollador: todas son «IP públicas». Criterios útiles para distinguirlas:

  • User agent: Terraform y las bibliotecas cliente llevan cadenas con versión; una CLI gcloud en Linux con interactive/True desde un VPS no es su pipeline.
  • Horario: la CI se ejecuta con los commits y según calendario; una sesión de atacante es una ráfaga densa a una hora extraña.
  • Errores: los pipelines rara vez acumulan decenas de llamadas denegadas en pocos minutos; la enumeración, sí.
  • Métodos: los pipelines repiten los mismos métodos; los atacantes llaman a GetIamPolicy sobre la organización y listan secretos, facturación y configuraciones de notificación de Security Command Center.

Paso 4: seguir la IP del atacante, no solo la clave

Cuando tenga la IP del atacante, quite el filtro de la clave y busque solo por la IP:

protoPayload.requestMetadata.callerIp="203.0.113.66"

Los atacantes cambian de identidad en cuanto pueden: conceden Owner a una cuenta que controlan (a menudo una dirección de Gmail) y siguen como esa cuenta desde la misma máquina. La IP une las dos fases. Vea abuso de SetIamPolicy para esa segunda fase y suplantación de cuentas de servicio si la clave se usó para emitir tokens de otras cuentas de servicio.

Paso 5: contener en el orden correcto

La guía de respuesta para credenciales comprometidas de Google y la página inhabilitar y habilitar claves describen la mecánica. El orden que sigo:

  1. Inhabilitar la clave (reversible, inmediato). Si la cuenta de servicio está comprometida más allá de la clave, inhabilitar la cuenta de servicio.
  2. Eliminar lo que el atacante añadió con ella: vinculaciones de IAM, claves, cuentas de servicio, claves HMAC.
  3. Desplegar una credencial de sustitución en la carga de trabajo legítima, a ser posible que no sea una clave: Workload Identity Federation para la CI.
  4. Borrar la clave antigua cuando la investigación haya registrado todo sobre ella.
  5. Dar por expuesto todo lo que la cuenta de servicio podía leer: secretos, buckets, conjuntos de datos. Rotar esos secretos.

Después, elimine la causa raíz: purgue el archivo del historial del repositorio y de los logs de CI, y busque otras copias.

Prevención que funciona de verdad

  • Política de organización iam.disableServiceAccountKeyCreation: no más claves nuevas gestionadas por el usuario.
  • iam.serviceAccountKeyExposureResponse configurada en DISABLE_KEY: Google detecta las claves expuestas en sitios públicos y las inhabilita, avisando a los propietarios y a los contactos de seguridad (blog de Google Cloud).
  • Caducidad para las claves que no pueda evitar y un inventario de las que queden.

Qué marca el analizador

Sobre una exportación cargada en el analizador, la historia de la clave produce hasta cinco hallazgos:

ReglaGravedadSe activa cuando
sa_key_createdMediaCreateServiceAccountKey tuvo éxito
sa_key_uploadedAltaUploadServiceAccountKey tuvo éxito
sa_key_used_externalMediaUna cuenta de servicio se autenticó con una clave gestionada por el usuario desde una IP pública (con cualquier resultado)
sa_key_new_ipAltaUna clave se usó desde una IP pública distinta de la primera vista para ella en los registros
permission_denied_burstMedia20 llamadas denegadas de un mismo principal en 10 minutos

La pestaña Entidades lista cada clave con su creador y todas las IP que la usaron. Un límite que conviene tener presente: «IP nueva» es relativo a la exportación. Si su exportación empieza después del primer uso del atacante, la IP del atacante pasa a ser la referencia. Exporte un periodo más largo siempre que pueda.

Preguntas frecuentes

¿Cómo sé si alguien usó una clave de cuenta de servicio filtrada?

Busque en los registros de auditoría protoPayload.authenticationInfo.serviceAccountKeyName terminado en el ID de la clave. Todas las llamadas hechas con la clave lo llevan. Las llamadas desde direcciones IP que no reconoce, sobre todo después de la fecha de la filtración, indican que otra persona usó la clave.

¿Inhabilita Google automáticamente las claves de cuenta de servicio filtradas?

Google analiza los repositorios públicos en busca de claves expuestas. Con la política de organización iam.serviceAccountKeyExposureResponse configurada en DISABLE_KEY, las claves detectadas se inhabilitan automáticamente y se avisa a los propietarios del proyecto y a los contactos de seguridad.

¿Debo borrar la clave de inmediato?

Inhabilítela primero: la inhabilitación es reversible y detiene al atacante. Anote el ID de la clave y los datos de su creación, y bórrela cuando la investigación ya no la necesite y las cargas de trabajo legítimas tengan un sustituto.

Lecturas recomendadas

Artículos relacionados

Esta herramienta no está afiliada a Google LLC ni está respaldada ni patrocinada por Google LLC. Google Cloud y Google Cloud Platform son marcas comerciales de Google LLC. Los demás nombres son marcas comerciales de sus respectivos propietarios.