
Script python simple pour vérifier une hypothétique vulnérabilité JWT.
Script Python simple pour vérifier une hypothétique vulnérabilité JWT.
Disons qu'il existe une application qui utilise des tokens JWT signés avec l'algorithme HS256. Un exemple de token ressemble à ceci :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.zbgd5BNF1cqQ_prCEqIvBTjSxMS8bDLnJAE_wE-0Cxg
Le token ci-dessus peut être décodé pour obtenir les données suivantes :
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Pour calculer la signature, le secret suivant est utilisé :
supersecret
Le pseudo-code suivant est utilisé pour calculer la signature :
$alg = "sha256";
$data = "...";
$key = "supersecret";
hmac($alg, $data, $key);
Mais que se passerait-il si un champ "kid":0 inattendu était injecté dans l'en-tête ?
{
"alg": "HS256",
"typ": "JWT",
"kid": 0
}
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Le champ kid est un moyen standard de choisir une clé. Mon hypothèse est que, si le champ kid n'est pas attendu, il pourrait y avoir une implémentation vulnérable qui traitera la valeur de la chaîne $key comme un tableau :
hmac($alg, $data, $key[kid]);
En conséquence, la valeur "s" ($key[0]) sera utilisée comme secret HMAC.
Le script injector.py prend un token JWT original, injecte le champ "kid":0 dans l'en-tête et génère des tokens signés avec les secrets d'une lettre (codes ASCII : 32 - 126 [{espace}, !, ", #, ..., x, y, z, {, |, }, ~]) :
python3 injector.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.zbgd5BNF1cqQ_prCEqIvBTjSxMS8bDLnJAE_wE-0Cxg
En résultat, deux fichiers sont créés : tokens.txt et tokens_meta.txt. tokens.txt contient les tokens générés et peut être utilisé comme liste de payloads pour Burp Intruder. Si un token est valide (ce qui signifie que l'application est vulnérable), le fichier tokens_meta.txt peut être utilisé pour vérifier quel algorithme et secret ont été utilisés pour générer le token donné. Le fichier tokens_meta.txt contient les données suivantes :
token1:algorithm:secret
...
token{n}:algorithm:secret
Consultez le CHANGELOG