Prevención de la apropiación total de la nube mediante ataques SSRF
Esta es la historia de un atacante que obtuvo acceso a los buckets de Amazon S3 de una startup, a variables de entorno y a varios secretos internos de la API, todo a través de un simple formulario que envía un correo electrónico. Aunque se trata de una historia real, mantendré en secreto el nombre de la startup.

Cómo entraron
Todo comienza con una aplicación PHP que envía un correo electrónico. Para cargar algunas de las imágenes de lujo en el correo electrónico como archivos adjuntos, la aplicación necesita descargarlas. En PHP esto es fácil. Se utiliza la función file_get_contents y ahí es donde empieza la diversión.
Por supuesto, algunas de las entradas del usuario para este correo electrónico no estaban totalmente verificadas o codificadas en HTML, por lo que un usuario podía incluir una imagen como <img src=’evil.com’/>
. Ahora, en teoría, esto no es tan malo, pero tristemente esta función PHP es muy poderosa y puede hacer mucho más que cargar imágenes a través de Internet. También puede leer archivos locales y lo que es más importante: archivos a través de la red local en lugar de Internet.
En lugar de evil.com, el atacante introdujo una URL local especial. Puedes utilizar esta URL para obtener las credenciales IAM vinculadas al rol del servidor AWS EC2 que estás ejecutando con una simple solicitud GET.
<img src=’http://169.254.169.254/latest/meta-data/'>
El resultado fue que el atacante recibió un correo electrónico que incluía las credenciales IAM para el servidor EC2 en un archivo adjunto en el buzón. Esas claves dan al atacante la capacidad de hacerse pasar por ese servidor al hablar con varios servicios de AWS. A partir de ahí todo va cuesta abajo...
¿Por qué es esto posible?
El sistema que carga estas claves IAM se llama IMDSv1 y Amazon lanzó una nueva versión en 2019 llamada IMDSv2. Con IMDSv2, necesita enviar una solicitud PUT con un encabezado especial para obtener sus credenciales IAM. Eso significa que una simple función de carga de URL basada en GET como file_get_contents ya no puede causar tanto daño.
No está claro cuál será la adopción de IMDSv2 a partir de 2023, pero está claro que Amazon sigue tomando medidas para aumentar su adopción y estamos viendo que IMDSv1 todavía se utiliza en la naturaleza.
El compromiso de las claves IAM lleva a más compromisos: Los buckets S3 podían ser listados y sus contenidos leídos. Para empeorar las cosas, uno de los buckets S3 contenía una plantilla cloudformation, que contenía variables de entorno sensibles (por ejemplo, las claves API de Sendgrid).
¿Cómo defiendo mi infraestructura de nube contra esto?
Ahora bien, ¿qué se podría hacer para evitar esta pérdida total de datos? Sus desarrolladores podrían ser muy cuidadosos y tener cuidado de utilizar una allowlist para las URLs que pasan a file_get_contents. Incluso podrían verificar que el contenido que reciben es una imagen si están esperando una imagen. Sin embargo, la realidad es que este tipo de errores son difíciles de evitar como desarrollador.
Sería mucho mejor asegurarse de que su infraestructura tiene defensas adicionales contra estos ataques. Nuestra nueva integración con AWS dentro de Aikido security te alertará si tu nube no toma activamente alguna de las siguientes medidas. Cada una de estas medidas por sí sola habría detenido este ataque en particular, pero recomendamos implementarlas todas. Utilice nuestra cuenta de prueba gratuita para ver si su nube ya está defendida contra estas amenazas. Vea cómo Aikdido protege su aplicación contra vulnerabilidades aquí.
Pasos a seguir:
- Migre sus nodos EC2 IMDSv1 existentes para utilizar IMDSv2
- No almacene ningún secreto en el entorno de sus servidores web ni en las plantillas de formación en la nube. Utilice una herramienta como AWS Secrets Manager para cargar los secretos en tiempo de ejecución.
- Cuando asigne roles IAM a sus servidores EC2, asegúrese de que tienen condiciones adicionales, como restringirlos para que solo se puedan utilizar desde dentro de su red local de AWS (su VPC). El siguiente ejemplo permite a tu servidor leer desde S3, pero sólo si el servidor EC2 se comunica a través de un endpoint VPC específico. Eso sólo es posible desde dentro de su red, por lo que el atacante no habría sido capaz de llegar a los buckets de S3 desde su máquina local.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "rule-example",
"Effect": "Allow",
"Action": "s3:getObject",
"Resource": "arn:aws:s3:::bucketname/*",
"Condition": {
"StringEquals": {
"aws:SourceVpce": "vpce-1s0d54f8e1f5e4fe"
}
}
}
]
}
Acerca de "The Kill Chain
The Kill Chain es una serie de historias reales de atacantes que llegan a las joyas de la corona de las empresas de software encadenando múltiples vulnerabilidades. Escrito por Willem Delbare, aprovechando sus diez años de experiencia en la construcción y el apoyo a startups SaaS como CTO. Los relatos proceden directamente de la red de Willem y todos han sucedido realmente.