Abuso de SetIamPolicy: detectar Owner y miembros externos
Lea las entradas SetIamPolicy como un investigador: bindingDeltas, Owner para cuentas de Gmail, dominios desconocidos, allUsers, Token Creator.
En resumen. Cada cambio en una política de IAM es una entrada Admin Activity, y lo útil no es la política completa de la solicitud, sino la diferencia: serviceData.policyDelta.bindingDeltas (o metadata.policyDelta, metadata.datasetChange en BigQuery), con action, role y member por cada cambio. Busque ADD de roles/owner, roles/editor o roles de administración de IAM, de cuentas personales (@gmail.com), de dominios que nunca aparecen entre quienes hacen llamadas, de allUsers y de los roles Token Creator / Service Account User.
En cuanto un atacante tiene una credencial con el permiso setIamPolicy, lo primero que suele hacer es darse una identidad duradera que controla. En términos de MITRE ATT&CK es T1098.003, Additional Cloud Roles. También es el paso más fácil de detectar, porque los registros Admin Activity están siempre activos y se conservan 400 días.
Qué contiene una entrada SetIamPolicy
gcloud projects add-iam-policy-binding parece un cambio pequeño, pero la API funciona en lectura-modificación-escritura: el cliente llama a GetIamPolicy, edita la política en local y la devuelve entera con SetIamPolicy. Por tanto, la solicitud contiene toda la política nueva. Leerla le dice el resultado, no lo que cambió.
El cambio está en el delta de la política:
"serviceData": {
"@type": "type.googleapis.com/google.iam.v1.logging.AuditData",
"policyDelta": {
"bindingDeltas": [
{ "action": "ADD", "role": "roles/owner", "member": "user:someone@gmail.com" }
]
}
}
Según el servicio y la versión de la API, la misma estructura aparece en protoPayload.metadata.policyDelta o, para los conjuntos de datos y tablas de BigQuery, en metadata.datasetChange.bindingDeltas / metadata.tableChange.bindingDeltas (registros de auditoría de BigQuery).
El nombre del método también varía según el recurso:
| Recurso | methodName habitual |
|---|---|
| Proyecto, carpeta, organización | SetIamPolicy (servicio cloudresourcemanager.googleapis.com) |
| Bucket de Cloud Storage | storage.setIamPermissions |
| Cuenta de servicio | google.iam.admin.v1.SetIAMPolicy |
| Imagen, instantánea o disco de Compute | v1.compute.images.setIamPolicy, …snapshots.setIamPolicy |
| Conjunto de datos o tabla de BigQuery | Actualización del conjunto de datos o métodos IAM de tabla; el delta está en metadata.datasetChange / metadata.tableChange |
Así que busque por el delta, no solo por un nombre de método.
Las cinco concesiones que importan
1. Owner, Editor y roles de administración de IAM
roles/owner y roles/editor son los roles básicos con control (casi) total (descripción general de los roles). roles/resourcemanager.projectIamAdmin, roles/resourcemanager.organizationAdmin y roles/iam.securityAdmin son igual de peligrosos, porque permiten conceder cualquier otra cosa. Cualquier ADD de estos roles durante la ventana del incidente es una pista.
2. Cuentas personales
Un miembro terminado en @gmail.com o @googlemail.com es una cuenta de Google personal. A los atacantes les encantan: gratuitas, anónimas y sobreviven a la rotación de todas las credenciales de su organización. ADD roles/owner user:x@gmail.com es, salvo que se trate de una cuenta de emergencia documentada, una toma de control.
3. Dominios desconocidos
Menos evidente: un miembro user: o group: de un dominio que nunca aparece como origen de llamadas en sus registros. Puede ser un proveedor externo; puede ser el propio tenant de Workspace del atacante. La restricción de uso compartido restringido por dominio (iam.allowedPolicyMemberDomains) impide ambos casos.
4. allUsers y allAuthenticatedUsers
Estos principales especiales hacen público un recurso. En un bucket, significa que cualquiera en Internet puede leer los objetos. Vea allUsers y el artículo sobre exfiltración.
5. Roles de suplantación
roles/iam.serviceAccountTokenCreator, roles/iam.serviceAccountUser, roles/iam.serviceAccountKeyAdmin y roles/iam.workloadIdentityUser permiten al miembro actuar como cuentas de servicio. Son más discretos que Owner y a menudo pasan desapercibidos. Vea suplantación de cuentas de servicio.
Cambios alrededor de la política
Otros dos eventos Admin Activity forman parte de la misma revisión:
- Cambios en políticas de organización (
google.cloud.orgpolicy.v2.OrgPolicy.CreatePolicy,UpdatePolicy,DeletePolicy, o los antiguosSetOrgPolicy/ClearOrgPolicy). Un atacante que relajaiam.allowedPolicyMemberDomainsantes de añadir una cuenta de Gmail, oiam.disableServiceAccountKeyCreationantes de crear claves, está preparando el siguiente paso (T1484). - Roles personalizados (
google.iam.admin.v1.CreateRole,UpdateRole,UndeleteRole). Un rol llamado «Viewer (legacy)» puede conteneriam.serviceAccountKeys.create. La investigación de Rhino Security Labs sobre la escalada de privilegios en GCP incluyeiam.roles.updateentre las vías de escalada.
Los cambios de configuración de auditoría (auditConfigDeltas) también pasan por SetIamPolicy; se tratan en evasión de defensas.
Investigar una concesión sospechosa
Para cada delta sospechoso, responda:
- ¿Quién hizo la llamada?
authenticationInfo.principalEmail, yserviceAccountKeyNameoserviceAccountDelegationInfosi aparecen. Una concesión hecha por una cuenta de servicio de CI con una clave, desde un VPS, no es un error humano. - ¿Desde dónde?
requestMetadata.callerIpy el user agent. Compárelos con las IP habituales del principal. - ¿Qué pasó después? Busque el nuevo miembro como
principalEmail. Una cuenta que recibe Owner y actúa desde la misma IP a los pocos minutos cierra el círculo. - ¿Sigue ahí? Las últimas respuestas de
SetIamPolicy, o ungcloud projects get-iam-policyactual, le dicen si se quitó la vinculación. - ¿Qué más cambió? Busque también deltas
REMOVE: a veces los atacantes eliminan a los propietarios legítimos.
Una consulta de Logs Explorer que captura la mayoría de los cambios a nivel de proyecto:
logName:"cloudaudit.googleapis.com%2Factivity"
protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
Qué marca el analizador
Las reglas del analizador evalúan cada delta por separado, sea cual sea el recurso:
| Regla | Gravedad | Condición sobre un delta |
|---|---|---|
owner_to_consumer | Crítica | ADD de roles/owner o roles/editor a un miembro @gmail.com / @googlemail.com |
public_access_granted | Crítica | ADD de allUsers o allAuthenticatedUsers |
owner_editor_granted | Alta | ADD de Owner, Editor, Organization Admin, Project IAM Admin o Security Admin |
consumer_account_granted | Alta | ADD de cualquier cuenta personal |
token_creator_granted | Alta | ADD de Token Creator, Service Account User, Key Admin o Workload Identity User |
new_external_domain (análisis) | Media | ADD de un miembro de un dominio nunca visto entre quienes hacen llamadas |
org_policy_changed | Media | Política de organización creada, actualizada o borrada |
custom_role_changed | Baja | Rol personalizado creado, actualizado o recuperado |
Los objetivos se muestran como deltas legibles (ADD roles/owner user:…) y la pestaña Entidades marca las cuentas personales como «Gmail personal».
Remediación
Quite las vinculaciones y después revise toda la jerarquía (proyecto, carpetas, organización) en busca de otros añadidos; aplique el uso compartido restringido por dominio; revise los roles personalizados; y restaure cualquier política de organización que se haya relajado. La guía de Google para credenciales comprometidas cubre la parte de identidad.
Preguntas frecuentes
¿Cómo veo quién concedió Owner en un proyecto de Google Cloud?
Consulte los registros de auditoría Admin Activity con protoPayload.methodName="SetIamPolicy" y lea protoPayload.serviceData.policyDelta.bindingDeltas: cada delta tiene una acción (ADD o REMOVE), un rol y un miembro. Quien hizo la llamada está en protoPayload.authenticationInfo.principalEmail.
¿Una cuenta gmail.com en una política de IAM es siempre maliciosa?
No: algunas organizaciones pequeñas usan cuentas personales y existen las cuentas de emergencia (break-glass). Pero una cuenta personal que recibe roles/owner durante un incidente es el movimiento clásico de toma de control, y la política iam.allowedPolicyMemberDomains existe para impedirlo.
Lecturas recomendadas
- Descripción general de los roles de IAM — documentación de Google Cloud.
- Restringir identidades por dominio — documentación de Google Cloud.
- Privilege Escalation in Google Cloud Platform – Part 1 (IAM) — Rhino Security Labs.
- Clave de cuenta de servicio de GCP filtrada: cómo investigar.