Respuesta a incidentes en Kubernetes con los audit logs
Guía de respuesta a incidentes en Kubernetes: qué evidencias reunir en los audit logs, qué preguntas responder, qué patrones de ataque buscar y cómo contener.
TL;DR. En un incidente de Kubernetes, el audit log del API server es tu fuente de verdad: cada kubectl exec, cada lectura de secret, cada binding nuevo y cada workload nuevo pasaron por el API server, y cada uno puede quedar registrado con quién, desde dónde, qué y si se permitió. Preserva primero los logs y después responde cinco preguntas en orden: qué identidad, desde cuándo, qué tocó, qué dejó atrás y a qué puede llegar todavía. El analizador gratuito de audit logs en el navegador te da un primer veredicto, hallazgos mapeados a MITRE ATT&CK y una línea de tiempo sin subir nada; el resto de esta guía explica qué hay detrás de cada paso.
Los incidentes de Kubernetes rara vez empiezan con una alerta que diga «tu clúster está comprometido». Empiezan con una factura cloud que se duplica, un nodo clavado al 100 % de CPU, una regla de Falco que nadie ha ajustado o un token de cuenta de servicio encontrado en un repositorio público. En ese momento necesitas saber rápido si alguien usó realmente el clúster y qué hizo con él.
Por qué el audit log es el centro de la investigación
Todo cambio en un clúster, y la mayoría de las lecturas, pasan por el API server de Kubernetes. La auditoría de Kubernetes registra esas solicitudes como eventos estructurados: el usuario autenticado y sus grupos, las IPs de origen, el user agent, el verbo, el recurso, namespace, nombre y subrecurso de destino, el código de respuesta y, según el nivel de auditoría, los cuerpos de la solicitud y de la respuesta.
Eso lo convierte en el único log que cubre la mayor parte del trabajo de un atacante a través del plano de control:
| Paso del atacante | Qué aparece en el audit log |
|---|---|
| Usa un token robado | Solicitudes de una cuenta de servicio conocida con un user agent o IP de origen inusual |
| Comprueba qué permite el token | Ráfagas de selfsubjectaccessreviews / selfsubjectrulesreviews (kubectl auth can-i) y respuestas 403 |
| Roba credenciales | list sobre secrets sin namespace, muchos get de secrets, solicitudes a serviceaccounts/token |
| Ejecuta comandos | create / get sobre pods/exec o pods/attach, con el comando en requestURI |
| Escala privilegios | Nuevos clusterrolebindings a cluster-admin, roles con escalate / bind / impersonate |
| Escapa al nodo | Pods o DaemonSets con privileged: true, hostPID, un hostPath de / |
| Persiste y monetiza | CronJobs, DaemonSets en kube-system, imágenes de minero |
| Borra huellas | delete / deletecollection sobre events |
Lo que no muestra importa igual: los comandos tecleados dentro de una shell ya abierta, los procesos lanzados en un nodo tras un escape o el tráfico entre pods. El artículo sobre limitaciones cubre esos puntos ciegos y qué fuentes de runtime los cubren.
Paso 0: preservar antes de tocar
El instinto es borrar el pod malicioso. Aguanta unos minutos.
- Exporta los audit logs de todo el periodo y guárdalos fuera del clúster. En plataformas gestionadas están en CloudWatch Logs (EKS), Cloud Logging (GKE) o Azure Monitor (AKS); la guía de exportación para EKS, GKE y AKS tiene los comandos exactos. Revisa la retención: los logs que caducan mañana son lo primero que hay que salvar.
- Guarda los specs de los objetos sospechosos con
kubectl get <kind> <name> -o yamlantes de borrarlos: DaemonSets, CronJobs, pods, ClusterRoleBindings, ServiceAccounts. - Haz snapshots de los discos de los nodos afectados si sospechas un escape de contenedor. Un nodo sustituido se lleva su evidencia.
- Apunta lo que ya has hecho, con la hora en UTC. Tus propios comandos
kubectlaparecerán en el mismo audit log.
Las recomendaciones de AWS sobre respuesta a incidentes y forense en EKS y las mitigaciones de seguridad de GKE de Google siguen el mismo orden: aislar, preservar y luego remediar.
Paso 1: una primera lectura de los logs
Un clúster genera mucho ruido de auditoría: kubelets renovando leases, controladores reconciliando, agentes de monitorización listando pods cada pocos segundos. Leer líneas JSON en bruto no es realista más allá de unos miles de eventos.
Arrastra la exportación al analizador de audit logs de Kubernetes. Normaliza líneas JSON audit.k8s.io/v1 en bruto y los formatos de exportación de EKS, GKE y AKS en un único modelo de evento, aplica 28 reglas de detección revisadas y devuelve:
- un veredicto: «Probable compromiso» cuando salta al menos una regla crítica o tres reglas altas distintas, «Actividad sospechosa» con una regla alta o dos medias, y si no «Sin señales de compromiso»;
- hallazgos agrupados por identidad o imagen, cada uno con severidad, ID de técnica ATT&CK y pasos de remediación;
- una línea de tiempo del incidente en la que se destaca la primera aparición de cada regla;
- un pivote por entidades (usuarios y cuentas de servicio, IPs de origen, namespaces, pods, imágenes, user agents).
Todo se ejecuta en la pestaña del navegador con WebAssembly; los archivos nunca se suben. La guía paso a paso recorre cada panel.
Un veredicto sin señales de compromiso no demuestra que estés a salvo. Significa que ninguna regla coincidió en los datos que aportaste, y esos datos dependen mucho de tu política de auditoría.
Paso 2: responder las cinco preguntas
¿Qué identidad?
Parte del hallazgo de mayor severidad y anota el user.username. Una cuenta de servicio (system:serviceaccount:<namespace>:<name>) manejada con kubectl/ o curl/ como user agent, o desde una IP pública, es casi siempre un token que salió de su pod. Una identidad humana haciendo algo inusual merece una llamada a su dueño antes de sacar conclusiones.
Ten en cuenta que sourceIPs lista primero las cabeceras de proxy; la referencia de eventos de auditoría advierte que todas las direcciones salvo la última las puede fijar el cliente.
¿Desde cuándo?
Filtra los eventos por esa identidad y por sus IPs de origen, y busca la solicitud más antigua. Los atacantes suelen hacer reconocimiento (/version, /api, llamadas de descubrimiento, auth can-i) antes de cualquier acción ruidosa. Si el evento más antiguo está al principio de tu exportación, la exportación se queda corta: retrocede más.
¿Qué tocó?
Lista todos los verbos y recursos de la identidad. Los secrets leídos son lo más urgente: cada uno es una credencial que rotar, y algunos (claves cloud, tokens de CI, credenciales de registry) dan acceso fuera del clúster. Consulta acceso a secrets y robo de tokens de cuenta de servicio.
¿Qué dejó atrás?
Busca escrituras: workloads, CronJobs, DaemonSets, ServiceAccounts, (Cluster)RoleBindings, Roles, webhooks y tokens nuevos emitidos con TokenRequest. Cada uno es una vía de vuelta tras revocar la primera credencial. El artículo sobre escalada RBAC cubre los bindings, el de pods privilegiados la parte de nodos.
¿A qué puede llegar todavía?
Un cluster-admin capaz de hacer exec en un pod privilegiado pudo leer credenciales de nodos, roles de instancia cloud y todos los secrets montados. Amplía el alcance más allá del clúster: la cuenta cloud (CloudTrail, Cloud Audit Logs, Azure Activity Log), el sistema de CI, el registry. Para la parte cloud, los sitios hermanos AWS Forensics, GCP Forensics y Azure Forensics cubren esos logs.
Paso 3: contener, erradicar, recuperar
El orden importa, porque algunos pasos invalidan otros.
- Corta el acceso actual del atacante. Elimina los bindings maliciosos, borra y vuelve a crear las cuentas de servicio comprometidas (un token emitido con TokenRequest sigue siendo válido hasta que caduca salvo que se borre la cuenta de servicio o el objeto al que está ligado, como explica la documentación de cuentas de servicio) y restringe quién puede alcanzar el endpoint de la API.
- Elimina la persistencia. Borra los DaemonSets, CronJobs, Jobs y pods maliciosos, tras guardar sus specs, y busca copias en todos los namespaces.
- Reconstruye los nodos que ejecutaron pods privilegiados o que montaban el host. Cordon, drain, sustitución; rota las credenciales del kubelet y de la instancia cloud.
- Rota cada secret que se haya leído.
- Cierra el punto de entrada: dashboard expuesto, kubeconfig filtrado, token con demasiados privilegios, acceso anónimo.
- Endurece y vigila: Pod Security Admission en todos los namespaces, RBAC de mínimo privilegio, audit logs conservados fuera del clúster. La guía de hardening de Kubernetes de la NSA y la CISA y la checklist de seguridad de Kubernetes son buenas bases.
La checklist de remediación del analizador sigue este orden y solo enumera los pasos relacionados con los hallazgos que realmente tienes.
Mapea los hallazgos a ATT&CK, no a herramientas
El informe es más fácil de escribir cuando cada hallazgo lleva un ID de técnica. La matriz MITRE ATT&CK Containers cubre los pasos habituales: T1609 Container Administration Command para exec, T1610 Deploy Container, T1611 Escape to Host, T1552.007 Container API para el robo de secrets, T1528 Steal Application Access Token, T1098.006 Additional Container Cluster Roles, T1053.007 Container Orchestration Job, T1496 Resource Hijacking. Cada regla de detección del analizador lleva estos IDs, así que la exportación está lista para el informe.
Un ejemplo realista de principio a fin
Si quieres ver todo esto sobre eventos concretos, el recorrido de un incidente ficticio sigue un token de dashboard expuesto hasta cluster-admin y un criptominero en 15 minutos de eventos de auditoría. Los mismos datos están detrás del botón «Probar un ejemplo» de la página del analizador.
FAQ
¿Qué es lo primero que hay que hacer si un clúster de Kubernetes puede estar comprometido?
Preservar la evidencia antes de cambiar nada: exportar los audit logs del API server de todo el periodo, ampliar su retención y guardar los specs de los workloads y bindings sospechosos. Borrar primero un pod o un binding destruye el contexto que necesitarás para delimitar el incidente.
¿Bastan los audit logs de Kubernetes para investigar una intrusión?
Son el registro principal de lo que se hizo a través de la API de Kubernetes, pero no ven los procesos dentro de los contenedores ni en los nodos. Complétalos con alertas de runtime, logs de nodos y contenedores, y los logs del plano de control de tu proveedor cloud.
¿Desde cuándo hay que exportar los audit logs?
Empieza unos días antes del primer evento sospechoso que conozcas y retrocede más cada vez que encuentres un rastro anterior de la misma identidad o IP de origen. El acceso inicial suele ser anterior a la parte ruidosa del ataque.