githubEdit

JSON Web Tokens JWT Penetration Testing

Tools: Burpsuite, cURL, https://jwt.io/ (JWT Decoder and editor), Cyberchef https://gchq.github.io/CyberChef/ (Encode/Decode values), https://github.com/ticarpi/jwt_tool (Automation tool to check for vulnerable JWT Tokens)

Attacks:

1) Sensitive Information Disclosure

Authenticate with a user and grab the JWT token from that user

curl -H 'Content-Type: application/json' -X POST -d '{ "username" : "user", "password" : "password1" }' http://10.10.190.243/api/v1.0/example1 

Go to jwt.io to decode the token and check the values inside the claim portion of the token. We may find sensitive information like internal resources, etc.

2) Signature is not verified

Grab the JWT token

curl -H 'Content-Type: application/json' -X POST -d '{ "username" : "user", "password" : "password1" }' http://10.10.190.243/api/v1.0/example1 

Authenticate with the JWT token

curl -H 'Authorization: Bearer JWT_TOKEN' http://10.10.190.243/api/v1.0/example2?username=user 

Go to jwt.io and try to verify the user WITHOUT the signature by removing the signature part leaving ONLY the dot (.).

Try to authenticate with the SIGNATURELESS token again to check if you can verify the user even without the signature.

Modify any values we may find in the token. Example:

Change the admin value from 0 to 1, then verify as admin with the newly modified JWT token.

3) Signature algorithm downgrade to NONE

Grab the JWT Token

Authenticate with the JWT Token

Go to jwt.io to modify the values inside the claim portion of the token: Admin from 0 to 1 for example.

If the response of the server contains: "Signature verification failed" we can go for the downgrade attack to None algorithm.

Go to cyberchef, then take the HEADER part of the JWT token and use the JWT decode recipe to get the plain text of the JWT header.

Grab the plain text JWT header, change the Alg to None and encode it with base64.

After this, put the base64 encoded header we just made at the BEGINNING of our modified JWT token to replace the previous header with the None algorithm. REMOVE THE EQUAL SIGN FROM THE BASE64 HEADER TO NOT GET ANY COMPLAINTS FROM THE SERVER RESPONSE!

4) Weak Symmetric Secrets

Grab JWT Token

Save the retrieved JWT in a text file

Download a wordlist for JWT secrets

Use hashcat to crack the secret of the JWT token so that we can forge our own JWT token to gain access

Then go to jwt.io and do the following:

Add the secret we just cracked down to the signature part where it tells us to enter our secret we just discovered.

Then, modify any values we may find to gain admin access. Example: admin from 0 to 1.

Then use this newly forged JWT token to authenticate:

5) Signature Algorithm Confusion

Grab the JWT Token with the public key in this example

Go to jwt.io to make the changes or use the script provided from THM that we are going to use. Script will be located in scripts folder in here.

Add the public key to the script and make the modifications: admin from 0 to 1 for example.

Before running the script, edit the file /usr/lib/python3/dist-packages/jwt/algorithms.py and comment out the specific code snippet:

Run the script to generate our forged JWT token

Gain access with our modified JWT token

6) JWT Token Lifetimes

If a token does not have an 'exp' value set inside its claim portion of the token, this means that the token NEVER EXPIRES!

Also, check for the 'exp' value of a JWT if it is too short or long to verify it's lifespan.

Last updated