> For the complete documentation index, see [llms.txt](https://x7331.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://x7331.gitbook.io/notes/postswigger/jwt-attacks/attacks/algorithm-confusion.md).

# Algorithm Confusion

> **Algorithm Confusion Attack**: using an unexpected algorithm to sign the token.

## Symmetric vs Asymmetric Algorithms

* **Symmetric algorithms** use the **same key** to both sign and verify the token, whereas **asymmetric algorithms** use a **key pair**, i.e., a private key to sign the token and a public key to verify it.&#x20;
* Vulnerabilities arise due to flawed implementation of JWT libraries.

## Process

1. Obtain the server's public key.&#x20;
   * This might be done through conventional endpoints such as `/jwks.json` or `/well-known/jwks.json`.
2. Convert it to a suitable format.&#x20;
   * The exposed keys (JWK format) must be identical with the server's keys.
3. Create a malicious JWT with a modified payload and the `alg` set to `HS256`.
4. Sign the token with `HS256` using the public key as the secret.

### LAB: Algorithm Confusion

> **Goal**: Obtain the key via a standard endpoint, use it to sign a modified session token to access `/admin` and delete `carlos`. The server stores the key in a `X.509` PEM file.

<figure><img src="https://3960676229-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmjLkek16kB60c2WFd5lf%2Fuploads%2FJlzh9Bu26uCvaLt55XCO%2Falgorithm_confusion_attack.png?alt=media&amp;token=941a320b-5189-45e8-b70f-4dc53c63f979" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3960676229-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmjLkek16kB60c2WFd5lf%2Fuploads%2FurBjI1WIUQzNZB9KdmRW%2Falgorithm_confusion_attack_2.png?alt=media&amp;token=eaa03a98-8197-4e98-a1e2-edfdd8c5da34" alt=""><figcaption></figcaption></figure>

## Deriving Public Keys from Existing Tokens

If no exposed public keys are available, we can derive one from a pair of existing JWTs using [`jwt_forgery.py`](https://github.com/silentsignal/rsa_sign2n).

```bash
# Simplified version of the above tool
docker run --rm -it portswigger/sig2n <token1> <token2>
```

The above command is using the provided token to calculate one or more potential `n` values. For each potential value, the script outputs:

1. A base64-encoded PEM key in both `X.509` and `PKCS1` format.
2. A forged JWT signed using each of these keys.

To identify the correct key we need to try both and see which is accepted by the server.

### LAB: Algorithm Confusion With Forged Key

> **Goal**: Obtain the key via a standard endpoint, use it to sign a modified session token to access `/admin` and delete `carlos`. The server stores the key in a `X.509` PEM file.

<figure><img src="https://3960676229-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmjLkek16kB60c2WFd5lf%2Fuploads%2FPlZamLNDPOImyABm2k6V%2Falgorithm_confusion_attack_no_exposed_key.png?alt=media&amp;token=7aff2f7c-82af-4212-8b19-b2876c99a116" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

```bash
$ docker run --rm -it portswigger/sig2n eyJ...<SNIP>jMQ  eyJ...<SNIP>...dQb
```

{% endcode %}

<figure><img src="https://3960676229-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmjLkek16kB60c2WFd5lf%2Fuploads%2FO8GQcuOZaO8HTZIevBiQ%2Falgorithm_confusion_attack_no_exposed_key_2.png?alt=media&amp;token=5696e03f-6bb9-4f6d-972a-9039cf595a81" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3960676229-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmjLkek16kB60c2WFd5lf%2Fuploads%2FfG4WAfs9lCOsuw74vPCG%2Falgorithm_confusion_attack_no_exposed_key_3.png?alt=media&amp;token=a6e244bf-9ca5-4003-a93d-1b42bc8ce51a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3960676229-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmjLkek16kB60c2WFd5lf%2Fuploads%2FnGX0SeCH2BhJ6ZyVgboq%2Falgorithm_confusion_attack_no_exposed_key_4.png?alt=media&amp;token=80ce0e0f-9123-4fe8-a221-b20165b6c621" alt=""><figcaption></figcaption></figure>
