
إعادة إنتاج هجوم Retbleed (CVE-2022-29900/29901) المعماري الدقيق في gem5. تسريب RSB underflow وFlush+Reload عبر القناة الجانبية، وتخفيف lfence موثّق.
إعادة إنتاج عملية لـ Retbleed (CVE-2022-29900 / CVE-2022-29901) — الهجوم المعماري الدقيق لعام 2022 الذي كسر دفاع "Retpoline" من خلال إثبات أن تعليمات ret، التي كان يُفترض منذ فترة طويلة أنها آمنة، يمكن اختطافها عندما يحدث underflow في Return Stack Buffer (RSB) الخاص بالمعالج.
يحاكي هذا المشروع دورة حياة الهجوم الكاملة على نموذج معالج x86 Out-of-Order في gem5: إطلاق RSB underflow، وتسريب البيانات السرية بايتًا واحدًا في كل مرة عبر قناة جانبية للذاكرة المؤقتة Flush+Reload، ثم التحقق من تخفيف برمجي (lfence) يغلق التسريب.
مشروع مقرر دراسي — Advanced Computer Architecture، خريف 2025، CUNY City College المؤلفان: Abdul Kalam Mansoor و Rebiha Selmani
أظهرت هجمات بنمط Spectre أن التنفيذ التخميني يترك آثارًا جانبية على مستوى الذاكرة المؤقتة حتى عندما "يتراجع" المعالج عن تخمين خاطئ. كان حل الصناعة — Retpoline — يستبدل القفزات غير المباشرة الخطيرة بتعليمات ret، على افتراض أن المرتجعات يتم التنبؤ بها بأمان من مكدس عتادي صغير (RSB). أظهر Retbleed أن هذا الافتراض خاطئ: استنزف RSB عبر استدعاء عودي عميق، وسيتراجع المعالج بصمت إلى نفس المتنبئ غير الآمن الذي صُمم Retpoline لتجنبه.
| المرحلة | ما يحدث |
|---|---|
| 1. Trigger | تستدعي rsb_deep_call() نفسها بشكل عودي بعمق 32 مستوى، مما يفيض عن RSB ذي 16 مدخلًا. عند فك الاستدعاء العودي، يصبح RSB فارغًا. |
| 2. Fallback | مع فراغ RSB، يتراجع المعالج إلى Branch Target Buffer (BTB) للتنبؤ بهدف ret — وهو ما يمكن للمهاجم تسميمه. |
| 3. Gadget | ينفذ المسار التخميني المختطف gadget()، الذي يقرأ بايتًا من كلمة المرور السرية ويستخدمه للفهرسة داخل probe_array، مما يسحب صفحة واحدة من تلك المصفوفة إلى الذاكرة المؤقتة. |
| 4. Flush+Reload spy | قبل الهجوم، يتم تفريغ كل صفحة من probe_array من الذاكرة المؤقتة (_mm_clflush). بعد إغلاق النافذة التخمينية، يقيس البرنامج زمن الوصول إلى كل قيمة بايت محتملة (__rdtscp) — والقيمة التي تعود بسرعة (cache hit) تكشف البايت السري. |
تكرار ذلك لكل بايت من ROOT_PASSWORD يعيد بناء السر بالكامل دون استدعاء gadget() معماريًا أبدًا.
| الوضع | زمن الوصول | النتيجة |
|---|---|---|
Vulnerable (SECURE_MODE غير معرّف) | ~49 دورة (cache hit) | تسريب السر بايتًا بايتًا، مؤكد بمؤشرات HIT! الحمراء |
Patched (SECURE_MODE معرّف، مع حقن _mm_lfence()) | >150 دورة (cache miss / ضوضاء) | فشل الهجوم — يُظهر الخرج SAFE / Found: ??? |
يجبر lfence المعالج على حل عنوان الإرجاع قبل أن تُنفَّذ أي تعليمة لاحقة، مما يطوي النافذة التخمينية قبل أن يلمس gadget أي ذاكرة تعتمد على السر.
src/
retbleed.c # Full PoC: trigger, gadget, Flush+Reload spy, and lfence mitigation (toggle via SECURE_MODE)
docs/
Retbleed_Report.pdf # Full written report: methodology, related work, gem5 setup, results
Retbleed_Attack_Demonstration.pptx # Slide deck used to present the project
تم بناء PoC وقياسه تحت gem5 (DerivO3CPU، وهو نموذج out-of-order — مطلوب لأن النماذج in-order لا تنفذ التنفيذ التخميني):
gcc -O0 -static -o retbleed src/retbleed.c
./build/X86/gem5.opt configs/deprecated/example/se.py \
--cpu-type=DerivO3CPU --caches --l2cache \
--l1d_size=64kB --l1i_size=64kB --cmd=retbleed
للتبديل بين السلوك المعرّض للثغرة والمُرقَّع، علّق/أزل التعليق عن هذا السطر في أعلى retbleed.c:
#define SECURE_MODE
يستخدم الكود intrinsics حقيقية لـ x86 (
_mm_clflush،__rdtscp،_mm_lfence) ويمكن أيضًا تجميعه وتشغيله أصليًا على عتاد x86 (gcc -O0 -o retbleed src/retbleed.c) للحصول على عرض أسرع — وستختلف النتائج حسب تخفيفات المعالج المضيف نفسه (eIBRS، تصحيحات microcode، إلخ)، وهو بحد ذاته توضيح مفيد لمدى شمولية ترقيع هذه الفئة من الأخطاء منذ 2022.
lfence إضافية) قيست بتكلفة أداء 14–39% على العتاد المتأثر.