Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2024-42642 — إثباتات مفهوم لاستغلال ثلاث ثغرات في آلية تحديث البرامج الثابتة لمحرك الأقراص الصلبة Crucial MX500 SSD، مما يتيح تجاوز سعة المخزن المؤقت واحتمالية تنفيذ التعليمات البرمجية عبر أوامر ATA. | Kitploit
أدوات/GitHubGitHub/vl4dr/cve-2024-42642
أمان الأنظمة المدمجةتحليل الثغرات الأمنيةالاستغلالالهندسة العكسيةاختراق الأجهزةأمن الأجهزةتحليل الملفات الثنائيةتحليل البرامج الثابتة
GitHubvl4dr/cve-2024-42642

CVE-2024-42642

إثباتات مفهوم لاستغلال ثلاث ثغرات في آلية تحديث البرامج الثابتة لمحرك الأقراص الصلبة Crucial MX500 SSD، مما يتيح تجاوز سعة المخزن المؤقت واحتمالية تنفيذ التعليمات البرمجية عبر أوامر ATA.

عرض المستودع
14112منذ سنة واحدةلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2024-42642

مقدمة

الجهاز المعني هو أي قرص SSD من سلسلة MX500. تُدار هذه الأقراص بواسطة وحدة تحكم من نوع Sillicon-Motion SM2259 (كانت الدفعات الأقدم تحتوي على وحدة تحكم أقدم، وهي Sillicon-Motion SM2258، لكن التركيز الرئيسي لهذا المستند هو الأحدث).
SM2259 هي وحدة تحكم دقيقة (micro-controller) بأربع قنوات و SATA 6Gb/s، وتضم CPU بمعمارية ARC وبنمط little-endian بعرض 32 بت.
من خلال ملاحظة أحدث برنامج ثابت سارٍ حتى تاريخ هذا المستند، وهو M3CR046، تم تحديد عدد من الثغرات وتأكيدها بشكل ثابت (statically) وديناميكي (dynamically).

تم تحديد جميع هذه الثغرات في آلية تحديث البرنامج الثابت الخاصة بوحدة التحكم، وتحديدًا في معالج المتحكم الدقيق لأمر ATA PIO DOWNLOAD-MICROCODE (0x92)، وبشكل خاص في المنطق الذي ينزّل البرنامج الثابت باستخدام طريقة الإزاحات (offsets)، والتي تقابل الأوامر الفرعية 0x03 و 0x0E.

تم التحقق من جميع الثغرات التي يغطيها هذا المستند على قرص Crucial MX500 بسعة 500GB (CT500MX500SSD1)، بوحدة تحكم SM2259H-AC تعمل بالبرنامج الثابت M3CR046 مع شرائح فلاش NY112، وذلك باستخدام حاسوب بوحدة معالجة x86_64.

يتم تعيين كود البرنامج الثابت إلى العنوان الأساسي 0x80020000، ويقع معالج ATA المعرّض للثغرة عند العنوان 0x80024A9C. يمكن العثور على نسخة مفككة من الدالة في المسار resources/download_microcode_handler.c لتيسير الاطلاع عليها.

لمن يفضّل عدم الخوض في التفاصيل التقنية ويريد فهم الخلاصة، يُرجى الرجوع إلى قسم الأسئلة الشائعة (FAQ) أدناه.

بما أن M3CR046 يحتوي على عدة صور للبرنامج الثابت، ويقوم آلية تحديث البرنامج الثابت باختيار الصورة المناسبة منها (ربما اعتمادًا على شرائح الفلاش المستخدمة فعليًا، أو على خصائص أجهزة أخرى)، فإن هذا المستند سيغطي تفاصيل المتغير الأول من البرنامج الثابت (لأنه البرنامج الثابت المدعوم على قرصنا المحدد، وبالتالي لم نتمكن إلا من اختبار هذا المتغير). ومع ذلك، يبدو أن الثغرات المعروضة في هذا المستند تنطبق على جميع متغيرات البرنامج الثابت، لكن قد توجد بعض الاختلافات في التفاصيل الفعلية عند إعادة إنتاجها.

الثغرة #1

تشير هذه الثغرة إلى الحالات التي يكون فيها الجزء (chunk) الأول المُرسل أكبر من 0x200 قطاع. إذا ألقينا نظرة داخل معالج أوامر ATA، وتحديدًا عند المنطق الذي يُنفَّذ عندما يكون حجم الجزء أكبر من حجم القطاع وعندما يكون الجزء المُرسل هو الأول:

معلومات الصورة

يؤدي ذلك إلى تعيين بعض المتغيرات بناءً على الإزاحة التالية (وهي في حالتنا، بما أننا أرسلنا جزءًا واحدًا فقط حتى الآن، طول الجزء بالقطاعات) وعلى متغير باسم lower_bound_fw_offset وهو إزاحة الكتلة (أي الإزاحة بدقة القطاعات) داخل صورة التنزيل المدخلة التي يُتوقع أن توجد فيها صورة البرنامج الثابت لدينا. هذه قيمة مُثبتة بشكل ثابت (hardcoded) لكل متغير برنامج ثابت، وهي في حالتنا (المتغير الأول) تساوي 0.
في هذه الحالة، يحدث underflow عند حساب نتيجة الطرح للمتغير some_index، مما يجعل قيمة some_index تبلغ 0xFFFF. هذا سلوك غير متوقع، لأنه بناءً على المنطق الذي ينقل البيانات إلى مخزن التنزيل المؤقت (download buffer):

معلومات الصورة

نلاحظ أن عنوان المصدر الذي تُنسخ منه البيانات قد لا يكون صالحًا نظرًا للقيمة غير المتوقعة المحسوبة لـ some_index.
عند اختبار ذلك ديناميكيًا عبر إرسال طلب تحديث للبرنامج الثابت بحيث يكون الجزء الأول أكبر من 0x200 قطاع، تعلّق وحدة التحكم ولا ترسل حتى استجابة للطلب الأصلي. هذا السلوك ثابت ومن السهل إعادة إنتاجه.
من المحتمل أن يحدث ذلك بسبب مرجع غير صالح إلى عنوان المصدر المحسوب، مما يؤدي إلى استثناء (exception) يسبّب تعليق وحدة التحكم. لم يتم إثبات ذلك، بل هو مجرد تخمين قد يفسّر هذا التعليق.

الثغرة #2

صورة التنزيل المدخلة (لـ M3CR046) يبلغ حجمها 0x242400 بايت، وداخل هذه الصورة توجد 3 صور داخلية للبرنامج الثابت، واحدة فقط منها تُكتب في النهاية إلى الفلاش بعد عملية تحديث البرنامج الثابت، وكل صورة من هذه الصور يبلغ حجمها 0xC0C00 بايت (أو 0x606 قطاع).
هذا يعني أنه عند قيام آلية تحديث البرنامج الثابت باستخراج النسخة الصحيحة من البرنامج الثابت من صورة التنزيل المدخلة، يجب عليها التحقق من أن حجمها لا يتجاوز 0xC0C00 بايت.

تحاول وحدة التحكم فعلًا القيام بذلك، لكن توجد بعض الحالات الحدّية (corner cases) التي قد تؤدي إلى سلوك غير متوقع. دعونا نلقي نظرة على المقطع التالي (الذي يشارك بعض الكود مع الثغرة السابقة):

معلومات الصورة

إذا كان حجم الجزء الحالي أكبر من 0x200 قطاع ولم يكن الجزء الأول في التسلسل، فسيتم نسخ 0x200 قطاع (0x40000 بايت) في كل مرة. بعد ذلك، يوجد فحص الغرض منه اقتطاع البايتات الزائدة من عدد البايتات المطلوب نسخها إذا تجاوز الحجم الإجمالي لصورة البرنامج الثابت higher_bound_fw_offset (وهو في حالتنا 0x606 قطاع، لأن حجم البرنامج الثابت يجب أن يكون هذا الحجم بالضبط).

هذا المنطق منطقي بشكل عام، لكن توجد فيه نقطة ضعف – إذا تسبب الجزء الأخير المُرسل في جعل الإزاحة التالية مرتفعة جدًا، بحيث يتجاوز عدد البايتات الزائدة 0x200 قطاع (أو 0x40000 بايت)، فإن curr_bytes_to_copy يحصل على قيمة “سالبة”، والتي تتحول عبر underflow إلى حوالي ~4GB (~0xFFFFFFFF). وكما رأينا سابقًا، يُستخدم هذا المتغير لتحديد عدد البايتات التي سيتم نقلها إلى مخزن التنزيل المؤقت.

إذا ألقينا نظرة داخل r_maybe_some_efficient_data_transfer، فسنرى المقطع البرمجي التالي:

معلومات الصورة

وهذا يعني أن حجم النسخ يُقتطع إلى 32MB (من حجم النسخ الأصلي ~4GB)، لكنه ما زال رقمًا كبيرًا قد يسبب أيضًا سلوكًا غير محدد إذا كان نطاق الذاكرة الذي يبدأ عند 0x40000000 أقل من 32MB.

عند اختبار ذلك ديناميكيًا عبر إرسال أجزاء ATA للوصول إلى إزاحة 0x600، ثم إرسال جزء كبير بحجم 0x207 قطاع لتحفيز الـ underflow، تعلّق وحدة التحكم مرة أخرى، على الأرجح بسبب وصول غير صالح إلى الذاكرة أثناء النسخ.

هذه الثغرة أكثر إثارة للاهتمام من سابقتها، لأنه على الرغم من عدم وجود كتابة فوقية موجهة (بل كتابة فوقية كبيرة قد تتسبب في استثناء يعلّق وحدة التحكم)، فإنه إذا تمكنت الدالة التي تنقل البيانات إلى مخزن التنزيل من نقل ذلك القدر الكبير من البيانات قبل الانهيار (بكتابة فوقية لنطاق الذاكرة الواقع مباشرة بعد مخزن التنزيل في الذاكرة الرئيسية)، فربما يتغير سلوك معالج الاستثناءات بناءً على البيانات المكتوبة فوقها. يمكن أن يحدث ذلك، على سبيل المثال، إذا قرأ معالج الاستثناءات مؤشرًا من المنطقة المكتوبة فوقها ثم قفز إليه (هذه الحالة المحددة ليست محتملة بشكل خاص، ولكن مع مزيد من البحث، قد يُكتشف شيء من هذا القبيل).

الثغرة #3

كما ذكرنا سابقًا، يبلغ حجم صورة التنزيل 0x242400 (أو 0x1212 قطاع). يتحقق البرنامج الثابت من أن الحجم الإجمالي للصورة المنقولة لا يتجاوز هذا الحجم عن طريق التحقق من أن الإزاحة التالية لا تتجاوز 0x1212 قطاع. هذا الفحص منطقي، لكن حساب الإزاحة التالية معيب:

معلومات الصورة

إذا كانت الإزاحة الحالية 0x600 قطاع، وكان أمر ATA التالي المطلوب معالجته كبيرًا بما يكفي (لنقل 0xFC00 قطاع، وهو مسموح به وفق معيار ATA)، فإن الإزاحة التالية تلتف (wrap around)، بحيث لا يعمل الفحص المذكور أعلاه بشكل صحيح:

معلومات الصورة

أو بعبارة أخرى، في الحالة المعتادة، كانت آلية تحديث البرنامج الثابت ستعيد ضبط آلة الحالة (state machine) وتُرجع خطأً، لكن إذا أرسلنا جزءًا كبيرًا جدًا، فسنواصل معالجته.

يوضح المقطع البرمجي التالي كيفية إجراء النقل:

معلومات الصورة

نذكّر هنا أنه إذا كان عدد القطاعات المراد نقلها أكبر من 0x200 قطاع والجزء الحالي ليس الأول، فسيتم نسخ 0x200 قطاع في كل مرة إلى مخزن التنزيل المؤقت. هذا مثير للاهتمام للغاية، لأنه يعني أنه يمكننا نسخ حوالي 0x200 قطاع (أو 0x40000 بايت) بعد مخزن التنزيل، مع الكتابة فوق بيانات في الذاكرة الرئيسية. على سبيل المثال، إذا كانت الإزاحة الحالية 0x605 قطاع وقدّمنا حجم جزء 0xF9FB قطاع، فإن __next_offset سيحصل على القيمة 0 بسبب الالتفاف. فهرس المصدر الذي يبدأ منه النسخ هو 0، ويحصل curr_bytes_to_copy على القيمة 0x40000. وبما أننا حاليًا عند الإزاحة 0x605 قطاع، فإن g_blocks_copied يحصل على القيمة 0x605. ونظرًا لأن الإزاحة الحالية صالحة بالفعل (والتالية كذلك)، يتم تشغيل عملية النسخ إلى مخزن التنزيل، مما يسبب كتابة فوقية ضخمة بحوالي أقل بقليل من 0x40000 بايت بعد نهاية مخزن التنزيل.

هذه بدائية (primitive) قوية تتيح تجاوزًا أكبر لمخزن وحدة التحكم (لا يسبب انهيارًا فوريًا لوحدة التحكم كما في الحالات السابقة)، ويمكن أن تؤدي إلى تنفيذ كود بدرجة يقين أعلى بكثير من الثغرة السابقة (لكن لا يزال هناك حاجة إلى مزيد من البحث حول ما هو موضوع بالضبط بعد مخزن التنزيل في الذاكرة الرئيسية لتحديد خصائص الاستغلال).

إعادة إنتاج الثغرات وملاحظات

تم التحقق من جميع هذه الثغرات على جهاز Ubuntu 22.04 بنية 64-bit باستخدام برنامج تشغيل SCSI القياسي في Linux عبر واجهة SG_IO. تجدر الإشارة إلى أنه لإعادة إنتاج الثغرة #3 مع برنامج التشغيل هذا تحديدًا، يجب تفعيل الصفحات الضخمة (huge pages) وتخصيص صفحة واحدة بحجم 1GB للطلب الكبير. السبب في ذلك هو أن برنامج التشغيل هذا، على ما يبدو، يتطلب أن يكون طلب ATA بالكامل في كتل ذاكرة فيزيائية متجاورة. ولأن حجم الطلب يقارب ~30MB، فإن صفحات 2MB غير كافية، وبالتالي فإن صفحات 1GB هي الحجم التالي (والأخير) المتاح على نظام الاختبار لدينا.

ومع ذلك، تجدر الإشارة أيضًا إلى أن هذا لا يعني أن هذه خطوة ضرورية لتفعيل الثغرة، لأنه ربما توجد حلول بديلة أخرى تسمح بإرسال طلبات ATA كبيرة لم نغطِّها بعد. كان تفعيل الصفحات الضخمة ببساطة أسرع طريقة لتأكيد هذه الثغرة. وإلى جانب ذلك، فإن المتطلب الوحيد اللازم لتفعيل كل هذه الثغرات هو الصلاحيات اللازمة لإرسال حزم ATA (عادةً صلاحيات الوصول الجذرية للحاسوب المتصل بوحدة التحكم).

الكود المصدري الذي يعيد إنتاج جميع الثغرات المذكورة أعلاه مقدم ضمن هذا المستودع.
بالنسبة للثغرة #1 والثغرة #2، السلوك المتوقع هو تعليق القرص حتى دورة التشغيل التالية.
أما بالنسبة للثغرة #3، فالكود المصدري المقدم لا يؤدي بالضرورة إلى انهيار وحدة التحكم، لكنه يقوم بكتابة فوقية كبيرة بعد مخزن التنزيل.

البناء والتشغيل

كما ذُكر سابقًا، نظرًا لأن الثغرات تم التحقق منها على جهاز Ubuntu 22.04 بنية 64-bit، يجب أن تتم عملية البناء على جهاز مشابه. لا توجد ضمانات للتوزيعات أو أنظمة التشغيل الأخرى.

للبناء، شغّل ما يلي في الدليل الجذر للمشروع:

root@kitploit:~
cmake -B build && make

عملية البناء تنشئ 3 ملفات تنفيذية، ستكون جميعها متاحة في دليل build بالأسماء CVE_MX500_BUG_1 و CVE_MX500_BUG_2 و CVE_MX500_BUG_3، والتي تقابل الملفات المصدريّة التي تثير الثغرة #1 والثغرة #2 والثغرة #3 على التوالي.

يتوقع كل ملف تنفيذي استلام مسار جهاز قرص MX500 SSD، ويجب تشغيله بصلاحيات الجذر. على سبيل المثال:

root@kitploit:~
sudo ./build/CVE_MX500_BUG1 /dev/sda

الأسئلة الشائعة

إذا كانت صلاحيات المسؤول/الجذر مطلوبة، فلماذا نتعب أنفسنا بمناقشة أي من الثغرات المذكورة هنا؟ أليس لديك سيطرة كاملة على القرص على أي حال؟

يعتمد ذلك على الهدف النهائي للمهاجم المحتمل. إذا كان كل ما يريده هو وصول كامل للقراءة/الكتابة إلى تخزين قرصك، فإن وجوده داخل حاسوبك يعد كافيًا بالفعل. لكن ماذا لو أراد المهاجم أن يتقدم خطوات إضافية؟ إذا كان البرنامج الثابت للقرص موقّعًا رقميًا، فإن الثغرة #3 يمكن أن تمكّن المهاجم من تجاوز التحقق من توقيع البرنامج الثابت، مما يتيح للمهاجم إدخال حمولة خبيثة في البرنامج الثابت للقرص. وبمجرد دخولها، تكون هذه الحمولة مخفية بشكل جيد للغاية، وتنجو من تهيئة القرص، ويمكنها حتى ضمان النجاة من تحديثات البرنامج الثابت لوحدة التحكم. ما يمكن أن تفعله هذه الحمولة فعليًا هو خارج نطاق هذا المستند، لذلك لن تتم مناقشته.

يبدو هذا خطيرًا! هل يجب أن أقلق بشأنه إذن؟

من المرجح أن تكون الإجابة: لا كبير. مقدار البحث والتطوير المطلوب لتنفيذ مثل هذا الهجوم مرتفع جدًا، ومن المحتمل جدًا أن يكون ممكنًا فقط من جهة جهات تهديدية خطيرة جدًا. ما لم تكن مطلوبًا من قبل الحكومات، فمن غير المرجح للغاية أن يؤثر ذلك عليك بأي شكل.

لماذا نشرت تفاصيل هذا CVE قبل أن يصدر البائع تصحيحًا له؟

لم يستجب البائع لرسائل بريد إلكتروني متعددة حول هذه القضايا على مدى أشهر. لكي يُنشر CVE فعليًا، يجب توفير رابط عام إلى CNA الذي قام بتعيينه. للأسف، إرسال المعلومات إليهم بشكل خاص ليس هو الطريقة التي يعمل بها هذا الأمر.

هل يمكنك مشاركة الجدول الزمني للإفصاح؟

الثغرات المذكورة في هذا المستند اكتُشفت في الأصل في مايو 2024. تم التواصل مع Micron عدة مرات منذ ذلك الحين (عبر بريدهم الإلكتروني الأمني الرسمي)، ولم يكن هناك رد منهم. تم إخطار MITRE في يوليو 2024، وتم تعيين CVE في أغسطس 2024. وفي نهاية أغسطس 2024، أصبح هذا المستودع عامًا (بعد أيام قليلة من اعتماد MITRE لـ CVE).

هل الإصدارات الأقدم متأثرة؟

نظرًا لأن إصدارات M3CR04X من البرامج الثابتة الأقدم من M3CR046 لم تعد متاحة للتنزيل، فمن غير الواضح ما إذا كانت متأثرة، ولكن إذا كان عليّ التخمين، فسأقول نعم.
أما بالنسبة للإصدارات الأقدم، على سبيل المثال M3CR033، فبناءً على التحليل الثابت، يبدو أن ثغرات مشابهة جدًا موجودة هناك.

ماذا عن البائعين الآخرين؟

وحدة التحكم المعنية، SM2259، مدمجة أيضًا في أقراص SSD من بائعين آخرين. من الممكن أن يقوم البائعون بتعديل جزء من كود البرنامج الثابت، لكنني أقول أيضًا إنه من الممكن بالتأكيد وجود هذه الثغرات (أو ثغرات مشابهة جدًا) في أقراص SSD من بائعين آخرين أيضًا.

الإفصاح

تم نشر هذا CVE بواسطة MITRE. كما تم تحليله بواسطة NVD بدرجة CVSS 3.0 تبلغ 6.7 (متوسطة).

ملاحظات ختامية

إذا حددت عدم دقة أو أخطاء في الوصف، أو كنت تواجه مشكلة في إعادة إنتاج هذه الثغرات، فيرجى التواصل معي على log1kxd at gmail.com.

تنزيل الأداة