
Fortbridge PoC خاص لسلسلة CVE-2026-32740 Next.js/sharp leak-to-memcpy-GOT RCE
إثبات مفهوم عملي يعمل على تحويل CVE-2026-32740 في
حزمة Next.js/sharp ذات الإصدارات المثبتة إلى كتابة على عنوان مختار واستدعاء
موثّق لـ /usr/bin/id.
هذا مستودع بحثي خاص بـ Fortbridge. استخدمه فقط ضد المختبر المضمّن أو أي نظام آخر مصرّح لك صراحةً باختباره.
يستخدم الاستغلال فقط مسارات رفع HTTP وتحسين الصور الخاصة بالهدف:
g_module_open_full من GLib، وهي روتين
GModule يغلّف dlopen لتحميل مكتبة مشتركة أصلية من مسار
ملف. يحسب الاستغلال عنوانه وقت التشغيل كقاعدة libvips المستردة
زائد إزاحة ملف التعريف المثبتة 0x3e995e. تحميل المكتبة يشغّل
البانية الخاصة بها./usr/bin/id. يرسل ذلك الملف ELF عبر مسار الرفع العام
تحت اسم الصورة x.jpg ونوع الوسائط image/jpeg.memcpy@GOT - 16.uploads/x.jpg مباشرة قبل
خانة GOT ويستبدل memcpy@GOT بمحمّل GModule المشتق. يستدعي الصف
التالي ذلك المحمّل مع مسار المكتبة الموجود بالفعل في RDI./usr/bin/id عبر TCP. تمنع رمزية لكل محاولة احتساب استدعاء قديم
كنجاح؛ سطر uid=... المُعاد هو الدليل.تُسجَّل عمليات التحقق الأصلية المرتبطة بـ libvips في
evidence/libvips-gmodule-rce-10x.json.
أعادت جميع العمليات العشر الجديدة مخرجات /usr/bin/id صالحة مع عشر قواعد
libvips عشوائية متمايزة وعشرة عناوين محمّل مشتقة بشكل مستقل.
توجد بيانات تشغيل Ubuntu الدقيقة في
evidence/libvips-gmodule-pie-rce-10x.json.
توجد بيانات تشغيل Debian 13 APT الدقيقة في
evidence/debian13-apt-libvips-gmodule-rce-10x.json.
اختبرنا الاستغلال الكامل ضد 10 عمليات Node على Ubuntu مُشغَّلة حديثًا
و10 عمليات Node على Debian مُشغَّلة حديثًا. وصلت جميع التشغيلات العشرين إلى تنفيذ
الأوامر وأعادت مخرجات /usr/bin/id الخاصة بالهدف. كما حسب الاستغلال
عنوان محمّل GModule مختلفًا لكل قاعدة libvips عشوائية.
قبل إنشاء الحمولة النهائية، قد يحتاج الاستغلال إلى عدة محاولات لتسريب ASLR. ترفع كل محاولة ملف AVIF للتسريب، وتمرّره عبر مسار التحسين، وتفحص ملف PNG المُعاد بحثًا عن أربعة مؤشرات تحدد ملف تعريف واحدًا وقاعدة libvips واحدة. احتاج Ubuntu ما بين 3 و23 محاولة. واحتاج Debian ما بين 3 و15. تؤدي الأدلة غير المكتملة أو الغامضة إلى محاولة أخرى بدلًا من تخمين ملف تعريف.
يحتوي المشروع أيضًا على 96 اختبار انحدار آلي. هذه فحوصات على مستوى الكود، وليست 96 تشغيلًا إضافيًا للاستغلال. وهي تغطي التحقق من ملفات التعريف، وتصنيف المؤشرات المُعادة، ومعايرة الكومة، وحساب العناوين، وبناء الحمولة، والفشل الآمن عندما لا تطابق الأدلة هدفًا مدعومًا.
يستخدم كلا هدفي x86-64 الإصدار Next.js 15.5.23، وsharp 0.34.4، وlibvips 8.17.2 المضمّن، وlibheif 1.20.2 المضمّن، وASLR، وNX. تختلف بيئات التشغيل الأصلية بينهما:
| ملف التعريف | Node | glibc | libstdc++ | علاقة المحدّد |
|---|---|---|---|---|
| Ubuntu | 25.8.1، PIE ET_DYN | 2.43-2ubuntu2.4 | 6.0.35 | 0x6000 - 0x690 = 0x5970 |
| Debian 13 | Debian APT 20.19.2، PIE ET_DYN | 2.41-12+deb13u4 | 6.0.33 | 0x6000 - 0x3a0 = 0x5c60 |
توجد معرّفات البناء الكاملة وقيم SHA-256 في
profiles/native_stack_profiles_pie.json.
تُسجَّل حزمة Debian، والمنتج، واختبار المسار، وقياسات التخطيط لخمس دورات حياة
في
evidence/debian13-profile-derivation.json.
يستخدم هدف Debian حزمة التوزيع القياسية
nodejs=20.19.2+dfsg-1+deb13u3؛ لم يتم ترجمة Node من المصدر.
لا تحتاج السلسلة إلى قاعدة Node العشوائية. هدف التحكم الخاص بها هو
الروتين الداخلي g_module_open_full داخل libvips، الذي تُسترد قاعدته العشوائية
من البكسلات المُعادة. يثبّت كل ملف تعريف مُصدَّر الثوابت الخاصة بالبناء
التي يتطلبها الاستغلال:
memcpy@GOT وإزاحة g_module_open_full بالإضافة إلى بايتات
التعليمات المتحققة الخاصة به؛لا تكون قاعدة libvips العشوائية، ولا عنوان المحمّل الناتج وقت التشغيل، ولا المحدّد النهائي المكوّن من بايتين مثبتة. بل تُشتق لكل عملية هدف من البكسلات المُعادة وملف التعريف المختار.
يفشل الاستغلال بشكل آمن عندما يكون ملف تعريف مشوّهًا أو عندما لا تحدد البكسلات المُعادة زوجًا واحدًا بالضبط من ملف تعريف/قاعدة مدعوم. يتطلب ملف التعريف الافتراضي أيضًا سجل الكومة المُعاد الكامل الخاص به. ملف التعريف هو ادعاء توافق دقيق، لذا ينبغي للمشغّل التحقق من منتجات الهدف دون اتصال قبل استخدامه.
واجهة المحمّل مهمة. يوفّر الاستدعاء المُستبدَل مسار المكتبة في RDI، ومؤشر صف الصورة في RSI، وطول النسخ البالغ 58 بايت في RDX. يستخدم روتين GModule المُعرَّف بدقة هذا فقط بتات الأعلام المدعومة من ESI ولا يفكّ مرجع RDX على مسار التحميل الناجح. تحقّق أداة اختبار دون اتصال من نقطة الدخول تلك وتوقيع التعليمات قبل استخدامها في التشغيلات المقاسة.
ffmpeg مع مُرمِّز libaom-av1cc على جهاز المهاجمثبّت الاعتماد الوحيد لـ Python:```bash python3 -m venv .venv . .venv/bin/activate python3 -m pip install -r requirements.txt
تأكيد دعم ترميز AV1:```bash
ffmpeg -hide_banner -encoders | grep libaom-av1
يقبل المختبر عن قصد أي ملفات مرفوعة ويمرر ملفات مختارة إلى sharp. لا تعرّضه لشبكة غير موثوقة.```bash cd lab npm ci npm run build npm run start
الهدف متاح بعد ذلك على `http://127.0.0.1:3000`.
لبناء صورة مختبر Ubuntu حول أثر Node المستخدم بواسطة ملف تعريف PIE
الأول:```bash
./scripts/build_ubuntu2604_container.sh
docker run --rm --network host \
fortbridge/libheif-grid-nextjs-rce:ubuntu2604
صورة Ubuntu 26.04 المقفلة بالبصمة تبني نسخة Node 25.8.1 PIE الدقيقة المسجلة في الملف التعريفي، وتتحقق من SHA-256 الخاص بها، ثم تنسخها إلى مرحلة تشغيل نظيفة. يُعد البناء من المصدر ضروريًا لأن ملف Node الثنائي الرسمي لنظام Linux هو ET_EXEC، بينما يختبر هذا الملف التعريفي عمدًا ملفًا تنفيذيًا من نوع PIE.
لإعادة إنتاج هدف Debian باستخدام حزمة APT المدعومة من Debian:```bash
./scripts/build_debian13_container.sh
docker run --rm --network host
fortbridge/libheif-grid-nextjs-rce:debian13
الصورة مبنية من قاعدة Debian 13 slim مقفلة ببصمة digest. npm موجود
فقط في مرحلة البناء؛ الهدف النهائي يثبّت Node من Debian APT ويشغّل
نفس التطبيق والمسارات.
## تشغيل الاستغلال