
Semplice script Python per verificare una vulnerabilità JWT ipotetica.
Semplice script Python per verificare un'ipotetica vulnerabilità JWT.
Supponiamo che esista un'applicazione che utilizza token JWT firmati con l'algoritmo HS256. Un esempio di token è il seguente:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.zbgd5BNF1cqQ_prCEqIvBTjSxMS8bDLnJAE_wE-0Cxg
Il token sopra può essere decodificato nei seguenti dati:
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Per calcolare la firma viene usato il seguente segreto:
supersecret
Il seguente pseudo-codice viene utilizzato per calcolare la firma:
$alg = "sha256";
$data = "...";
$key = "supersecret";
hmac($alg, $data, $key);
Ma cosa succede se un campo "kid":0 inaspettato viene iniettato nell'header?
{
"alg": "HS256",
"typ": "JWT",
"kid": 0
}
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Il campo kid è un modo standard per scegliere una chiave. La mia ipotesi è che, se il campo kid non è previsto, potrebbe esserci un'implementazione vulnerabile che tratta il valore della stringa $key come un array:
hmac($alg, $data, $key[kid]);
Di conseguenza, il valore "s" ($key[0]) verrà usato come segreto HMAC.
Lo script injector.py prende il token JWT originale, inietta il campo "kid":0 nell'header e genera token firmati con segreti di una lettera (codici ASCII: 32 - 126 [{spazio}, !, ", #, ..., x, y, z, {, |, }, ~]):
python3 injector.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.zbgd5BNF1cqQ_prCEqIvBTjSxMS8bDLnJAE_wE-0Cxg
Come risultato vengono creati due file: tokens.txt e tokens_meta.txt. tokens.txt contiene i token generati e può essere usato come lista di payload per Burp Intruder. Se un qualsiasi token è valido (il che significa che l'applicazione è vulnerabile), il file tokens_meta.txt può essere usato per verificare quale algoritmo e segreto sono stati utilizzati per generare il token dato. Il file tokens_meta.txt contiene i seguenti dati:
token1:algorithm:secret
...
token{n}:algorithm:secret
Consulta il CHANGELOG