
مختبر 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 سير العمل بعدة طرق:
--exploit بشكل صريح.HOST:PORT، وبدائية قراءة الملفات معيارية من خلال --file-read-template./proc/self/status، /proc/self/maps، وإمكانية الوصول إلى procfs لعامل نفس UID.system()، ومعرفات البناء، وتجميعات الثنائيات، وتفاصيل نظام التشغيل، وإعدادات proc-mem/core من خلال البدائية البعيدة.rewrite + set الضعيفة المرشحة.nginx_rifter.py؛ الطريقة الافتراضية هي coreless proc-mem.النسخة الحالية من nginx_rifter.py قائمة بذاتها. لم تعد تستورد أو تستدعي إصدارات PoC التجريبية السابقة أو tools/proc_mem_coreless_exploit.py للتقييم أو الاستغلال.
تطبيق nginx_rifter.py القديم الموجه بـ core محفوظ كـ nginx_rifter_core_v2_1.py.
الملف الأحدث artifacts/nginx_rifter_v3_coreless_exploit_20260519.gif يُظهر مسار الاستغلال coreless لـ v3 المدمج في nginx_rifter.py. demo4.gif يُظهر تدفق التقييم والاستغلال الصريح من الأداة القديمة الموجهة بـ core. nginx-aslr-demo.gif القديم لا يزال كعرض توضيحي للاستغلال الأصلي مع ASLR.
تم اختباره على Ubuntu 24.04.3 LTS.
إعادة إنتاج Docker الأصلي مع ASLR معطل:
./setup.sh — بناء الحاوية.docker compose -f env/docker-compose.yml up — تشغيل خادم NGINX الضعيف.python3 poc.py --shell — الحصول على شل.للحصول على تدفق إعادة إنتاج Docker المحلي، انظر LAB.md.
سلسلة core-guided القديمة مع ASLR على VM:
./nginx_rifter_core_v2_1.py --target <target-host>:19321 --exploit --cmd id --fast
أداة v3 للتقييم أولاً:
./nginx_rifter.py --target <target-host>:19321
nginx_rifter.py هو المقيم الحالي الموجه للعالم الحقيقي ونقطة دخول PoC المدمجة. وضعه الافتراضي لا يشغل مسار الاستغلال المتسبب في العطل. يقوم بتوصيف بدائية قراءة الملفات عبر HTTP، ويفحص القراءات النطاقية والثنائية، ويأخذ بصمات OS/nginx/libc، ويكتشف عمال nginx والخرائط المتعلقة بـ ASLR، ويختبر قابلية قراءة /proc/<worker>/mem لنفس UID، ويحاول استعادة مسارات تكوين nginx من خلال قراءات pid/cmdline/config، ويضع علامات على مسارات rewrite + set الضعيفة المرشحة، ويطبع مصفوفة جدوى للسلسلة coreless الحالية.
النسخة الحالية من nginx_rifter.py قائمة بذاتها. لم تعد تستورد أو تستدعي إصدارات PoC التجريبية السابقة أو أداة البحث المستقلة proc-mem للتقييم أو الاستغلال.
لشكل LFI/تحميل مخصص:
./nginx_rifter.py --target <target-host>:19321 \
--file-read-template 'http://{host}:{port}/download?path={path_url}{range_query}'
تنفيذ الاستغلال صريح:
./nginx_rifter.py --target <target-host>:19321 --exploit --cmd id --fast
# Discovery-only exploit smoke test, no spray/probe
./nginx_rifter.py --target <target-host>:19321 --exploit --derive-only --cmd id
طريقة الاستغلال الافتراضية هي coreless proc-mem. الخيارات التالية محددة افتراضيًا لأنها كانت الأكثر موثوقية لإثبات coreless Docker:
--exploit-method proc-mem
--target-len 6
--max-region 268435456
وضع readable-core القديم لا يزال متاحًا للمقارنة، لكن السكريبت المحدد بالإصدار أوضح لإعادة إنتاج ذلك المسار القديم:
./nginx_rifter_core_v2_1.py --target <target-host>:19321 --exploit --cmd id --fast
عرض توضيحي قديم مناسب للتسجيل على الطرفية:
./demo_ctf_exploit_v1_9.py --host <target-host>:19321 --cmd id --clear
demo_ctf_exploit_v1_9.py هو المشغل القديم الموجه للمشغل لمسار المختبر core-guided. نقطة دخول PoC المفضلة حاليًا هي nginx_rifter.py.
بدائية قراءة الملفات الافتراضية هي مسار PHP في هذا الفرع:
/lfi.php?file=<path>&offset=<n>&length=<n>
لتطبيق CTF معروف الثغرات آخر أو منصة اختبار، يمكن تخصيص ناقل قراءة الملفات:
./nginx_rifter.py --target <target-host>:19321 --exploit --cmd id \
--target-profile generic \
--file-read-template 'http://{host}:{port}/download?path={path_url}{range_query}'
القالب يدعم {host} و{port} و{path_url} و{offset} و{length} و{range_query}. الملف الشخصي العام (generic) يتجاوز تأكيدات تكوين nginx الخاصة بهذا الفرع، لكن الاستغلال الافتراضي لا يزال يحتاج إلى نفس القدرات الأساسية: خرائط /proc قابلة للقراءة لعامل nginx، وlibc قابل للقراءة، و/proc/<worker>/mem قابل للقراءة. phpinfo() اختياري؛ استخدم --phpinfo-path '' لتعطيله.
ملاحظة واقعية: فئة ثغرات LFI/قراءة الملفات ونموذج النشر على نفس المضيف nginx/PHP-FPM واقعية. سلسلة proc-mem أكثر واقعية من سلسلة crash-core السابقة لأنها لا تتطلب تمكين أو قراءة ملفات قلب العمال. لا تزال ليست افتراضًا إنتاجيًا عالميًا: تخطيط العملية لنفس UID، وسياسة procfs/Yama، وإعدادات مساحة اسم الحاوية، وجودة بدائية قراءة الملفات تحدد ما إذا كان /proc/<worker>/mem قابلاً للوصول.
تحقيقات بحثية بدون LFI:
python3 tools/non_lfi_leak_probe.py --target <target-host>:19321
python3 tools/non_lfi_active_response_probe.py --target <target-host>:19321
هذه تحقيقات بحثية سلبية، وليست نقاط دخول للاستغلال. تمارس مصارف الانعكاس السلبي وشكل القراءة الزائدة للاستجابة المؤجلة الأولية دون استخدام LFI أو phpinfo أو procfs أو ملفات القلب أو الوصول إلى مصحح الأخطاء أو قواعد ASLR حية محددة مسبقًا.
ملاحظات مختبر إضافية وسجلات التشغيل موجودة تحت docs/، خاصة:
docs/CTF_PLAN.mddocs/CTF_FINDINGS.mddocs/CTF_TESTS.mddocs/CTF_EXPERIMENT_LOG.mddocs/DEMO_POC_IMPROVEMENTS.mddocs/KNOWN_LAYOUT_PATTERNS.mddocs/VAGRANT_ESXI.mddocs/CORELESS_ASLR_PLAN.mddocs/CORELESS_ASLR_FINDINGS.mddocs/NON_LFI_ASLR_BYPASS_LOG.mddocs/DEMO_RECORDING_WORKFLOW.md