
CVE-2026-111497 إثبات مفهوم لتنفيذ التعليمات عن بُعد (RCE) لصورة Docker Official Image واحدة مثبّتة لـ WordPress
هذا الـ PoC المعتمد على المصدر فقط يعيد إنتاج تنفيذ أوامر دون مصادقة ضد صورة Docker Official Image واحدة مثبّتة لـ WordPress.
طلب pingback.ping واحد يجعل WordPress يجلب عنوان URL يتحكم به المهاجم مرتين خلال طلب PHP نفسه. الاستجابة الأولى تُفسد معالج PHP عبر Brotli. ترويسة إعادة المحاولة تُشغّل Bash وتُعيد علم المختبر.
الملف الشخصي (profile) خاص بالهدف. لا يقدّم أي ادعاء بشأن صور WordPress الحالية، أو بصمات (digests) أخرى، أو خطأ في الذاكرة داخل WordPress Core.
تحذير: شغّل هذا الـ PoC فقط داخل المختبر المرفق وعلى نظام تملكه. يحتوي على حمولة RCE فعّالة.
/flag.txt جديدًا، ويُعاد العلم في استجابة XML-RPC.sh إلى bash إلى sleep.| العنصر | القيمة |
|---|---|
| الهدف | docker.io/library/wordpress@sha256:806680ba62232c4c300fb9dcc9f89d08e9e8c2bfc59837a1f58716f8648306d5 |
| معرّف الصورة | c64dd89c00079939f18d70489e7c3e30cb071e8581824ab2de688f9f4d70d076 |
| المنصة | Linux amd64، Debian 13.7 |
| التطبيق | WordPress 7.1.3، Apache 2.4.69 prefork |
| بيئة التشغيل | PHP 8.3.36 NTS |
| فاكّ الترميز | libbrotli1:amd64 1.1.0-2+b7 |
اختيرت وثيقة تعريف (manifest) Linux/amd64 هذه بواسطة wordpress:latest عند النشر. لم تعد وسمة latest الحالية تختارها.
يشغّل المختبر صورة Docker Official Image هذه دون تعديل باستخدام Podman بلا جذر (rootless). لا يحقن مكتبة Brotli.
توفّر CVE-2026-111497 إفساد فاكّ الترميز. ويوفّر WordPress مسار الجلب دون مصادقة عبر pingback.ping.
ينسخ التدفق المشوّه ستة بايتات من مؤشر معالج system الحيّ إلى معالج strtolower. يستخدم كلا المؤشرين نفس قاعدة libphp.so المحمّلة عبر ASLR. لذلك، لا يحتاج الملف الشخصي إلى تسريب عنوان مطلق.
لا يزال الملف الشخصي يعتمد على الإصدارات الدقيقة من Brotli وPHP وglibc وcURL وRequests وApache والمُخصِّص وسجل الطلبات. تستخدم الاستجابة الأولى ترويسة بحجم 161 بايت وجسمًا بحجم 23,069,816 بايت. يرسل المصدر 23,069,752 بايت، وينتظر ثانية واحدة، ثم يرسل الـ 64 بايت الأخيرة.
يُعيد فاكّ الترميز خطأً بعد الإفساد. تُعيد Requests المحاولة دون فك ترميز المحتوى بعد CURLE_BAD_CONTENT_ENCODING. يصل أول اسم ترويسة إلى المعالج المعدّل ويشغّل أمر Bash الثابت.
يتطلب مسار التطبيق هذه الشروط:
/xmlrpc.php قابلًا للوصول، ويكون pingback.ping مُفعّلًا.ينشئ المختبر هذه الشروط دون إضافة أو أدوات قياس على جانب الضحية.
generate_payloads.py هو المصدر الموثوق للحُمولات. لا يتتبع المستودع أي ملفات حُمولات ثنائية مبنية مسبقًا.
يستخدم المولّد مكتبة Python القياسية فقط. يعمل دون اتصال ولا يرسل حركة مرور أو ينفّذ أوامر. يحدّد ثوابت الملف الشخصي ومراحل التسلسل وفقًا لـ RFC 7932.
يعيد verify.sh توليد جميع الأجزاء (fragments). يتحقق من أحجامها وتجزئاتها وإزاحات البتات الوسيطة وعلاقة المحدد ذي البت الواحد.
استخدم المضيف المُختبَر Ubuntu 24.04.4 تحت WSL2 على amd64. واستخدم Podman 4.9.3 بلا جذر، وBash 5.2.21، وPython 3.12.3.
الحد الأدنى من المتطلبات هو Linux amd64، وPodman بلا جذر، وBash، وPython 3.8 أو أحدث، ووضع ASLR رقم 2، وأدوات GNU القياسية للمستخدم. أبقِ المنفذ 18170 والشبكة الفرعية 93.184.218.0/24 متاحين، أو اختر بدائل. قد يرفض مضيف SELinux في وضع الإنفاذ (enforcing) عمليات bind mounts.
قبل تشغيل المختبر، اسحب الصور غير القابلة للتغيير:
podman pull docker.io/library/wordpress@sha256:806680ba62232c4c300fb9dcc9f89d08e9e8c2bfc59837a1f58716f8648306d5
podman pull docker.io/library/wordpress@sha256:65d5f185a6f539803a177ea9cdd5ad632ae24427bea114447e67a6fcd5d8bfe8
podman pull docker.io/library/mariadb@sha256:33a6653ab666774f48818120045f9367a81cd4c54c027412fe294a7d1274e2dc
اجعل السكربتات قابلة للتنفيذ، ثم تحقق من حزمة المصدر:
chmod +x generate_payloads.py verify.sh run.sh
./verify.sh
شغّل كل وضع بوسم جديد:
| الوضع | الأمر | النتيجة المطلوبة |
|---|---|---|
| إيجابي | ./run.sh standard | يعيد العَلَم ويطبع PoC positive: |
| قابل للملاحظة | ./run.sh observable | يسجّل أيضًا عمليات bash وsleep المرئية |
| المحدِّد | ./run.sh selector | يعيد المحاولة لكن يُبقي العَلَم خارج الاستجابة |
يغيّر المحدِّد بتة واحدة عند إزاحة البايت 1066. وهو ضابط سببي على الصورة نفسها، وليس ضابطًا لمُفكِّك ترميز ثابت.
الوسائط الاختيارية هي الوضع، والوسم، ومنفذ المضيف، والثُماني الثالث للشبكة:
./run.sh standard trial2 18171 219
يكتب المشغّل الأدلة إلى runs/<tag>/. الملفات الرئيسية هي:
VERDICT.txt: النتيجة وأعداد الطلباتclient-request.raw وclient-response.raw: بيانات الاتصال الواردةorigin-evidence/origin-events.json: كلا الطلبين الصادرين وترويسات إعادة المحاولةoracle-match.txt: مطابقة العلامة في الاستجابةpayloads/identity.json: بيانات التعريف المولّدة للملف الشخصيMANIFEST.sha256: تجزئات جميع ملفات الأدلةيستخدم المشغّل شبكة Podman داخلية وينشر WordPress فقط على 127.0.0.1. لا يقبل العميل أي عنوان هدف. لا يقبل الأصل أي إدخال أوامر. يقرأ الأمر الثابت العلامة الاصطناعية فقط.
يزيل المشغّل قيمة العلامة من بيئة Apache قبل بدء Apache. كما ينشئ بيانات اعتماد جديدة ويزيل فقط الموارد الخاصة بالتشغيل الحالي.
تقسيم الاستجابة وسجل العمليات هما مدخلات الاستغلال. إذا فشل تشغيل، أعد الملف الشخصي دون تغيير باستخدام وسم جديد. لا تضبط العناوين أو بايتات الحمولة بعد تشغيل فاشل.
لا تثبت هذه الحزمة قابلية النقل عبر ملخصات الصور (image digests) أو إصدارات بناء PHP أو المعماريات أو المخصصات (allocators) أو جداول الاستجابة. قد يوقف هدف مختلف التنفيذ أو يسبب مجرد انهيار.
أصلح المشروع الأصلي (upstream) فروع Brotli المدعومة في 1.0.10 و1.1.1 و1.2.1. يمكن لمورّدي التوزيعات نقل الإصلاح (backport). استخدم إرشادات المورّد وسجل تغييرات الحزمة، وليس الإصدار المعروض فقط.