Hacking JWT Tokens: Client Side Token Decode

Shivam Bathla
Pentester Academy Blog
8 min readJun 30, 2020

--

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:

  1. Introduction to JSON Web Tokens
  2. JWT RFC

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: Client Side Token Decode

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

Retrieving the IP address of the host machine

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

Viewing the application

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

Launching Burp

The following window will appear:

Opening Burp

Click Next.

Finally, click Start Burp in the following window:

Opening Burp (contd.)

The following window will appear after BurpSuite has started:

Opening Burp (contd.)

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.

Configure browser to use Burp proxy

Select Manual Proxy Configuration and set the HTTP Proxy address to localhost and the port to 8080.

Configure browser to use Burp proxy (contd.)

Click OK.

Everything required to intercept the requests has been setup.

Step 4: Interacting with the Token API.

Click on Get Token button:

Interacting with the Token API

Check the intercepted request in BurpSuite.

Inspecting the intercepted request

Note: Make sure that Burp proxy is running in intercept mode.

Forward the request and return back to the browser.

Forward the above request to get the issued token

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:

Decode the issued token using the API

Check the corresponding request in BurpSuite.

Forward the intercepted request

Forward the request.

The request sends the supplied token to the target machine on port 8081

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.

Viewing the decoded token

The token is successfully decoded by the API.

Notice that the admin claim is set to “false”.

admin claim is false

Paste the obtained token in the input field in front of the Get Golden Ticket button.

Inspecting the above request

Forward the request.

Notice the token sent in the above 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.

No Golden Ticket for us!!

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 the library documentation

Check out the “API-Library: Token Decoding” section.

Viewing the token decoding info

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.

Viewing the “API Library: Internal Wiki” section

Scroll down this page.

Viewing the “API Library: Internal Wiki” section (contd.)

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.

Notice the Note: for the Decode Token point

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:

Decoding the previously issued token using https://jwt.io

Set the algorithm to HS256.

Set the algorithm to HS256 using https://jwt.io

HS256 Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ3aXRyYXAuY29tIiwiYWRtaW4iOiJmYWxzZSIsImV4cCI6MTU3NTM3OTkzMiwiaWF0IjoxNTc1MzY5MTMyfQ.V8ox_spsCUGIboXbclEOA2E9ltY8Gp0u9ffMO4snyAg

Click on Decode Token button again:

Decode the issued token (a valid one)
Forward the OPTIONS request

Forward the OPTIONS request.

Send this request to the Repeater

Send the above request to the Repeater.

Replace the token with the forged token (alg = HS256)

Replace the RS256 token with the HS256 token obtained from https://jwt.io and send the request.

Notice the signing key retrieved in the response

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.

Creating a valid HS256 token using the above obtained signing key

HS256 Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ3aXRyYXAuY29tIiwiYWRtaW4iOiJmYWxzZSIsImV4cCI6MTU3NTM3OTkzMiwiaWF0IjoxNTc1MzY5MTMyfQ.7uUdU2Nh0Ug0H-nyhAaAFCtPF0payBbn33PtZUwcTWQ

Note: For the following requests, turn off the Intercept mode.

Turn off the Intercept mode

Pass the HS256 token obtained above to get the Golden Ticket.

Paste the newly obtained HS256 token and use it to retrieve the Golden Ticket
Well the token got accepted but the Golden Ticket was not retrieved!!

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”.

Create the forged token (admin = true)

HS256 Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ3aXRyYXAuY29tIiwiYWRtaW4iOiJ0cnVlIiwiZXhwIjoxNTc1Mzc5OTMyLCJpYXQiOjE1NzUzNjkxMzJ9.EkR6M6IiBcOJfZC0mMK7boKLtml5h-yRgGgOSt1at8Y

Pass the above obtained HS256 token to get the Golden Ticket.

Retrieving the Golden Ticket using the forged token
Awesome!! We got 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:

  1. JWT RFC

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!

--

--