JWT Hacking
Introduction
JSON Web Token (JWT) is a widely used standard for securely exchanging information between parties, commonly applied in authorization processes. JWT is compact, readable, and digitally signed using a private or public key pair by the Identity Provider (IdP), allowing the integrity and authenticity of the data to be verified by other parties involved.
JWT serves primarily to ensure data authenticity rather than conceal data, as it is signed and encoded but not encrypted. It operates as a stateless, client-side authentication mechanism that relieves the server of storing session data.
JWT Structure
A JWT consists of three elements:
Header: Specifies the token type and signing algorithm. Typical algorithms include HMAC, SHA256, RSA, HS256, and RS256.
Payload: Contains user-related information such as user ID, username, role, and custom claims.
Signature: The key component of JWT, generated by encoding the header and payload with Base64url Encoding and concatenating them with a period (.). The Identity Provider uses a private key to create this signature, preventing unauthorized token tampering.
Format:
JWT can be generated using symmetric or asymmetric encryption:
Symmetric Encryption: Utilizes a single key for both creation and verification. The HS256 algorithm is commonly used.
Asymmetric Encryption: Requires a public key for verification and a private key for signing, with RS256 as the most frequent algorithm.
Key Components in JWT Header
JWT headers can include several optional parameters that may pose security risks if improperly handled:
Key ID (kid): Identifies a specific key in the filesystem or database for signature validation. If injectable, an attacker could reference a known file.
jku: Specifies a URL that refers to a set of keys for token validation, which attackers could manipulate if improperly controlled.
jwk: Allows embedding the key directly within the token, potentially enabling an attacker to introduce malicious keys.
x5u and x5c: Provide public key certificates or certificate chains within the token, with x5u as a URI and x5c embedding data directly.
x5t: Contains a Base64url-encoded SHA-256 thumbprint of the X.509 certificate, analogous to the key identifier or kid claim.
Key Claims in Payload Section
Several claims in the payload are integral to JWT’s security:
jti: Prevents replay attacks by adding a unique identifier.
iss: Identifies the token issuer.
iat: Specifies the token issuance time.
nbf: Indicates the time before which the JWT is invalid.
exp: Sets the token’s expiration time.
aud: Identifies the intended audience.
Workflow
A typical JWT authentication workflow includes the following steps:
The user authenticates with credentials or a third-party identity provider like Google or Facebook.
The authentication server validates the credentials and issues a JWT, signed using either a secret or a private key.
The client passes the JWT in the HTTP Authorization header to access protected resources.
The resource server verifies the token’s authenticity using the shared secret or public key.
Tools:
GitHub — ticarpi/jwt_tool: A toolkit for testing, tweaking and cracking JSON Web Tokens
GitHub — mazen160/jwt-pwn: Security Testing Scripts for JWT
GitHub — brendan-rius/c-jwt-cracker: JWT brute force cracker written in C
GitHub — jmaxxz/jwtbrute: Brute forcing jwt tokens signed with HS256 since 2014
GitHub — Sjord/jwtcrack: Crack the shared secret of a HS256-signed JWT
Attacking JWT
Finding JWT Tokens:
JWT tokens can be discovered by searching for them in the proxy history using regular expressions.
Common regular expressions to find JWT tokens:
Identify a Test Page:
Locate a request to a page that utilizes JWT tokens and provides clear responses depending on token validity.
A profile page is a good candidate to start with.
Verify Token Validity:
Send the request to the repeater and check if the same token works again. If not, the token might have expired.
Once confirmed, you can proceed with testing various attack methods.
Check for Sensitive Data in the JWT:
Turn on intercept in Burp Suite and log in to the web application.
Forward the request until you get the JWT token.
Switch to the JSON Web Token Tab.
Inspect the payload section for any sensitive information, such as user details.
If sensitive information is found in the payload, it’s a security concern as JWT tokens are often not encrypted, and the information could be easily decoded.
Bypassing JWT Using the “None” Algorithm:
Turn on intercept in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
Switch to the JSON Web Token Tab or JOSEPH (which also supports bypass).
Modify the
alg
value from its current algorithm (e.g., RS256) tonone
:
Remove the signature or set it to empty:
Forward the request to complete the attack.
Using JWT_Tool for JWT Bypass:
Turn on intercept in Burp Suite and log in to the web application.
Forward the request to capture the JWT token.
Execute the following command to generate bypass payloads, replacing
<JWT>
with the captured JWT token:
Test different payloads generated by the tool by inserting them into the request.
If one of the payloads works, use that token to proceed.
Change Algorithm from RS256 to HS256:
Turn on intercept in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
Get the Public key from the application (e.g.,
pubkey.pem
file) using the following commands:
or
Use the following command to generate a JWT token:
Use the generated token in the request and try changing the payload.
Forward the request to complete the attack.
This will work when the web app supports both algorithms.
Signature Not Being Checked:
Turn on intercept in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
Switch to the JSON Web Token Tab or JOSEPH.
Modify the payload section and remove the signature completely, or change some characters in the signature.
Forward the request to complete the attack.
Crack the Secret Key:
Turn on intercept in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
If the JWT-Heartbreaker Plugin is installed, weak secret keys will be shown directly.
Or you can Copy the JWT token and store it in a text file, then use Hashcat to crack the secret key:
You can also use JWT_Tool to crack the secret key:
Use the cracked secret key to forge a new JWT token and forward the request.
Attacks Using kid
in JWT Token
kid
in JWT TokenTurn on intercept in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
If there is a
kid
in the header section of the JWT token, forge a new JWT token using JWT_Tool:
Alternatively, use the content of any file in the web root, such as CSS or JS, to validate the signature:
Manipulate the payload section and use the generated token in the request.
Forward the request to complete the attack.
SQL Injection via kid
Turn on intercept in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
Switch to the JSON Web Token Plugin tab and manipulate the
kid
field with an SQLi payload:
Forward the request and escalate the SQLi further.
Command Injection via kid
Turn on intercept in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
Switch to the JSON Web Token Plugin tab and manipulate the
kid
field with a command injection payload:
Use the forged JWT token in the request.
Check if you can connect to the server on port 1337 or use a reverse shell payload to verify if you get a connection back.
Done!
Forged Header Parameter
JSON Set URL (jku):
Turn Intercept on in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
Decode the JWT token and check if it contains the
jku
attribute in the Header section.Generate your Public and Private Key pair using the following commands:
This will generate
publickey.crt
(Public Key) andpkcs8.key
(Private Key).Use jwt.io and paste the public key (publickey.crt) and the private key (attacker.key) in their respective places in the “Decoded” section.
Host the generated certificate locally and modify the
jku
header parameter accordingly.Retrieve the
jwks.json
file from the URL present in thejku
header claim:
Create a Python script getPublicParams.py:
Run the Python script:
Update the values of
n
ande
in the localjwks.json
.Host the JWK Set JSON file using repl.it or any server.
Manipulate the payload section and copy the generated JWT token from jwt.io.
Replace the JWT token in your request and forward. Done!
x5u Claim Misuse:
Note: The algorithm used for signing the token is “RS256”.
The token uses the x5u
header parameter, which contains the location of the X.509 certificate to be used for token verification.
Turn Intercept on in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
Decode the JWT token and check if it contains the
x5u
attribute in the Header section.Create a self-signed certificate:
Extract the public key from the generated certificate:
Use jwt.io and paste the public key (publicKey.pem) and the private key (attacker.key) in their respective places in the “Decoded” section.
Set
x5u: http://192.87.15.2:8080/attacker.crt
. You can use repl.it to host.Done! Use the forged JWT token in the request.
x5c Claim Misuse:
Note: The algorithm used for signing the token is “RS256”.
The token uses the x5c
header parameter, which contains the X.509 certificate to be used for token verification. The token has various fields: n
, e
, x5c
, x5t
, kid
. Also, the kid
value is equal to the x5t
value.
Turn Intercept on in Burp Suite and log in to the web application.
Forward the request until you capture the JWT token.
Decode the JWT token and check if it contains the
x5c
attribute in the Header section.Note: jwt.io automatically extracts the X.509 certificate and places it in the “Verify Signature” sub-section in the “Decoded” section.
Create a self-signed certificate:
Extract RSA public key parameters (
n
ande
) from the generated certificate:
Convert modulus (
n
) to base64-encoded hexadecimal strings:
Convert exponent (
e
) to base64-encoded hexadecimal strings:
Find the new
x5c
value:
Find the new
x5t
value:
Note: The
kid
parameter would also get the same value as thex5t
parameter.Create a forged token using all the parameters calculated in the previous steps.
Visit jwt.io and paste the token retrieved in Step 3 in the “Encoded” section.
Paste the X.509 certificate (attacker.crt) and the private key (attacker.key) in their respective places in the “Decoded” section.
Manipulate the Payload section and copy the forged token.
Replace the forged token in the request and forward. Done!
1. Key Database Mismanagement
In this attack, the vulnerability lies in poor management of JWT public keys, allowing attackers to register their own keys. By adding a public key to the target’s keystore, attackers can then forge tokens with admin privileges using their private key. This enables unauthorized access to restricted resources, like an admin panel or other high-privilege endpoints.
Start by locating the target’s IP and active services to identify potential endpoints for JWT handling:
This reveals that a Python-based HTTP service is running on port 8080, which might be hosting the vulnerable API.
Use
curl
to interact with available endpoints, like/issue
for token issuance or/register
for key registration.
The response should provide a JWT token, likely for a non-admin user.
Decode the token to inspect claims such as
"iss"
,"exp"
, and"admin"
. Noting"admin": "false"
indicates that the current token lacks admin rights, which sets the goal to escalate privileges.Sample decoded payload:
Here, we know the token is signed using
RS256
(an asymmetric signing algorithm), meaning it requires the private key of the issuer (witrap.com
) for signing and a corresponding public key for verification.
The critical vulnerability lies in the key management system:
The public keys used to verify the JWTs are stored in a database or file system that is accessible or modifiable by the attacker.
The system may allow public key registration. If accessible, attackers can register their public key, which the server will later use for JWT verification. This opens the door to signing tokens with a private key and gaining admin access.
If the public key management API allows users to register keys, this is where the exploitation occurs:
Using
openssl
, create a key pair for signing and verification:
Convert the public key into a format that can be registered:
Convert the public key to a format suitable for the request and register it:
Now, the system associates your public key with the username
elliot
.
With the attacker’s public key now in the database, you can forge a valid JWT token using your private key. Modify the payload to include an “admin”: “true” claim, effectively impersonating an admin.
Use a JWT library (e.g., PyJWT
in Python) to create an admin token. Key details include setting "admin": "true"
in the payload and signing with the private key.
Sample Python code to create a signed JWT:
Send the forged token to an admin-only endpoint, such as /goldenticket
:
If successful, the server will issue the golden ticket, which is typically a privileged access token or admin access to the application.
Hacking JWT Tokens: Key Database Mismanagement
For Other Attacks :
Verification Key Mismanagement
Hacking JWT Tokens: Verification Key Mismanagement
Hacking JWT Tokens: Verification Key Mismanagement II
Hacking JWT Tokens: Verification Key Mismanagement III
Hacking JWT Tokens: Verification Key Mismanagement IV
Vulnerable Key Generator
Hacking JWT Tokens: Vulnerable Key Generator
Transaction Replay
Hacking JWT Tokens: Transaction Replay
Hacking JWT Tokens: Transaction Replay II
JWS Standard for JWT
Hacking JWT Tokens: JWS Standard for JWT
Hacking JWT Tokens: JWS Standard for JWT II
Bypassing NBF Claim
Hacking JWT Tokens: Bypassing NBF Claim
Special Version Claim
Hacking JWT Tokens: Special Version Claim
Cross Service Relay Attack — Missing audience claim
Hacking JWT Tokens: Cross Service Relay Attack — Missing audience claim
Cross Service Relay Attack — Misconfigured audience claim
Hacking JWT Tokens: Cross Service Relay Attack — Misconfigured audience claim
Quick Methodology:
1. Copy Jwt token from the request
2. Use Jwt_Tool
3. use command :
4. Check for green line
MindMap:
Labs:
https://github.com/h-a-c/jwt-lab
GitHub — Sjord/jwtdemo: Practice hacking JWT tokens
Reports:
site:hackerone.com inurl:reports “jwt”
Video:
How to Exploit “Json Web Token”(JWT) vulnerabilities | Full Practical
Last updated