CVE-2021-41117
توليد أرقام عشوائية غير آمن
- تم النشر
- 11/10/2021
- محدث
- 04/08/2024
- تخصيص CNA
- GitHub_M
- الأدلة المرصودة
- 08/08/2026
CVSS الأساسي
nvd · CVSS 3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:Nمنخفض · الثلاثين يومًا القادمة
- المئوية
- 87.1%
- تاريخ الموديل
- 21/09/2026
EPSS هو تقدير إحصائي، وليس يقينًا أو مقياسًا للتأثير. ادمجها مع CVSS وحالة KEV والتعرض وبيئتك.
ملخص
keypair هو مولّد مفاتيح RSA بصيغة PEM مكتوب بلغة JavaScript. يطبّق keypair الكثير من الأوليات التشفيرية (cryptographic primitives) بنفسه أو بالاستعانة بمكتبات أخرى حيثما أمكن، بما في ذلك node-forge. تم اكتشاف مشكلة تتمثل في أن هذه المكتبة كانت تولّد مفاتيح RSA متطابقة تُستخدم في SSH. هذا يعني أن المكتبة كانت تولّد قيماً متطابقة لـ P و Q (وبالتالي N)، وهو أمر مستحيل عملياً مع مفاتيح RSA-2048. عادةً ما يشير توليد قيم متطابقة بشكل متكرر إلى وجود مشكلة في ضعف توليد الأرقام العشوائية، أو ضعف في التعامل مع مخرجات CSPRNG. المشكلة 1: ضعف توليد الأرقام العشوائية (`GHSL-2021-1012`). لا تعتمد المكتبة كلياً على CSPRNG الموفَّر من المنصة، بل تستخدم نهج CMAC القائم على العدّاد الخاص بها. موضع الخلل هو بَذر تنفيذ CMAC ببيانات عشوائية "حقيقية" في الدالة `defaultSeedFile`. من أجل بَذر مولّد AES-CMAC، تتبع المكتبة نهجين مختلفين اعتماداً على بيئة تنفيذ JavaScript. في المتصفح، تستخدم المكتبة [`window.crypto.getRandomValues()`](https://github.com/juliangruber/keypair/blob/87c62f255baa12c1ec4f98a91600f82af80be6db/index.js#L971). ومع ذلك، في بيئة تنفيذ nodeJS، لا يتم تعريف كائن `window`، لذا تنتقل إلى حل أقل أماناً بكثير، ويحتوي هذا الحل أيضاً على خطأ فيه. يبدو أن المكتبة تحاول استخدام CSPRNG الخاص بـ node عندما يكون ذلك ممكناً، لكن للأسف يبدو أن كائن `crypto` هو `null` بسبب تعريف متغير بنفس الاسم وضبطه على `null`. لذلك لا يتم أبداً اتخاذ مسار CSPRNG الخاص بـ node. لكن، عندما لا تكون `window.crypto.getRandomValues()` متاحة، يتم استخدام مولّد أرقام عشوائية من نوع Lehmer LCG لبَذر عدّاد CMAC، ويتم بَذر الـ LCG باستخدام `Math.random`. في حين أن هذا ضعيف وربما يُعد بحد ذاته خطأً أمنياً، إلا أنه لا يفسّر التكرار الشديد لحدوث مفاتيح مكررة. الخلل الرئيسي: يتم ترميز مخرجات Lehmer LCG بشكل غير صحيح. [السطر المحدد][https://github.com/juliangruber/keypair/blob/87c62f255baa12c1ec4f98a91600f82af80be6db/index.js#L1008] الذي يحتوي على الخلل هو: `b.putByte(String.fromCharCode(next & 0xFF))` [تعريف](https://github.com/juliangruber/keypair/blob/87c62f255baa12c1ec4f98a91600f82af80be6db/index.js#L350-L352) `putByte` هو `util.ByteBuffer.prototype.putByte = function(b) {this.data += String.fromCharCode(b);};`. وبشكل مبسّط، هذا يعادل `String.fromCharCode(String.fromCharCode(next & 0xFF))`. الاستدعاء المزدوج لـ `String.fromCharCode` شبه مؤكد أنه غير مقصود وهو مصدر ضعف البَذر. وللأسف، لا يؤدي هذا إلى حدوث خطأ، بل يؤدي إلى أن معظم محتوى المخزن المؤقت يكون أصفاراً. وبما أننا نقوم بإخفاء البتات باستخدام 0xFF، يمكننا تحديد أن 97% من مخرجات الـ LCG تتحول إلى أصفار. المخرجات الوحيدة التي تنتج قيماً ذات معنى هي المخرجات من 48 إلى 57 شاملةً. الأثر هو أن كل بايت في بَذر مولّد الأرقام العشوائية لديه فرصة 97% ليكون 0 بسبب التحويل غير الصحيح. وعندما لا يكون كذلك، تكون قيمة البايتات من 0 إلى 9. باختصار، هناك ثلاثة مخاوف فورية: 1. تمتلك المكتبة مساراً احتياطياً غير آمن للأرقام العشوائية. من الأفضل أن تتطلب المكتبة CSPRNG قوياً بدلاً من محاولة استخدام LCG و `Math.random`. 2. لا تستخدم المكتبة بشكل صحيح مولّد أرقام عشوائية قوياً عند تشغيلها في NodeJS، على الرغم من توفر CSPRNG قوي. 3. يحتوي المسار الاحتياطي على مشكلة في التنفيذ حيث أن غالبية بيانات البَذر ستكون أصفاراً فعلياً. بسبب ضعف توليد الأرقام العشوائية، يولّد keypair مفاتيح RSA يسهل تخمينها نسبياً. قد يمكّن هذا المهاجم من فك تشفير الرسائل السرية أو الحصول على وصول مصرّح به إلى حساب يخص الضحية.
الاستخدام المسؤول
استخدم معلومات الثغرات الأمنية فقط على الأنظمة التي تمتلكها أو المرخص لها باختبارها. يرتبط Kitploit ببيانات تعريف البحث العامة ولا يخزن أكواد الاستغلال أو الحمولات الضارة.