Postmortem: una cuenta cloud comprometida por credenciales olvidadas

El incidente no empezó con una explotación sofisticada, sino con algo mucho más común en empresas: credenciales antiguas de una cuenta de servicio que nadie recordaba, aún válidas y con permisos “temporales” que nunca se recortaron. El acceso inicial fue silencioso, y cuando el equipo detectó actividad anómala, el atacante ya había tenido tiempo de moverse con calma.

Este postmortem describe el fallo, el análisis de causas, las señales que se ignoraron (o no se vieron), y la respuesta operativa para contener y evitar recurrencia. El foco es práctico: qué revisar, qué configurar y cómo validar que el cierre es real, no solo “aparente”.

Qué salió mal: credenciales antiguas que seguían vivas

La puerta de entrada fueron unas claves de acceso programático (access key) asociadas a una cuenta de servicio creada para una integración puntual. En su día se justificó por urgencia: “si no lo hacemos hoy, el proyecto se para”. El problema no fue crear la credencial, sino que se convirtió en una dependencia invisible: se copió a un sistema heredado, se replicó en otro entorno y nunca volvió al radar de nadie.

El patrón típico en empresas es que esas claves acaban en varios lugares: variables de entorno en un servidor, un secreto en un vault mal gobernado, o un pipeline antiguo. Cuando se intenta limpiar años después, nadie se atreve a rotarlas porque “algo crítico podría romperse”. Ese miedo operativo mantiene viva la exposición.

La consecuencia real fue que el atacante no necesitó vulnerar nada: autenticó como un principal legítimo. A partir de ahí, la plataforma de seguridad no vio un exploit, vio “una cuenta de servicio haciendo llamadas”, y la diferencia entre tráfico normal y abuso quedó en los detalles de comportamiento y contexto.

Análisis de causa raíz: gobierno IAM débil y deuda operativa acumulada

El incidente tuvo múltiples factores, pero la raíz fue organizativa y de control: no había un inventario confiable de identidades no humanas (service accounts), ni un proceso de caducidad/rotación que se cumpliese de verdad. La empresa tenía políticas “escritas”, pero no automatismos que las hicieran inevitables.

Otro elemento fue el exceso de permisos. La cuenta de servicio tenía permisos amplios para “evitar tickets”: lectura de secretos, enumeración de recursos y capacidad de asumir roles que, en teoría, solo se usaban en mantenimiento. Esto es frecuente cuando se delega en el equipo de plataforma “para que no moleste al negocio” y se aprueba una política demasiado abierta sin fecha de expiración.

Un anti-patrón habitual aquí es usar una única cuenta de servicio “comodín” para varios sistemas. Cuando algo falla, es imposible aislar: rotar rompe demasiadas piezas a la vez; restringir permisos genera incidentes; y el resultado es inmovilismo. A nivel forense, además, se pierde trazabilidad: demasiados procesos comparten identidad y las señales se diluyen.

Señales tempranas que llegaron tarde: telemetría sin contexto operativo

Las señales existían, pero no estaban conectadas a decisiones. Hubo llamadas inusuales a APIs de IAM y Secrets desde rangos de IP no habituales y en horarios atípicos, pero los umbrales estaban calibrados para “no generar ruido”. En muchas organizaciones, se prefiere tolerar falsos negativos antes que lidiar con alertas que nadie atiende.

También aparecieron patrones de reconocimiento: enumeración de roles, políticas y recursos en ráfagas cortas. Eso suele confundirse con scripts internos de inventariado si no se dispone de etiquetas (tags), naming y ownership claros para diferenciar automatizaciones corporativas de comportamiento de intruso.

  • Accesos desde geolocalizaciones nuevas o ASN no corporativos

Si la cuenta de servicio normalmente opera desde una VPC/egress controlado o desde un runner específico, cualquier desviación debería disparar una investigación inmediata. En el incidente, ese dato estaba en logs, pero no existía una regla que lo convirtiera en acción.

  • Uso de APIs de identidad como paso inicial

Llamadas tempranas tipo “quién soy” y “qué puedo hacer” (por ejemplo, consultas a identidad, listing de roles/policies, lectura de secretos) son una señal de exploración. En un flujo legítimo de aplicación, ese patrón suele ser estable y repetible; en abuso, aparece como una secuencia nueva y corta.

El aprendizaje operativo fue claro: no basta con “tener logs”. Hace falta contexto de funcionamiento normal por identidad. Sin baseline por cuenta de servicio, se tiende a tratar todo como “ruido” hasta que el impacto es visible (coste, fuga o interrupción).

Contención y erradicación: cortar acceso sin romper el negocio

La primera decisión fue asumir que la credencial estaba comprometida y actuar como si hubiera persistencia. En la práctica, el reto fue contener sin provocar una caída masiva: la clave antigua alimentaba procesos que nadie recordaba. Por eso, la contención tuvo que ser gradual y verificada, no un “delete y ya”.

El equipo empezó por limitar el radio de acción: bloquear el uso desde ubicaciones no esperadas, reducir permisos a lo mínimo necesario y forzar trazabilidad. En paralelo, se buscó el origen: dónde estaba almacenada la clave (servidores, repositorios, pipelines, herramientas de ITSM, etc.) y quién la estaba usando.

Cómo hacerlo en la práctica

  • Desactivar la access key comprometida y crear una nueva con ventana controlada

Primero, desactiva (no borres) la key para poder revertir si rompes un proceso crítico; después crea una nueva key solo si no hay alternativa (idealmente migrando a credenciales temporales). Valida el impacto revisando el error rate de los servicios dependientes y los logs de autenticación fallida asociados a esa identidad.

  • Aplicar una política de denegación explícita temporal (guardrail) mientras investigas

Cuando no puedes rotar de inmediato, un guardrail reduce daño: limita acciones sensibles (por ejemplo, lectura de secretos, cambios IAM, asunción de roles) mientras identificas consumidores legítimos. La clave es que sea temporal, revisable y con owner claro.

  • Buscar uso real de la identidad en logs para encontrar dependencias ocultas

Identifica qué servicios, recursos y horarios están asociados al uso legítimo. Un hallazgo típico es que hay jobs “huérfanos” (scripts en cron, runners antiguos, integraciones de terceros) que todavía tiran de esas credenciales. Sin ese mapa, la erradicación se convierte en una ruleta.

En este punto es donde muchas empresas fallan: se “soluciona” rotando y restaurando rápido para apagar el fuego, pero no se elimina la causa. La erradicación real exige retirar el mecanismo que permite que existan credenciales olvidadas operando sin dueño.

Prevención real: eliminar credenciales olvidadas como clase de problema

La medida más efectiva fue migrar las integraciones a credenciales temporales y relaciones de confianza bien delimitadas, de forma que no existan claves de larga vida olvidables. Cuando se pasa a tokens temporales, el riesgo cambia: un secreto filtrado deja de ser una llave permanente y se convierte en una ventana acotada.

En paralelo se implantaron controles que no dependieran de la memoria humana: caducidad por diseño, inventario obligatorio, ownership y revisiones automáticas. Si la organización acepta que “las cosas se olvidan”, debe hacer que el olvido no sea equivalente a exposición.

Ejemplo de control técnico (AWS IAM) para forzar credenciales temporales

Si una carga debe acceder a AWS, prioriza roles con STS (por ejemplo, a través de IAM Roles for Service Accounts en Kubernetes, instance profiles en EC2, o roles asumidos desde un IdP). En lugar de permitir access keys en usuarios IAM para automatización, restringe su creación y uso. Una aproximación habitual es: bloquear a nivel organizativo el uso de access keys salvo excepciones aprobadas, y exigir que las identidades no humanas sean roles asumibles con condiciones (origen, audiencia, tags, etc.).

Cómo validar que está bien aplicado

  • Inventario de access keys activas y su antigüedad

Verifica cuántas access keys siguen activas, cuánto tiempo llevan sin rotar y qué identidades las poseen. El objetivo práctico es que ese número tienda a cero y que cualquier excepción tenga owner, motivo y fecha de revisión.

  • Revisión de permisos efectivos del principal comprometido

No te quedes en “políticas adjuntas”: valida el permiso efectivo (incluyendo policies heredadas, permisos por grupos/roles y límites tipo permission boundaries). En incidentes reales, el exceso de privilegio suele estar escondido en una combinación de permisos legítimos acumulados.

  • Alertas basadas en comportamiento por identidad

Configura detecciones que miren “esta identidad hace esto desde aquí y en este patrón” en lugar de umbrales globales. Es lo que diferencia una alerta accionable de una bandeja de entrada llena.

Recomendaciones para entornos corporativos

Este compromiso no ocurrió por una técnica avanzada, sino por credenciales olvidadas y permisos acumulados en una cuenta de servicio sin dueño real. La lección operativa es que las identidades no humanas necesitan el mismo ciclo de vida que cualquier activo crítico: inventario, ownership, caducidad y controles automáticos que impidan que la deuda se convierta en acceso persistente.

Las señales “tardías” fueron el resultado de telemetría sin contexto: había registros, pero no baseline por identidad ni reglas que convirtieran desviaciones en investigación inmediata. Cuando el atacante usa un principal legítimo, la diferencia está en el comportamiento; si no lo modelas, lo normal y lo malicioso se parecen demasiado.

En la respuesta, la contención efectiva fue la que equilibró seguridad y continuidad: desactivar/rotar con verificación, reducir permisos y mapear dependencias antes de cortar. Y en prevención, el objetivo corporativo debe ser que las credenciales de larga vida desaparezcan del día a día, sustituidas por credenciales temporales y guardrails que hagan difícil “olvidar” algo en producción.


¿Te interesa la seguridad en Cloud?

Comparto análisis técnicos, laboratorios prácticos y experiencias reales sobre Cloud Security.

Política de privacidad