مختبر Nginx Rift ASLR الخاص، سلسلة الاستغلال، وتسجيلات العرض التوضيحي
دليل إثبات للمفهوم لـ CVE-2026-42945، وهو تجاوز سعة مخزن مؤقت في كومة الذاكرة في وحدة ngx_http_rewrite_module من NGINX تم تقديمه في 2008. يتيح الخلل تنفيذ برنامج عن بعد غير مصدق ضد الخوادم التي تستخدم توجيهات rewrite و set.
هذا الفرع يوسع الـ PoC الأصلي بسلسلة تجاوز لـ ASLR تجمع بين تجاوز NGINX وبدائية شائعة لقراءة الملفات من نفس المضيف (LFI/arbitrary-file-read). تُستخدم بدائية قراءة الملفات لاستعادة خرائط عمال nginx و libc و /proc/<worker>/mem الحية، ثم اشتقاق عنوان system() وأهداف كومة قابلة للاستخدام عن بعد.
الإصدارات السابقة من هذا المختبر كانت تتسبب عمدًا في تعطل عامل nginx لجعل الخدمة تكتب ملف قلب (core dump)، ثم تجلب وتفسر هذا الملف عبر بدائية قراءة الملفات لاستعادة حالة العملية الحساسة لـ ASLR، بما في ذلك أهداف الكومة. في هذا المستودع، coreless هي اختصار فقط لـ "بدون ملف قلب قابل للقراءة": المسار الافتراضي الحالي يستبدل هذا الاعتماد على ملف القلب بقراءات حية لذاكرة procfs، بينما المسار القديم المحفوظ core-guided لا يزال يستخدم ملف القلب المولد للعامل.
تم اكتشاف هذه الثغرة - إلى جانب ثلاث مشاكل أخرى لفساد الذاكرة (CVE-2026-42946, CVE-2026-40701, CVE-2026-42934) - بشكل مستقل بواسطة نظام التحليل الأمني لـ depthfirst بعد نقرة واحدة لبدء تحليل كود NGINX.
هل تريد العثور على مشاكل كهذه في الكود الخاص بك؟ جرب نفس النظام على https://depthfirst.com/open-defense.
محرك البرامج النصية لـ NGINX يستخدم عملية من مرحلتين: أولاً حساب حجم المخزن المؤقت المطلوب، ثم نسخ البيانات. يتم تعيين علامة is_args على المحرك الرئيسي عندما يحتوي استبدال rewrite على ?، ولكن مرحلة حساب الطول تعمل على محرك فرعي جديد معاد ضبطه. لذلك:
is_args = 0 → تُرجع طول الالتقاط الخام.is_args = 1 → تستدعي ngx_escape_uri مع NGX_ESCAPE_ARGS، مما يوسع كل بايت قابل للتهريب إلى 3 بايتات.ينسخ البيانات الزائدة عن الحجم إلى المخزن المؤقت للكومة الصغير جدًا مع بيانات URI يتحكم بها المهاجم. يستخدم الاستغلال فن فنغ شوي للكومة عبر الطلبات لإفساد مؤشر cleanup لـ ngx_pool_t المجاور (يتم رشه عبر أجسام POST، لأن بايتات URI لا يمكنها احتواء بايتات صفرية)، وإعادة توجيهه إلى ngx_pool_cleanup_s مزيف يستدعي system() عند تدمير التجمع.
اقرأ المزيد عن هذا الخلل في مقالنا التقني.
| المنتج | المتأثر | المصحح في |
|---|---|---|
| NGINX Open Source | 0.6.27 – 1.30.0 | 1.31.0, 1.30.1 |
| NGINX Plus | R32 – R36 | R36 P4, R35 P2, R32 P6 |
الإعلان الكامل من البائع: https://my.f5.com/manage/s/article/K000160932



يحافظ هذا الفرع على PoC الإفصاح الأصلي سليمة، ولكنه يضيف مسار بحث ثانٍ يركز على سؤال أكثر واقعية:
هل يمكن استغلال الخلل ضد آلة افتراضية حقيقية x86_64 تعمل بنظام Linux مع ASLR مفعل، دون الاعتماد على إزاحات Docker/مختبر محددة مسبقًا؟
الإجابة في هذا الفرع البحثي هي نعم، مع قيود مهمة. السلاسل العاملة لا تعطل ASLR ولا تستخدم عناوين الكومة/libc المحددة مسبقًا. بدلاً من ذلك، تستمد حالة التشغيل من خلال بدائيات يمكن الوصول إليها عبر HTTP على نفس المنفذ، ثم تختار هدف الكومة النهائي من بيانات الإفصاح التي تم الحصول عليها عن بعد.
يوجد الآن مساران للاستغلال مع ASLR، حيث يُعتبر مسار coreless أفضل PoC حاليًا:
nginx_rifter.py: نقطة الدخول النظيفة والمتكاملة للتقييم والاستغلال. طريقة الاستغلال الافتراضية الآن هي سلسلة coreless /proc/<nginx-worker>/mem.nginx_rifter_core_v2_1.py: النسخة القديمة المحفوظة الموجهة من nginx_rifter.py باستخدام core. مفيدة لإعادة إنتاج مسار البحث القديم الذي تم اختباره على VM، لكنها لم تعد PoC المفضلة.tools/proc_mem_coreless_exploit.py: أداة البحث المستقلة السابقة لـ coreless. تم دمج منطقها في nginx_rifter.py؛ تبقى الأداة لإعادة تشغيل التجارب الخام.طوبولوجيا الهدف هي بشكل متعمد على نفس المنفذ:
/api/.../lfi.php?file=.../phpinfo.phpمسار proc-mem coreless الحالي يؤدي الخطوات التالية عالية المستوى:
/proc/<pid>/maps لعامل nginx، وملف libc المعين.system() المطلق لذلك العامل./proc/<worker>/mem من خلال بدائية قراءة الملفات.مسار core-guided القديم يؤدي اشتقاق عنوان أساسي مماثل، ثم يتسبب عمدًا في تعطل عامل، ويقرأ ملف القلب المولد عبر LFI، ويستخرج من ذلك القلب فتحات التنظيف المزيفة الموزعة. كان ذلك جسرًا بحثيًا مفيدًا، لكنه يعتمد على سياسة ملفات القلب وأذونات نظام الملفات الأقل شيوعًا في التوزيعات الافتراضية.
هذا ليس هو نفسه العرض التوضيحي الأصلي لـ Docker الحتمي. مسار VM x86_64 يترك ASLR العادي لـ Linux مفعلًا ويعيد حساب العناوين الخاصة بالعملية في كل تشغيل. مسار Docker coreless أيضًا يترك ASLR مفعلًا ويزيل شرط ملف القلب القابل للقراءة غير المعتاد، لكنه يعتمد على سلوك أذونات procfs الذي يجب التحقق منه لفئة الهدف.
هذا الفرع هو مختبر بحثي خاضع للرقابة. تعتمد سلاسل ASLR على شروط قوية ليست افتراضات إنتاجية عالمية:
/proc/<pid>/maps لنفس UID، وlibc المعين، و/proc/<pid>/mem في إزاحات معينة كبيرة./proc/<pid>/maps لنفس UID، وlibc المعين، وملف القلب المولد للعامل.phpinfo() و/proc/<pid>/maps كافيان لاستعادة العناوين الأساسية لـ PIE/libc، لكنهما ليسا كافيين بمفردهما لاستعادة كائن/نافذة الكومة الدقيقة المطلوبة لهذا الاستغلال. السلسلة القديمة استخدمت ملف قلب قابل للقراءة لهذا الإفصاح النهائي. السلسلة الافتراضية الحالية تستخدم /proc/<worker>/mem بدلاً من ذلك، وهو أقرب إلى نتيجة قراءة ملفات عشوائية حقيقية في توزيعات نفس UID لأنه يكشف ذاكرة العامل الحية دون تغيير سياسة ملفات القلب.
قيود مهمة متبقية:
/proc/<pid>/mem محمي بـ ptrace. عمل في مختبر Docker وفي فحص نفس UID ضد نموذج الصورة الرسمي nginx:stable، لكن عمليات التطبيقات ذات UID مختلف يجب أن تفشل تحت حماية procfs الافتراضية.نقطة الدخول النظيفة الحالية هي nginx_rifter.py، أداة تقييم أولاً تهدف إلى أن تكون أقرب إلى كيفية تقييم المختبر المرخص لنشر nginx معروف الثغرات مع بدائية قراءة ملفات محلية يمكن الوصول إليها عبر HTTP.
مقارنة مع المشغل التجريبي الأولي، يحسن nginx_rifter.py سير العمل بعدة طرق: