Buenas a todos!

A raiz de un curso que hice hace un par de meses, tomé diferentes notas e investigué acerca de qué era y cómo funcionaba JWT.

Espero que os sirva tanto como me sirvió a mi para entender más que es JWT.

JWT FOR BEGINNERS

  1. Introducción a autenticación y JWTs
  2. Estructura de JWTs
  3. Firma de un token JWT
  4. Securización de Token JWT
  5. Ciclo de vida de un Token JWT
  6. Understanding HS256
  7. Understanding RS256
  8. Recomendaciones para evitar ataques a JWT
  9. Diferentes ataques
  10. Referencias

1.    Introducción a JWTs

JSON Web Token (JWT) es un estándar abierto (RFC 7519) que define una forma compacta y autónoma de transmitir información de forma segura entre las partes como un objeto JSON. Esta información puede ser verificada y confiable porque está firmada digitalmente. Los JWT pueden ser firmados usando un secreto (con el algoritmo HMAC) o un par de claves públicas/privadas usando RSA o ECDSA.

JWT se utiliza para autorizar al usuario, una vez logueado, a acceder a las rutas, servicios y recursos que se permiten con ese token a los usuarios en las aplicaciones después de un inicio de sesión válido y también para transmitir información de forma segura entre las partes

Éstos se basan en el formato JSON e incluyen una firma para asegurar la integridad del token.

2.    Estructura de JWTs

Se trata de una cadena de texto formada por tres partes codificadas en Base64, donde cada una de ellas está separada por un punto, como se observa en la siguiente imagen:

Sh3llCON - JWT FOR BEGINNERS

Este token puede ser decodificado y mostraría la siguiente apariencia con diferentes Claims (propiedades):

Sh3llCON - JWT FOR BEGINNERS

El token está formado por tres partes: header, payload y signature.

Header

La primera parte «header«, hace referencia al encabezado dónde se indica, al menos, el algoritmo (alg) y el tipo de token (typ).

Sh3llCON - JWT FOR BEGINNERS

En la imagen, correspondería a la siguiente cadena «eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9»

Existen varios tipos de algoritmo como HS256 y RS256:

  • HS256: Simétrico, usa el mismo «secret» para firmar y para verificar el token. Es más seguro (siempre y cuando el «secret» no se vea comprometido y sea robusto) , más rápido y el token es más pequeño.
  • RS256: Asimétrico (un par de claves públicas/privadas), usa una clave privada para firmar el token y usa una clave pública para verificar el token.

Se puede emplear HS256 de forma segura, ya que se tiene el control sobre quién usa las claves secretas. En el caso de que no se tenga control sobre el cliente o si no se tiene forma de asegurar la «shared key», es mejor emplear RS256 ya que el consumidor solo necesita conocer la clave pública (compartida).

Payload

La segunda parte «payload«, hace referencia a los datos de usuario y privilegios de éste. Existen 3 tipos de Claims:

  • Public Claim Names: son valores personalizados públicos. Para evitar colisiones, se recomienda registrarlos en IANA JSON Web Token Registry.
  • Private Claim Names: son valores personalizados privados. Estos pueden estar sujetos a colisiones.
  • Registered Claim Names: son valores acerca del registro. Estos proporcionan información acerca del contenido. Existen varios tipos de de Claim especificos:
    • iss: Identifica al emisor del token. El uso de este claim es opcional.
    • sub: Identifica el asunto del JWT. El valor del sujeto debe ser contemplado para ser locamente único en el contexto del emisor o ser globalmente único. El uso de este claim es opcional.
    • aud: Identifica a los receptores del JWT. El uso de este claim es opcional.
    • exp: Identifica la hora de expiración, a partir de la cual, el token no será válido para su procesamiento. El uso de este claim es opcional.
    • nbf: Identifica el momento antes del cual el JWT no debe ser aceptado para su procesamiento. Requiere que la fecha/hora actual debe ser posterior o igual a la fecha/hora que figura en ‘nbf’. El uso de este claim es opcional.
    • iat: Identifica la hora a la que fue emitido el token. El uso de este claim es opcional.
    • jti: Identifica un ID único para el JWT. Este debe asignarse de manera que asegure que hay una probabilidad insignificante de que el mismo valor sea asignado accidentalmente a un objeto de datos diferente; si la aplicación utiliza múltiples emisores, se deben prevenir las colisiones entre los valores producido por diferentes emisores también. El uso de este claim es opcional.

En la imagen, correspondería a la siguiente cadena «eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ»

Sh3llCON - JWT FOR BEGINNERS
Signature

Por último, la tercera parte «signature«, permite verificar si el token es válido. En la imagen, correspondería a la siguiente cadena «SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c»

3.    Firma de un token JWT

La firma de un token JWT garantiza la validez del mensaje y de remitente.

La firma se construye como el HMACSHA256, que son las siglas de Hash-Based Message Authentication Code (Código de Autenticación de Mensajes), cifrado con el algoritmo SHA de 256. Esta función es aplicada a:

  • Codificación en Base64 de header.
  • Codificación en Base64 de payload.
  • Un secreto (establecido por la aplicación).
Sh3llCON - JWT FOR BEGINNERS

La firma se genera, en primer lugar, cuando la aplicación concatena la cadena de «header» y «payload» en Base64url. Después, se usa el secreto y se aplica el algoritmo presente en «header» para generar la «signature».

Todo este proceso no garantiza que el Token JWT sea completamente seguro.

Con las medidas mencionadas, en el caso de que se trate de modificar algún dato, se podría verificar la integridad del mensaje y denegar la solicitud de datos que hayan sido solicitados. Siempre se debería de verificar con esta firma si el token es válido.

4.    Securización de Token JWT

Es necesario tener en cuenta la securización del token debido a que los datos de «header» y «payload» se codifican en Base64url y con lo cual, no van cifrados sino codificados.

Se recomienda que la comunicación entre el cliente y el servidor vaya cifrada con el protocolo HTTPS.

5.    Ciclo de vida de un Token JWT

A continuación, se explica el ciclo de vida de un Token JWT.

En primer lugar, el cliente hace una petición POST al servidor enviando el usuario y contraseña. De esta manera, se realiza el proceso de login.

A continuación, en el servidor se comprueba que el usuario y contraseña son correctos, y si lo son, se genera un token JWT que es enviado al cliente.

A partir de ese momento, la aplicación cliente, con el token generado, hace peticiones al cliente solicitando recursos. Este token JWT siempre va en las cabeceras de las peticiones; se mostraría de la siguiente forma «Authorization: Bearer XXXXXXX», siendo Bearer el prefijo que precede al contenido del token.

En la parte del servidor, se comprueba la validez del token mediante la firma para verificar que el token es válido.

Una vez verificado el token e identificado al usuario que ha realizado la petición, se aplica el control de acceso a los recursos que solicite.

Sh3llCON - JWT FOR BEGINNERS

6.    Understanding HS256

HS256 es un algoritmo de firma SHA256 que codifica «Header«,»Payload» y «Secret» en base64url.

Sh3llCON - JWT FOR BEGINNERS
  1. En primer lugar, se mandan las credenciales del login desde «Client» a «Authorization Server» y este comprueba si las credenciales son válidas.
  2. En el caso de que las credenciales sean válidas, «secret key» es empleada para la generación de un token JWT válido.  (Esa «secret key» es distribuida a los diferentes «Resource Server» presentes en la aplicación).
  3. Una vez que «Client» tiene el token JWT válido e intenta acceder a «Resource Server» este comprueba que la «secret key» con la que se ha firmado el token JWT es la misma que el posee.

Un ataque no tendría acceso a «Resource Server» debido a que, en primer lugar, comprueba la existencia de un token JWT válido. Para poder obtener «secret key» tendría que darse alguna de las siguientes casuísticas:

  1. Dado que «secret key» es distribuida a todos los servidores, si se compromete un servidor, se podría obtener dicha «secret key«.
  2. Si el «Header» de «secret key» que se emplea con HS256 es débil, ésta puede ser obtenida a través de fuerza bruta.

.

Ejemplo

En primer lugar, se ejecuta la máquina virtual y se observa la IP que nos asigna.

Seguidamente, se ejecuta en nuestro entorno «Postman» y se lanza la petición de login (esta se facilita en el pdf de la documentación del curso).

Sh3llCON - JWT FOR BEGINNERS

Se observa la respuesta de la petición, donde devuelve el token JWT de acceso generado a partir del algoritmo de tipo HS256.

Sh3llCON - JWT FOR BEGINNERS

Una vez generado el token JWT, se accede vía ssh a la máquina donde está desplegada la aplicación. Se abre «api.php» que es el archivo donde se encuentra el código fuente asociado al endpoint del login y del getccinfo

Sh3llCON - JWT FOR BEGINNERS

7.    Understanding RS256

RS256 es la «signature» del hash generado a partir del «Header» y del «Payload«. Dicho hash se firma utilizando la clave privada de RSA. Esta firma generada es la tercera parte del JWT.

RS256 usa algoritmos de cifrado RSA y SHA256.

Solamente se puede emplear este tipo de firma si se tiene la «secret key» para descifrar el hash generado. Esta «secret key» solamente se encuentra disponible en «Authorization Server», que es donde se generan los token JWT y no se encuentra disponible en ningún «Resource Server».

Sh3llCON - JWT FOR BEGINNERS
  1. En primer lugar, se mandan las credenciales del login desde «Client» a «Authorization Server» y este comprueba si las credenciales son válidas.
  2. En el caso de que las credenciales sean válidas, «secret key» es empleada para la generación de un token JWT válido.
  3. Una vez obtenido un token JWT válido, cuando se quiera acceder a «Resource Server», este tiene que comprobar si la «signature» del JWT es válido o no. Usa la «public key» (presente en los «Resource Server») para validar si la «signature» presente en el JWT es válida o no.

Si el atacante quiere acceder a «Resource Server» no podrá acceder debido a que no tiene un token JWT válido. Para poder acceder a «Resource Server», el atacante debe tener las credenciales del login y un token JWT válido o tener acceso a «secret key«, habiendo comprometido previamente «Authoriztion Server» que es donde se localiza «secret key«, para generarse sus propios tokens JWT válidos.

El empleo de RS256 implica:

  1. «Private key» solamente está presente en «Authorization Server».
  2. Solamente aquel servidor que tenga la «private key» puede crear nuevos tokens JWT válidos.
  3. El empleo de cifrados de tipos RSA son lo suficientemente largos para prevenir los ataques de fuerza bruta.

8.    Recomendaciones para evitar ataques a JWT

No se recomienda el uso del algoritmo ‘none’ en la generación de JWT.

Se recomienda el uso de claves compartidas robustas para evitar, de esta forma, que sea fácil crackear esta clave.

Se recomienda el uso de un algoritmo en vez de una whitelist donde permita, por ejemplo, el algoritmo ‘none’. En el caso de que se necesite emplear algoritmos como RS256 y HS256, se recomienda que se separen ambos algoritmos en funciones diferentes para tener un control sobre las claves que se emplean en cada caso.

9.    Diferentes ataques

 None algorithm attack

JWT soporta el algoritmo de tipo «none». Si el campo «alg» está configurado como «none», cualquier token puede estar considerado valido dejando la sección «signature» vacía.

Esto permitirá a los atacantes utilizar un token falso y hacerse pasar por otro usuario utilizando un token suplantado.

En primer lugar, se instala la extensión llamada «JSON Web Tokens» para manipular los tokens JWT «on the fly», comprobar su validez y automatizar los ataques comunes.

Sh3llCON - JWT FOR BEGINNERS

Se acceder a https://jwt-lab.herokuapp.com/users/new y se crea un usuario con el cual se van a realizar las pruebas:

Sh3llCON - JWT FOR BEGINNERS
Sh3llCON - JWT FOR BEGINNERS

En segundo lugar, se accede a la web: https://jwt-lab.herokuapp.com/authentication/none, se activa el «Intercept» del Burp y se introducen los datos que se han generado: test_es/test.

Sh3llCON - JWT FOR BEGINNERS

Se deja pasar la petición, se intercepta la siguiente, se observa que nos devuelve un parámetro llamado «challenge» donde viene el JWT y nos indica que nuestro usuario actual es «test_es»:

Sh3llCON - JWT FOR BEGINNERS
Sh3llCON - JWT FOR BEGINNERS

Se envía la petición al «Repeater» para analizarla:

Sh3llCON - JWT FOR BEGINNERS

Una vez esté la petición en el apartado «Repeater», se selecciona el JWT que la aplicación ha devuelto y se analiza. Existen varias formas de analizarlo: La primera es mandarlo al «Decoder» y la segunda con la extensión «JSON Web Tokens«, instalada anteriormente.

Opción «Decoder»:

Se manda el JWT al apartado «Decoder».

Sh3llCON - JWT FOR BEGINNERS

Una vez en el apartado «Decoder», se selecciona la opción «Base64».

Sh3llCON - JWT FOR BEGINNERS

Cuando se codifica, se observa la información que contiene el JWT.

Sh3llCON - JWT FOR BEGINNERS

Opción «JSON Web Tokens»:

Se pincha en la opción «JSON Web Tokens«.

Sh3llCON - JWT FOR BEGINNERS

La extensión devuelve la información del JWT de una forma sencilla de interpretar la información que tiene el token.

Sh3llCON - JWT FOR BEGINNERS

En este caso, se quiere comprobar que permite un ataque al algoritmo dejando este vacío. Se modifica el tipo de algoritmo a «none» y en valor del parámetro «name» del Payload a «admin», que es el usuario que se pide.

Sh3llCON - JWT FOR BEGINNERS

Se lanza la petición y se comprueba en la respuesta que el usuario actual es «admin».

Sh3llCON - JWT FOR BEGINNERS

Cabe destacar que el valor del parámetro «challenge» solamente contiene «header» y «payload«. El algoritmo, al ser de tipo «none» no requiere de «signature«.

Sh3llCON - JWT FOR BEGINNERS
 The signature is not checked

Un fallo de seguridad en JWT suele ser que no se verifica el token cuando lo recibe la aplicación. Un atacante podría eludir este paso de verificación proporcionando a la aplicación una «signature» invalida.

Esto permitirá a los atacantes suplantar cualquier token que quieran y hacerse pasar por otro usuario usando un token suplantado.

Se accede a la web https://jwt-lab.herokuapp.com/authentication/signature y se observa que el usuario creado anteriormente está logueado.

Se recarga la web, se intercepta y se manda al «Repeater«.

Sh3llCON - JWT FOR BEGINNERS

Se emplea la extensión «JSON Web Tokens«.

Sh3llCON - JWT FOR BEGINNERS

Se elimina el valor del campo «Signature» y se modifica el valor del campo «Payload» de «test_es» a «admin».

Sh3llCON - JWT FOR BEGINNERS
Sh3llCON - JWT FOR BEGINNERS

Por último, se lanza la petición y se comprueba que se tiene un JWT válido con el usuario «admin».

Sh3llCON - JWT FOR BEGINNERS
The signature is weak

En este ataque se verá cómo se puede obtener, en texto claro, la firma obtenida mediante fuerza bruta.

En primer lugar, acceder a la URL donde está el reto: https://jwt-lab.herokuapp.com/authentication/weak.

A continuación, se realiza el login con el usuario creado en el reto inicial: test_es/test. Una vez logueado, con una extensión del navegador, como «Cookie Editor«, se observa que una flag se llama «challenge«, se copia el valor, que es el token válido y se genera un fichero llamado «secretkey.hash» que posteriormente será usado.

Sh3llCON - JWT FOR BEGINNERS

Con la herramienta hashcat, se crackea la «signature» del token anteriormente guardado en el archivo «secretkey.hash» facilitándole un diccionario existente como «rockyou.txt» o generando uno con la herramienta Crunch, por ejemplo.

Sh3llCON - JWT FOR BEGINNERS
Sh3llCON - JWT FOR BEGINNERS

Una vez finalizado el crackeo de la contraseña, hashcat muestra el valor de la firma en texto claro.

Sh3llCON - JWT FOR BEGINNERS

Una vez obtenido el valor de la clave, se captura una sesión de login y se manda al Repeater.

Sh3llCON - JWT FOR BEGINNERS

Una vez mandada la petición al Repeater, se emplea la extensión «JSON Web Tokens«.

Sh3llCON - JWT FOR BEGINNERS

Si se ejecuta la petición original, siendo el usuario ‘test_es’ el que está logueado, la aplicación indicaría que el usuario actual es ‘test_es’.

Sh3llCON - JWT FOR BEGINNERS
Sh3llCON - JWT FOR BEGINNERS

Como se ha conseguido el valor de la firma, se recalcula la firma introduciendo el valor de la key y modificando el usuario ‘test_es’ por el usuario ‘admin’.

Sh3llCON - JWT FOR BEGINNERS

Una vez modificados estos parámetros, se lanza la petición y se comprueba que se ha realizado el inicio de sesión como ‘admin’.

Sh3llCON - JWT FOR BEGINNERS

El token válido del usuario ‘test_es’ es: eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidGVzdF9lcyJ9.DZSgsFtFQWMePcXMpuOfEU3ouJKFUcr0vWRzyHAB8vw

El token válido del usuario ‘admin’ es: eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYWRtaW4ifQ.gDs9V-6by-T2sF5CVXQn7WPOZ_YkAfg0nx-pzLMQk

Brute forcing the signature

En algunos casos cuando se genera los JWT, en la fase de implementación se ha emplea una «key» débil para generar la «signature«. Esto deja expuesto a que esa «signature» pueda ser descubierta utilizando la técnica «brute force» y emplearla para generar «signatures» propias.

Esto permitirá a los atacantes suplantar cualquier token que quieran y hacerse pasar por otro usuario usando un token suplantado.

Se recomienda el uso de «keys» robustas y largas o tokens RS256.

Si se dispone de un token válido, por ejemplo «eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDc4MDIzMTQsImlzcyI6ImxvY2FsaG9zdCIsImV4cCI6MTYwNzgxMTMxNCwidXNlcklkIjoiYWRtaW4iLCJpc0FkbWluIjoidHJ1ZSJ9.iGnnxauj6mCBnXtCuwQl-uP1LRLCyGrwArZ8xF7sWsY», se pueden emplear herramientas como «jwt-cracker» para obtener el valor de la «signature«.

En primer lugar, se instala la aplicación ejecutando el comando «npm install –global jwt-cracker».

Sh3llCON - JWT FOR BEGINNERS

Después empleamos la herramienta. Su sintaxis es la siguiente: jwt-cracker

Sh3llCON - JWT FOR BEGINNERS

De esta forma se obtendría la secret key.

10.  Referencias:

Debugger online: https://jwt.io/

Laboratorio: https://jwt-lab.herokuapp.com/

https://adamc95.medium.com/json-web-token-lab-guide-c402857fa44c

https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a

JWT: https://openwebinars.net/blog/que-es-json-web-token-y-como-funciona/

RFC7519 – https://tools.ietf.org/html/rfc7519

https://www.developerro.com/2019/03/12/jwt-api-authentication/

jwt-cracker – https://github.com/lmammino/jwt-cracker

https://theoffensivelabs.com/p/hacking-and-securing-json-web-tokens-jwt

La imagen de cabecera se ha compuesto con una foto cortesía de Pixabay

Firmado: Carol

Sh3llCON no se hace responsable de las opiniones vertidas por sus colaboradores ni por las actuaciones que, fruto del conocimiento transmitido, puedan realizar terceras personas.