Hacking JWT Tokens: Client Side Token Decode
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 looking at another interesting way of hacking JWT Tokens by leveraging the bad design of the application that verifies the issued JWT Tokens on the client side!!!
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.
This lab environment consists of a target machine hosting a simple REST API. The API interacts with a JWT library and provides the features to issue and decoded JWT Tokens. The API flow is pretty simple to minimize any attack surface.
The issue is that the internal documentation containing the API-library interaction details went public by mistake. Interact with the API and explore how this mistake could be disastrous.
Objective: To get the HS256 signing key and the Golden Ticket!
Solution:
Step 1: Check the IP address of the machine.
Command: ifconfig
The IP address of the machine is “192.93.154.2”
Therefore, the Token API is running on port 5000 of the target machine having IP address 192.93.154.3.
Step 2: Viewing the application hosted on the target machine.
Open the following URL in firefox.
URL: http://192.93.154.3:5000
Step 3: Configuring the browser to use BurpSuite proxy and making BurpSuite intercept all the requests made to the API.
Launch BurpSuite.
Select Web Application Analysis > burpsuite
The following window will appear:
Click Next.
Finally, click Start Burp in the following window:
The following window will appear after BurpSuite has started:
Configure the browser to use the Burp proxy listener as its HTTP Proxy server.
Open the browser preference settings and search for network proxy settings.
Select Manual Proxy Configuration and set the HTTP Proxy address to localhost and the port to 8080.
Click OK.
Everything required to intercept the requests has been setup.
Step 4: Interacting with the Token API.
Click on Get Token button:
Check the intercepted request in BurpSuite.
Note: Make sure that Burp proxy is running in intercept mode.
Forward the request and return back to the browser.
Notice that a JWT Token has been issued.
Issued JWT Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ3aXRyYXAuY29tIiwiYWRtaW4iOiJmYWxzZSIsImV4cCI6MTU3NTM3OTkzMiwiaWF0IjoxNTc1MzY5MTMyfQ.XewkpUiZNW8cJzM6HAABhFn2gN1MfYXMaB-MMWfoqJnjeo6YETAzEK8tyPcn4ya0m2F1sXqrmKXbthMDeCKPZZ-HqgCMdMVY6iLXV9mgmyxaRZ8nGq0FyAV94GFB7GWvbRlKlN4jh0yZqstCMnKOuYvFiVmpjrKRj6z0ZKG8DJUdrqvSbwcpBXgj6Zr9Ez3y5my6HPAqd-Eycdx4X2JdRyo3vPGzVunmlMB_eXUYBFZ6ST9cKjKe1YAqX78-Q3q8WahNi2uFs1GqZDru833NtrUrayGdtdUcgzVyzne3hn2UANkCkShuS4zPhwIv0MVDufVBdhgG7GpMPjVbE9EUcQ
Decode the issued JWT Token using using the provided Token API:
Paste the issued JWT Token in the input field in front of the Decode Token button:
Check the corresponding request in BurpSuite.
Forward the request.
Notice that the above request sends the supplied token to a service running on the target machine on port 8081.
Forward this request as well.
The token is successfully decoded by the API.
Notice that the admin claim is set to “false”.
Paste the obtained token in the input field in front of the Get Golden Ticket button.
Forward the request.
Notice that the above request sends the supplied token to a service running on the target machine on port 8081.
Forward this request as well.
The response indicates that the Golden Ticket is only for the admin user.
Step 5: Check the Library documentation.
Open the following URL in firefox:
Documentation URL: http://192.93.154.3
Check out the “API-Library: Token Decoding” section.
Notice that the information on this page reveals that once the decode token button is clicked the verification key is fetched from the server.
The library supports 2 algorithms: HS256 and RS256.
Check out the “API-Library: Internal Wiki” section.
Scroll down this page.
The above information reflects that if an HS256 token is sent to the API, it would send back the HS256 symmetric signing key on the client side for token verification.
In the example above, a curl request is shown containing the HS256 token to retrieve the symmetric key.
Request: curl -X POST -H “Content-Type: application/json” -d ‘{“token”: “YOUR_HS256_JWT_TOKEN”}’ http://IP:PORT/verificationkey
The vulnerability here is that the library is not performing the token verification on the server side but sending the verification key on the client side.
Therefore, if the user supplies an HS256 token while clicking on the Decode Token button, that user would get the HS256 signing key in response.
This means that the user can then create the forge a token for admin user and get the Golden Ticket from the server.
Step 6: Sending an HS256 token to the server to retrieve the corresponding signing key.
Decode the previously issued RS256 token using https://jwt.io:
Set the algorithm to HS256.
HS256 Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ3aXRyYXAuY29tIiwiYWRtaW4iOiJmYWxzZSIsImV4cCI6MTU3NTM3OTkzMiwiaWF0IjoxNTc1MzY5MTMyfQ.V8ox_spsCUGIboXbclEOA2E9ltY8Gp0u9ffMO4snyAg
Click on Decode Token button again:
Forward the OPTIONS request.
Send the above request to the Repeater.
Replace the RS256 token with the HS256 token obtained from https://jwt.io and send the request.
HS256 Signing Key: 3ddd07f727e342533453758d3c8181e703d2
Step 7: Creating a valid HS256 token.
Paste the obtained signing key on https://jwt.io in the decoded section and get a valid JWT Token that would be accepted by the server.
HS256 Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ3aXRyYXAuY29tIiwiYWRtaW4iOiJmYWxzZSIsImV4cCI6MTU3NTM3OTkzMiwiaWF0IjoxNTc1MzY5MTMyfQ.7uUdU2Nh0Ug0H-nyhAaAFCtPF0payBbn33PtZUwcTWQ
Note: For the following requests, turn off the Intercept mode.
Pass the HS256 token obtained above to get the Golden Ticket.
The response is that the Golden Ticket is for admin user.
But that also indicates that this forged token was processed by the token library, indicating that the token is valid.
Step 8: Creating a valid token for admin user and retrieving the Golden Ticket.
Visit https://jwt.io and paste the HS256 token from the previous step and set the value for admin claim to “true”.
HS256 Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ3aXRyYXAuY29tIiwiYWRtaW4iOiJ0cnVlIiwiZXhwIjoxNTc1Mzc5OTMyLCJpYXQiOjE1NzUzNjkxMzJ9.EkR6M6IiBcOJfZC0mMK7boKLtml5h-yRgGgOSt1at8Y
Pass the above obtained HS256 token to get the Golden Ticket.
Golden Ticket: This_Is_The_Golden_Ticket_7395aaad3a1524e459978147
Token Decoding on client side should be done only for tokens using public keys for verification!! For symmetric keys this scheme is inherently flawed as seen above.
I hope you guys enjoyed this post. If you are interested in exploring more ways to hack JWT Tokens, make sure to check out my other posts in the Hacking JWT Tokens series.
Stay Safe and Happy Hacking!
References:
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!