Cloud Security
AWS IAM
escalada de privilegios
cloud pentesting

Escalada de Privilegios AWS IAM: Rutas de Ataque

Rutas de escalada de privilegios en AWS IAM: abuso de iam:PassRole, versionado de políticas, cadenas sts:AssumeRole y su detección con CloudTrail.

Secra6 de julio de 202610 min de lectura

La escalada de privilegios en AWS IAM es una de las fases más rentables de cualquier auditoría ofensiva en la nube. Un atacante rara vez aterriza directamente en una cuenta con permisos de administrador: lo habitual es comprometer una identidad limitada (una clave de acceso filtrada en un repositorio, un rol de instancia EC2 alcanzado vía SSRF, un usuario de servicio con permisos mal acotados) y desde ahí buscar la ruta que lleva a AdministratorAccess. Este artículo mapea las rutas de escalada de privilegios en AWS IAM más explotadas, con el comando ofensivo que las materializa y, para cada una, la corrección defensiva que las corta de raíz.

El enfoque es deliberadamente ofensivo. Si buscas la base conceptual de identidades y permisos, tenemos una guía dedicada sobre qué es IAM y la gestión de identidades y accesos. Aquí asumimos ese contexto y vamos directos a cómo se rompe.

Por qué IAM es el campo de batalla del cloud ofensivo

En un datacenter clásico la escalada de privilegios se jugaba en el sistema operativo: kernel exploits, servicios SUID, credenciales en memoria. En AWS el plano de control se ha desplazado a IAM. El permiso, no el binario, es la primitiva que un atacante encadena. Una política mal escrita convierte a un usuario de solo lectura en administrador sin tocar un solo host.

La causa raíz casi siempre es la misma: permisos de gestión de IAM concedidos a identidades que no deberían tenerlos. Acciones como iam:CreatePolicyVersion, iam:AttachUserPolicy o iam:PassRole parecen inocuas en una revisión superficial, pero cada una habilita una ruta directa hacia el control total de la cuenta. Rhino Security Labs documentó más de veinte métodos distintos de escalada IAM, y la mayoría siguen siendo válidos hoy porque dependen del diseño de permisos, no de un bug del proveedor.

Enumeración de permisos: el paso previo

Ninguna escalada empieza a ciegas. Lo primero es enumerar qué puede hacer la identidad comprometida.

La forma sigilosa es leer la política directamente cuando hay permisos para ello:

aws iam get-user
aws iam list-attached-user-policies --user-name victima
aws iam list-user-policies --user-name victima
aws sts get-caller-identity

Cuando no hay visibilidad sobre las propias políticas, la herramienta de referencia es enumerate-iam (Andrés Riancho, NCC Group), que fuerza por fuerza bruta llamadas de solo lectura para inferir qué acciones están permitidas sin depender de iam:Get*. En una operación más completa, el framework Pacu de Rhino Security Labs automatiza el ciclo entero: el módulo iam__enum_permissions construye el mapa de permisos efectivos y iam__privesc_scan prueba automáticamente las rutas de escalada conocidas contra ese mapa. Un flujo típico en Pacu:

run iam__enum_permissions
run iam__privesc_scan

El escaneo devuelve las rutas viables ordenadas por facilidad de explotación. A partir de ahí, el trabajo es manual y quirúrgico.

Rutas de escalada de privilegios en AWS IAM

iam:PassRole y el pivote a servicios de cómputo

iam:PassRole es probablemente el permiso más peligroso de IAM cuando se concede sin condiciones. No hace nada por sí solo: autoriza a entregar un rol existente a un servicio de AWS. El problema es que muchos servicios de cómputo ejecutan código bajo el rol que les pasas.

Si la identidad tiene iam:PassRole sobre un rol privilegiado más lambda:CreateFunction y lambda:InvokeFunction, el atacante crea una función Lambda que asume ese rol y ejecuta comandos con sus permisos:

aws lambda create-function --function-name pwn \
  --runtime python3.12 --role arn:aws:iam::ACCT:role/rol-privilegiado \
  --handler pwn.handler --zip-file fileb://pwn.zip
aws lambda invoke --function-name pwn out.json

La misma primitiva funciona con ec2:RunInstances (lanzando una instancia con un instance profile privilegiado y leyendo sus credenciales desde el IMDS), con glue:CreateDevEndpoint, con sagemaker:CreateNotebookInstance, con datapipeline o con cloudformation. El vector serverless lo desarrollamos a fondo en la guía de pentesting serverless en AWS Lambda.

Corrección defensiva: nunca concedas iam:PassRole con Resource: "*". Restríngelo al ARN exacto del rol que la carga de trabajo necesita y añade la condición iam:PassedToService para atarlo a un único servicio (por ejemplo lambda.amazonaws.com). Combínalo con SCPs a nivel de organización que denieguen iam:PassRole sobre roles administrativos.

Versionado de políticas: CreatePolicyVersion y SetDefaultPolicyVersion

Las políticas gestionadas de IAM conservan hasta cinco versiones. Si la identidad tiene iam:CreatePolicyVersion sobre una política que está asociada a ella, puede crear una versión nueva con permisos de administrador y marcarla como predeterminada en un solo comando:

aws iam create-policy-version --policy-arn arn:aws:iam::ACCT:policy/mi-politica \
  --policy-document file://admin.json --set-as-default

Donde admin.json concede Action: "*" sobre Resource: "*". La escalada es instantánea.

Una variante más silenciosa aprovecha iam:SetDefaultPolicyVersion: si ya existe una versión antigua y más permisiva en el historial de la política, basta con volver a ella (rollback) sin crear nada nuevo, lo que deja menos rastro:

aws iam set-default-policy-version --policy-arn arn:aws:iam::ACCT:policy/mi-politica --version-id v1

Corrección defensiva: trata iam:CreatePolicyVersion y iam:SetDefaultPolicyVersion como permisos administrativos. Bloquéalos con una SCP salvo para un rol de administración de identidades muy acotado. Aplica permission boundaries a las identidades operativas: aunque consigan reescribir su política, el boundary limita los permisos efectivos al mínimo definido.

AttachUserPolicy y PutUserPolicy: autoescalada directa

Si la identidad puede modificar sus propias políticas, la escalada es trivial. Con iam:AttachUserPolicy se asocia la política gestionada AdministratorAccess al propio usuario:

aws iam attach-user-policy --user-name victima \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

Con iam:PutUserPolicy se inyecta una política inline con permisos totales sin depender de ninguna política gestionada existente. Las variantes de grupo (iam:AttachGroupPolicy, iam:PutGroupPolicy, iam:AddUserToGroup) y de rol (iam:AttachRolePolicy, iam:PutRolePolicy) logran lo mismo por caminos laterales. Otras autoescaladas clásicas: iam:CreateAccessKey sobre un usuario privilegiado, o iam:CreateLoginProfile / iam:UpdateLoginProfile para fijar una contraseña de consola a una identidad con más permisos.

Corrección defensiva: ninguna identidad operativa debería poder editar políticas de IAM. Estos son permisos de tier 0. Sepáralos en un rol de administración dedicado, protégelo con MFA y permission boundaries, y activa IAM Access Analyzer en modo unused access para detectar quién acumula permisos de gestión que nunca usa.

Cadenas sts:AssumeRole y confused deputy

sts:AssumeRole es legítimo y omnipresente, pero se vuelve una ruta de escalada cuando la política de confianza (trust policy) de un rol privilegiado es demasiado abierta. Un Principal con comodín, una condición ausente o un ExternalId que no se valida permiten que una identidad de bajo privilegio asuma un rol de alto privilegio:

aws sts assume-role --role-arn arn:aws:iam::ACCT:role/rol-admin \
  --role-session-name esc

El role chaining encadena varios AssumeRole sucesivos para saltar entre cuentas de la organización hasta alcanzar la cuenta de gestión. Y si la identidad posee iam:UpdateAssumeRolePolicy sobre un rol privilegiado, puede reescribir su trust policy para autorizarse a sí misma y luego asumirlo. Estas cadenas son un objetivo central en un pentesting cloud sobre AWS, Azure y GCP, donde el valor está en encadenar fallos menores hasta un compromiso crítico.

Corrección defensiva: audita todas las trust policies buscando Principal con comodines o cuentas externas sin ExternalId. Restringe sts:AssumeRole con condiciones (aws:PrincipalOrgID, sts:ExternalId, MFA obligatorio) y trata iam:UpdateAssumeRolePolicy como permiso de tier 0.

Reproducción en laboratorio con CloudGoat

Ninguna de estas rutas debería probarse por primera vez en producción. CloudGoat, el entorno vulnerable-por-diseño de Rhino Security Labs, despliega escenarios reproducibles con Terraform. Dos de ellos son la referencia para practicar escalada IAM:

  • iam_privesc_by_rollback: reproduce la escalada vía iam:SetDefaultPolicyVersion volviendo a una versión antigua y permisiva de una política.
  • iam_privesc_by_attachment: reproduce el abuso de un rol de instancia EC2 al que el atacante adjunta la política de administrador aprovechando iam:PassRole y el instance profile.

El ciclo de práctica es directo:

./cloudgoat.py create iam_privesc_by_rollback

CloudGoat entrega las credenciales de partida y el objetivo. Practicar ambos escenarios con Pacu y la CLI enseña a reconocer los mismos patrones en un entorno real y, sobre todo, qué eventos genera cada acción en CloudTrail.

Defensa: cerrar cada ruta de forma sistemática

Las correcciones puntuales de cada apartado se consolidan en cuatro capas que, combinadas, cierran la superficie de escalada:

  1. Mínimo privilegio real. Ninguna identidad de carga de trabajo debe tener permisos de gestión de IAM. Revisa iam:*, PassRole sin condición y comodines en Action o Resource. Es el mismo criterio que aplicamos al catalogar los errores de configuración cloud más peligrosos en AWS y Azure.
  2. Permission boundaries. Actúan como techo infranqueable: aunque una identidad logre adjuntarse AdministratorAccess, el boundary limita los permisos efectivos. Son la contramedida específica contra la autoescalada.
  3. Service Control Policies (SCPs). A nivel de AWS Organizations, deniegan globalmente acciones peligrosas (iam:CreatePolicyVersion, iam:SetDefaultPolicyVersion, iam:UpdateAssumeRolePolicy) salvo para roles de administración explícitos. Ninguna política de cuenta puede sobrepasarlas.
  4. Detección en CloudTrail. Cada ruta deja un evento identificable: CreatePolicyVersion, SetDefaultPolicyVersion, AttachUserPolicy, PutUserPolicy, CreateAccessKey, UpdateAssumeRolePolicy y AssumeRole anómalos. Configura alertas sobre estos eventos (vía EventBridge, GuardDuty o consultas de CloudTrail Lake y Athena) y correlaciona con el origen (una IP inusual asumiendo un rol admin es una señal de alta fidelidad).

Esta postura defensiva se refuerza midiendo continuamente la configuración con las herramientas que describimos en qué es CSPM y la gestión de postura de seguridad cloud, y extendiendo el mismo principio de permisos efectivos al plano SaaS con SSPM. La validación definitiva, sin embargo, es ofensiva: solo un ejercicio real confirma qué rutas son explotables de verdad. En Secra lo verificamos con nuestro servicio de auditoría cloud.

Preguntas frecuentes

¿Cuál es el permiso IAM más peligroso para la escalada de privilegios?

iam:PassRole sin condiciones, combinado con permisos de creación en un servicio de cómputo (lambda:CreateFunction, ec2:RunInstances, glue:CreateDevEndpoint). Permite ejecutar código bajo la identidad de un rol privilegiado sin tocar sus políticas. Le siguen de cerca iam:CreatePolicyVersion y iam:AttachUserPolicy, que habilitan autoescalada directa a administrador.

¿Sirve un permission boundary para frenar la escalada IAM?

Sí, es una de las contramedidas más efectivas. El permission boundary define el máximo de permisos efectivos de una identidad. Aunque un atacante consiga adjuntarse la política AdministratorAccess, el boundary limita lo que realmente puede hacer al conjunto definido en él. Es la defensa específica frente a AttachUserPolicy, PutUserPolicy y CreatePolicyVersion.

¿Cómo detecto un intento de escalada de privilegios en CloudTrail?

Configura alertas sobre eventos de gestión de IAM: CreatePolicyVersion, SetDefaultPolicyVersion, AttachUserPolicy, PutUserPolicy, UpdateAssumeRolePolicy, CreateAccessKey y AssumeRole desde orígenes inusuales. GuardDuty genera hallazgos de tipo anómalo sobre estas acciones, y CloudTrail Lake o Athena permiten cazarlas de forma retroactiva.

¿Qué herramientas se usan para probar rutas de escalada IAM?

Para enumeración, enumerate-iam infiere permisos sin depender de iam:Get*. Pacu automatiza el mapa de permisos (iam__enum_permissions) y el escaneo de rutas (iam__privesc_scan). Para reproducir escenarios en un laboratorio seguro, CloudGoat despliega entornos vulnerables con Terraform, como iam_privesc_by_rollback y iam_privesc_by_attachment.

¿Las SCPs sustituyen al mínimo privilegio?

No, se complementan. Las SCPs son un límite máximo a nivel de organización que ninguna cuenta puede sobrepasar, ideales para bloquear globalmente acciones peligrosas. Pero no conceden permisos ni sustituyen políticas bien diseñadas. La defensa robusta combina SCPs (techo organizativo), permission boundaries (techo por identidad) y políticas de mínimo privilegio (permisos concretos).

Conclusión

La escalada de privilegios en AWS IAM no depende de exploits sofisticados, sino de permisos de gestión concedidos a quien no debería tenerlos. Las rutas son conocidas y reproducibles: abuso de iam:PassRole, versionado de políticas, autoescalada con AttachUserPolicy o PutUserPolicy, y cadenas sts:AssumeRole. La buena noticia es que cada una tiene una corrección concreta, y las cuatro capas defensivas (mínimo privilegio, permission boundaries, SCPs y detección en CloudTrail) las cierran de forma sistemática. Si gestionas cargas de trabajo en AWS y no has validado tu superficie de escalada IAM con un ejercicio ofensivo, contacta con nuestro equipo para una evaluación.

Sobre el autor

Equipo de Secra Solutions

Ethical hackers certificados OSCP, OSEP, OSWE, CRTO, CRTL y CARTE, con más de 7 años de experiencia en ciberseguridad ofensiva. Autores de los CVE-2025-40652 y CVE-2023-3512.

Compartir artículo