Esta historia es la que nadie quiere reconocer en un postmortem: no hubo 0-days, ni ingeniería social sofisticada, ni “APTs”. Hubo una credencial filtrada, permisos sobrantes y detección tardía. El resultado fue control operativo del entorno en menos de una hora, con persistencia suficiente como para sobrevivir a cambios de contraseña.
El escenario es corporativo y común: varios equipos deployan en cloud, hay automatización, existen cuentas de servicio antiguas “porque funcionan”, y el SOC recibe demasiadas alertas como para investigar cada anomalía de IAM. La cadena completa cabe en un turno corto.
Minuto 0–10: la credencial filtrada se convierte en acceso real
El punto de entrada no fue un usuario humano, sino una credencial de automatización: una access key expuesta en un repositorio (privado, pero clonado fuera del perímetro). En cuanto la clave aparece en manos del atacante, el primer movimiento no es “atacar”, es comprobar si vive: una llamada de identidad y un par de listados para medir superficie.
En AWS, lo típico es arrancar con sts:GetCallerIdentity y, si responde, enumerar permisos efectivos con llamadas baratas: listar buckets, describir instancias, leer parámetros, ver repos de contenedores. No hace falta un escáner agresivo; con 20–30 requests bien elegidas se dibuja el mapa. En empresa, este comportamiento se camufla fácilmente entre pipelines legítimos si no tienes baseline de origen y frecuencia.
- Señal operativa: origen geográfico y ASN no habituales.
Si en tus accesos de CI salen de rangos conocidos (NAT, runners, IPs corporativas) y de repente ves llamadas firmadas desde un ASN o cloud distinto, eso es un IoC claro. Muchas organizaciones solo alertan por “login console”; aquí no hay consola.
- Señal operativa: patrón de enumeración temprano.
Una access key comprometida suele empezar con llamadas de descubrimiento (List*, Describe*, Get*) a servicios que el pipeline original no toca. Si no estás registrando y agregando CloudTrail (o equivalente) con detecciones sobre secuencias, el atacante gana minutos.
Minuto 10–25: escalada por permisos “utilitarios” que nadie revisó
La escalada rara vez viene de “Admin” directo; suele venir de permisos comodín que se justificaron por velocidad: iam:PassRole para ejecutar jobs, permisos de lambda:UpdateFunctionCode para hotfix, o capacidad de editar tareas de contenedor. Con eso, el atacante no necesita romper IAM: necesita encontrar un servicio que pueda ejecutar código bajo un rol más privilegiado.
Un camino realista: la credencial filtrada pertenece a un usuario/rol de CI con permisos para actualizar una función Lambda y ejecutarla, y además existe un rol de ejecución de Lambda con permisos amplios (por ejemplo, acceso a Secrets Manager/Parameter Store y capacidad de asumir roles internos). El atacante sube un payload mínimo que exfiltra secretos y, en el mismo flujo, intenta sts:AssumeRole hacia un rol con más privilegios, o extrae credenciales temporales de donde el runtime las expone.
En empresa esto ocurre porque “la Lambda solo la toca el equipo de plataforma” o porque el rol de ejecución se creó con una política amplia para evitar incidencias. Esa comodidad (menos fricción hoy) se paga en escalada mañana.
- Consecuencia típica: robo de secretos de integración.
Con acceso a secretos, el atacante no solo progresa dentro de la cuenta; también puede saltar a SaaS (Git, monitorización, email transaccional) o a otras cuentas/tenants si hay llaves compartidas. En muchos incidentes, el impacto principal no es las cargas de trabajo en máquinas virtuales: es el “grafo de integraciones” que se abre.
- Señal operativa: cambios en código/config de funciones o tareas fuera de ventana.
Un update de Lambda/ECS/Batch fuera de un despliegue, desde un principal que normalmente solo hace builds, es una anomalía fuerte. Si el control de cambios vive en Git pero los permisos permiten modificar en caliente, estás dando una puerta lateral difícil de auditar.
Minuto 25–45: persistencia que sobrevive a rotación de credenciales
Una vez que el atacante obtiene un rol con capacidad sobre IAM, el objetivo cambia: dejar de depender de la credencial filtrada (que puede revocarse) y crear persistencia “legítima”. En entornos cloud, persistencia suele ser IAM + automatización: un usuario nuevo “de integración”, una access key adicional en un usuario existente, o una relación de confianza (trust policy) que permite asumir un rol desde otra cuenta controlada por el atacante.
El método que más se cuela en revisiones es el trust policy. No hay que crear usuarios; basta con modificar la relación de confianza de un rol usado en producción para permitir sts:AssumeRole desde un principal externo. A nivel operativo, la cuenta seguirá funcionando y los equipos verán que “nada se cayó”, pero ya existe una entrada estable.
Ejemplo de trust policy peligrosa (AWS) que introduce persistencia:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "sts:AssumeRole"
}
]
}
En una cuenta corporativa, ese 111122223333 puede ser una cuenta externa “de pruebas” que nadie recuerda, o directamente una cuenta del atacante. Si no tienes control de drift y alertas sobre cambios en AssumeRolePolicyDocumentesto pasa desapercibido.
Cómo hacerlo en la práctica (validación mínima):
- Verificar cambios recientes en roles (CloudTrail).
Busca eventos como UpdateAssumeRolePolicy, PutRolePolicy, AttachRolePolicy, CreateAccessKey y UpdateLoginProfile. No es “tener logs”: es tener consultas y alertas por estos verbos con contexto (principal que lo ejecuta, IP, user-agent, hora).
- Revisar trust policies en roles críticos.
Audita roles con privilegios (por ejemplo, los que tocan IAM, KMS, organizaciones, redes). Cualquier Principal cross-account debe estar justificado, documentado y preferiblemente acotado con Condition (como aws:PrincipalArn, sts:ExternalId si aplica, o restricciones por tags).
Minuto 45–60: control operativo y capacidad de impacto en negocio
Con persistencia establecida, el atacante ya no está “dentro”: está en posición de operar. El siguiente paso realista no siempre es borrar recursos; muchas veces es preparar monetización o extorsión: exportar datos, crear snapshots, copiar objetos a un bucket externo, o deshabilitar controles para moverse sin ruido. Si existe acceso a KMS o a llaves usadas por servicios, el radio de impacto se multiplica.
En organizaciones con varias cuentas, una vía habitual es abusar de roles de acceso entre cuentas (por ejemplo, roles de lectura central, roles de despliegue, roles de auditoría) para pivotar. No necesitas admin global si puedes asumir un rol en la cuenta de logs o en la cuenta de red: desde ahí puedes degradar visibilidad o abrir caminos laterales.
- Señal operativa: exfiltración “legal” usando APIs de exportación.
No verás “descarga masiva” si el atacante usa mecanismos nativos: GetObject selectivo, copias server-side, exportaciones programadas, snapshots compartidos. Por eso importan las alertas por acciones sensibles, no solo por volumen de tráfico.
- Consecuencia típica: el equipo rota credenciales… y el atacante vuelve.
Este es el fallo más caro en respuesta: se revoca la access key filtrada, pero se ignoran los cambios de IAM que ya dejaron backdoors. A las 24–48 horas aparece actividad “misteriosa” y se asume un segundo compromiso, cuando en realidad es el mismo acceso persistente.
Recomendaciones para entornos corporativos
Esta cadena termina en menos de una hora porque cada eslabón se apoya en decisiones de operación reales: credenciales estáticas en automatización, permisos amplios para evitar fricción y falta de detección específica en IAM. El atacante no necesita sofisticación cuando la cuenta le permite ejecutar código con un rol útil y modificar relaciones de confianza.
Las señales clave estuvieron disponibles desde el minuto 1: orígenes anómalos, enumeración fuera de patrón, cambios en código/config de runtimes y, sobre todo, modificaciones de IAM (políticas, access keys y trust policies). En un entorno corporativo maduro, esas señales se tratan como eventos de alta criticidad con respuesta rápida, porque indican capacidad de persistencia.
Operativamente, lo que marca la diferencia es validar y proteger el “plano de control”: registrar y centralizar auditoría, alertar por verbos de IAM sensibles, limitar PassRole y cambios en runtimes a pipelines controlados, y revisar trust policies de roles críticos como si fueran reglas de firewall. Si hoy no puedes responder con certeza a “qué roles cambiaron su trust policy esta semana y por quién”, estás a una credencial filtrada de repetir esta historia.
¿Te interesa la seguridad en Cloud?
Comparto análisis técnicos, laboratorios prácticos y experiencias reales sobre Cloud Security.