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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
cve-2024-21978-poc | Kitploit
أدوات/GitHubGitHub/freax13/cve-2024-21978-poc
أدوات التشفير/فك التشفيرتحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالاختبار الاختراقأمن الأجهزةاستغلال الملفات الثنائية
GitHubfreax13/cve-2024-21978-poc

cve-2024-21978-poc

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

الأكثر شعبية

عرض الكل →

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

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

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

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

ثغرة في البرنامج الثابت الخاص بـ SEV

يحتوي هذا المستودع على استغلال (exploit) لثغرة في البرنامج الثابت الخاص بـ SEV. يتيح الاستغلال فك تشفير ذاكرة اعتباطية من ضيف SEV-SNP قيد التشغيل.

تم اختباره على الإصدار 1.55.16 (أحدث إصدار وقت كتابة هذا النص).

السبب الجذري

يمكن استخدام حقل nv_paddr الخاص بأمر SEV_INIT_EX للتبرع بجزء من الذاكرة إلى البرنامج الثابت، بحيث يمكن استخدامه بدلاً من الفلاش الدائم. إذا كان SEV-SNP مفعّلاً، فيجب أن تكون هذه الذاكرة في حالة FIRMWARE. يتحقق البرنامج الثابت من ذلك مرة واحدة أثناء تنفيذ أمر SEV_INIT_EX. ومنذ تلك النقطة فصاعداً، يفترض البرنامج الثابت أن هذه الذاكرة في حالة FIRMWARE ويكتب إليها دون أي تحقق إضافي.

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

الاستغلال

يمكننا استغلال فساد الذاكرة هذا من خلال استهداف صفحات CONTEXT. تُعد صفحات CONTEXT هدفاً قوياً، لكن توجد بعض المشاكل:

  1. صفحات CONTEXT مشفرة بمفتاح مختلف عن بقية الذاكرة. ونتيجة لذلك، ليس من السهل التحكم في النص الصريح (plaintext) حتى لو تمكنا من التحكم في النص المشفر (ciphertext).
  2. ليس لدينا تحكم كبير في الذاكرة التي يكتبها البرنامج الثابت.

يملأ فساد الذاكرة صفحة CONTEXT فعلياً ببيانات عشوائية، لذا ليس من السهل إفساد صفحات CONTEXT بطريقة تفيد المهاجم. وللتغلب على ذلك، يمكننا تكرار تشغيل الثغرة لإحداث الفساد واستخدام أمر SNP_GUEST_STATUS لقراءة الحقول ذات الصلة من صفحة CONTEXT التالفة حتى نلاحظ قيماً مفيدة.

يمكن استخدام أمر SNP_DBG_DECRYPT لفك تشفير ذاكرة ضيف SEV-SNP مع تفعيل سياسة DEBUG. إذا تمكنا من صياغة CONTEXT بحيث تكون فيه علامة DEBUG مضبوطة ويحتوي على ASID الخاص بضيف آخر، فيمكننا استخدامه لفك تشفير ذاكرة الضيف الآخر حتى لو لم تكن سياسة DEBUG مفعّلة لديه.

اتضح أن SNP_DBG_DECRYPT يتجاهل معظم الحقول في صفحة CONTEXT؛ فهو يتحقق فقط من gctx->guest.asid وgctx->guest.policy_snp وgctx->guest.guest_flags. إن احتمال صحة هذه الحقول بعد فساد الذاكرة ليس مرتفعاً، لكنه ليس مستبعداً تماماً أيضاً. والخبر الجيد أيضاً أن بإمكاننا قراءة كل تلك الحقول باستخدام أمر GUEST_STATUS.

في الختام، يمكننا استغلال الثغرة عبر الخطوات التالية:

  1. نقل nv_paddr إلى حالة FIRMWARE باستخدام تعليمة rmpupdate.
  2. تنفيذ أمر SEV_INIT_EX.
  3. إعادة nv_paddr إلى حالة HYPERVISOR باستخدام أمر SNP_RECLAIM_PAGE.
  4. إنشاء صفحة CONTEXT واحدة أو أكثر عند nv_paddr.
  5. خداع البرنامج الثابت ليكتب إلى nv_paddr باستخدام أمر SEV_PDH_GEN. يؤدي هذا إلى إفساد صفحات CONTEXT.
  6. استخدام أمر GUEST_STATUS للتحقق مما إذا كان SNP_DBG_DECRYPT سينجح، وإذا لم ينجح فالعودة إلى الخطوة 5. العقبة الرئيسية هنا هي أن ASIDs تُخزَّن في عدد صحيح 32-بت، لكن عدد ASIDs الصالحة أقل بكثير (509 أو 1006 حسب المعالج)، لذا سيتطلب الأمر محاولات كثيرة جداً لتحقيق ذلك.

يقضي الاستغلال معظم وقته في الخطوتين 5 و6. احتمالات توافر جميع الشروط الصحيحة تبلغ حوالي 1/20,000,000 على معالج EPYC Milan، ويمكننا تنفيذ حوالي 100 محاولة في الثانية، لذا نتوقع بلوغ الشروط الصحيحة مرة واحدة كل يومين تقريباً (تحذير: الحسابات تقريبية فقط وقد أكون أخطأت في شيء ما، لكن من واقع التجربة، مرة كل يومين تبدو صحيحة تقريباً). يمكننا تسريع ذلك بعدم مهاجمة صفحة CONTEXT واحدة فقط في كل مرة، بل مهاجمة ثلاث صفحات CONTEXT عند nv_paddr وnv_paddr+4096 وnv_paddr+8192 (سيفسد SEV_PDG_GEN ثلاث صفحات). ومن الملائم أن هذه الخطوات يمكن تنفيذها قبل إطلاق الضيف الضحية، ولا يلزم نجاحها إلا مرة واحدة لمهاجمة أي عدد من الضيوف (لاحظ أن الإثبات المفاهيمي (PoC) يهاجم حالياً ضيفاً واحداً فقط).

التأثير

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

التخفيف

ينبغي لعدد من الأوامر (مثل SNP_RECLAIM_PAGE وSNP_GCTX_CREATE وRING_BUFFER، وربما المزيد؟ ربما كلها احتياطاً؟) التي تقبل صفحة بحالة FIRMWARE أن تتحقق مما إذا كانت تتداخل مع nv_paddr وأن تفشل إذا كان الأمر كذلك.

تخفيفات الترقية

لدّي قلق إضافي واحد، لست متأكداً من صحته وسأحب سماع رأيكم فيه: إذا ما فهمتُ الأمر بشكل صحيح، يمكن ترقية البرنامج الثابت لـ SEV دون مقاطعة الضيوف قيد التشغيل. وهذا يوحي لي بإمكانية نقل صفحة CONTEXT التالفة من إصدار قديم هشّ من البرنامج الثابت إلى إصدار جديد مُصلَح. هل سيكون من الممكن البدء بإصدار قديم هشّ، وتنفيذ الاستغلال الموصوف أعلاه، ثم ترقية البرنامج الثابت المُصلَح الجديد وتثبيته، وإطلاق الضيف باستخدام البرنامج الثابت الجديد (بحيث لا يظهر إصدار البرنامج الثابت القديم في تقرير الإثبات)؟ ثم استخدام صفحة CONTEXT التالفة التي أُنشئت باستخدام البرنامج الثابت القديم لمهاجمة الضيف الذي أُنشئ باستخدام الإصدار الجديد؟ هل سيكون بمقدور مستهلك تقارير الإثبات التي أنشأها الضيف الجديد معرفة أن إصدار البرنامج الثابت القديم كان يعمل في وقت ما قبل إطلاق الضيف الجديد؟ وإذا لم يكن الأمر كذلك، فهل ثمة تخفيفات إضافية مطلوبة لمنع حدوث ذلك؟

استخدام PoC

  1. طبّق التصحيحات الموجودة في مجلد linux-patches على آخر نسخة من https://github.com/AMDESE/linux/commits/snp-host-v10. ثم ابنِ النواة وثبّتها وشغّلها.

  2. شغّل الإثبات المفاهيمي (PoC).

    root@kitploit:~
    root@server:~/sev-exploit# cargo run --release
        Finished release [optimized] target(s) in 0.12s
        Running `target/release/sev-exploit`
    Corrupt guest context page so that ASID is in range 1..510
    Smallest ASID: 0x0000001f iterations: 14052175 zeros: 10539628 unique asids: 31500727 elapsed time: 1d 19h 20m 31s
    Creating VM with same ASID
    [03, 00, 00, 00, 00, 00, 00, 00, 11, 0f, a0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, f0, 51, a5, 03, 3f, 69, 6b, 93, e8, d8, 61, 0d, 2e, 5a, 45, f1, ea, 6d, bf, 49, fe, e4, a9, 2d, 8d, af, 76, 5e, 2e, 56, e0, fa, a9, b3, a7, e0, bc, 09, d9, 4f, 28, 5c, 9f, 84, d2, 7e, 34, eb, ea, 3f, 29, 88, 30, 01, 28, 65, 8b, 73, 3c, 84, 00, ae, 4a, 74, a2, 7a, d1, c7, 4f, 63, 7f, 72, 7b, 3b, 2f, 08, b3, 1a, 8c, 99, 1b, ad, b5, 1d, 42, 0b, 4d, 98, d4, 7d, c1, 0b, d6, 2f, b4, 6c, 6b, 51, a2, 92, 17, 3b, 01, e8, 82, 11, 1e, cb, cb, a2, 8f, c9, b0, 52, 1d, 1d, b7, d2, 25, 8d, 32, a9, 7a, 6f, 86, e4, 40, 44, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 80, 00, 88, 00, 00, 00, 00, ee, ff, 00, 00, f0, ff, ff, ff, ff, ff, ff, ff, ff, 3f, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, <cut off zeros>]
    thread 'main' panicked at src/main.rs:170:13:
    not yet implemented: use the leaked secrets to send guest messages
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

لاحظ أنه من الطبيعي أن يستغرق الاستغلال وقتاً طويلاً (في حدود الساعات إذا كنت محظوظاً، وأيام إذا لم تكن كذلك). التشغيل على معالج EPYC Genoa سيكون أسرع على الأرجح لأن عدد ASIDs الصالحة يبلغ ضعف العدد تقريباً.

خلال الخطوتين 5 و6 يعرض الإثبات المفاهيمي (PoC) بعض المقاييس:

  • "Smallest ASID": أصغر ASID تمت مصادفته حتى الآن. وهو مجرد مقياس تحقق سليم للتأكد من أننا نصادف ASIDs أصغر فأصغر مع مرور الوقت.
  • "iterations": يزداد هذا المقياس في كل مرة تُشغَّل فيها الثغرة.
  • "zeroes": في حوالي 1/4 من الحالات، تكون صفحة CONTEXT في حالة يعتبرها البرنامج الثابت غير معيّن لها ASID بعد. في تلك الحالات، سيرجع SNP_GUEST_STATUS القيمة 0 في حقل ASID.
  • "unique asids": مقياس تحقق سليم آخر للتأكد فقط من أن ASIDs عشوائية ولا تتكرر بعد فترة.
  • "elapsed time": المدة المنقضية منذ بدء تشغيل الإثبات المفاهيمي (PoC).

في معظم الحالات، يتسبب إلغاء تخصيص صفحات CONTEXT التالفة في تعطل البرنامج الثابت (على الأرجح هنا). وعلى حد علمي، يتسبب تعطل البرنامج الثابت في إعادة تشغيل النظام بأكمله. ولتجنب هذه الأعطال، تمنع تصحيحات النواة إلغاء تخصيص صفحات CONTEXT. ومن عيوب ذلك أن وحدة النواة ccp لا يمكن إلغاء تحميلها. وبمجرد بدء تشغيل الإثبات المفاهيمي (PoC)، يجب إعادة تشغيل النظام بالكامل قبل إمكانية تشغيله مرة أخرى (بغض النظر عما إذا نجح أم أُجهض).

تنزيل الأداة
  • إطلاق (وتشغيل اختياري) ضيف ضحية باستخدام ASID التالف في صفحة CONTEXT التالفة، مع تتبع صفحة الأسرار. هذا ممكن لأن البرنامج الثابت لـ SEV يتتبع ASIDs النشطة داخلياً ولا يفحص صفحات CONTEXT النشطة للتحقق من التكرار.
  • استخدام صفحة CONTEXT التالفة لتنفيذ SNP_DBG_DECRYPT على صفحة أسرار الضيف الضحية.