
مختبر Docker محلي لإعادة إنتاج CVE-2026-3844، رفع ملف تعسفي غير مصادق عليه إلى RCE في إضافة WordPress Breeze Cache. يقارن الإصدار الضعيف 2.4.4 مع الإصدار المصحح 2.4.5 باستخدام خدمات معزولة و PoC بأقل ضرر.
مختبر Docker محلي فقط لإعادة إنتاج ومقارنة سلوك CVE-2026-3844 في إضافة Breeze Cache الخاصة بووردبريس.
يوضح هذا المستودع السلوك القابل للاستغلال في Breeze Cache 2.4.4 ويقارنه بالسلوك المُصحح في Breeze Cache 2.4.5. يستخدم المختبر خدمتي ووردبريس معزولتين، إحداهما قابلة للاستغلال والأخرى مُصححة، بالإضافة إلى خادم حمولة محلي داخل شبكة Docker.
إثبات المفهوم (PoC) مُصمم ليكون بالحد الأدنى من الضرر: فهو لا يستخدم ويب شيل، ولا يعرض معامل أوامر، ولا يبدأ قشرة عكسية (reverse shell)، ولا يتطلب قراءة ملفات من داخل الحاوية. يعتمد الإثبات على سلوك HTTP قابل للملاحظة من المضيف.
تؤثر ثغرة CVE-2026-3844 على إضافة Breeze Cache لووردبريس حتى الإصدار 2.4.4 وما قبله. مسار الكود القابل للاستغلال مرتبط بميزة التخزين المحلي لصور Gravatar في الإضافة، وتحديدًا تدفق fetch_gravatar_from_remote().
عند تفعيل خيار Host Files Locally - Gravatars في Breeze، يمكن للإصدارات القابلة للاستغلال جلب ملف عن بُعد يتحكم فيه المهاجم وتخزينه تحت دليل ذاكرة تخزين مؤقت عام يمكن الوصول إليه عبر الويب. إذا كان الملف الذي تم جلبه هو PHP، فقد ينفَّذ الملف بواسطة خادم الويب عند طلبه عبر HTTP.
يعيد هذا المختبر إنتاج ذلك السلوك محليًا:
vuln: ووردبريس + Breeze Cache 2.4.4patched: ووردبريس + Breeze Cache 2.4.5payload: خادم حمولة محلي داخل Docker فقطsrcset مُتحكم بهاالنتيجة المتوقعة هي:
http://127.0.0.1:8081 / Breeze 2.4.4 → ملف PHP الإثباتي يتم تخزينه مؤقتًا وتنفيذهhttp://127.0.0.1:8082 / Breeze 2.4.5 → ملف PHP الإثباتي لا يتم تخزينه مؤقتًا/قراءته/تنفيذه.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── scripts/
│ └── seed-wordpress.sh
├── payload/
│ └── manual-proof.php
│ └── proof-cve3844.php
├── poc/
│ └── poc.py
│ └── requirements.txt
├── .gitignore
├── README.md
Host machine
│
├── http://127.0.0.1:8081 -> vuln WordPress + Breeze 2.4.4
├── http://127.0.0.1:8082 -> patched WordPress + Breeze 2.4.5
└── http://127.0.0.1:9100 -> local payload server
Docker network
│
├── vuln -> WordPress vulnerable target
├── patched -> WordPress patched target
├── vuln_db -> MariaDB for vulnerable WordPress
├── patched_db -> MariaDB for patched WordPress
└── payload -> Python static HTTP server
تتواصل حاويات ووردبريس مع الحمولة عبر عنوان شبكة Docker:
http://payload:9100/<payload-file>.php
يتحقق المضيف من النتيجة عبر طلبات HTTP عادية إلى خدمات ووردبريس.
2.4.42.4.5fetch_gravatar_from_remote()inc/class-breeze-cache-cronjobs.phpbreeze-store-gravatars-locallyلا يمكن الوصول إلى السلوك القابل للاستغلال إلا عند تفعيل التخزين المحلي لـ Gravatar. هذا الخيار معطَّل افتراضيًا في التثبيتات النموذجية، لكن هذا المختبر يفعّله عمدًا لإعادة إنتاج مسار الكود القابل للاستغلال.
في Breeze Cache 2.4.4، يمكن لتدفق توطين Gravatar استخراج عنوان URL بعيد من HTML مرتبط بالصور الرمزية وتمريره إلى fetch_gravatar_from_remote().
يفتقر الإصدار القابل للاستغلال إلى التحقق الكافي حول الملف البعيد:
.phpيُخزَّن الملف الناتج تحت:
/wp-content/cache/breeze-extra/gravatars/
عند حفظ ملف PHP هناك ثم طلبه عبر Apache/PHP، ينفذه الخادم.
في Breeze Cache 2.4.5، يضيف التدفق المُصحح تحققًا يمنع تخزين حمولة هذا المختبر كملف PHP قابل للتنفيذ. في إعادة الإنتاج المحلية، يعمل المحفّز نفسه ضد 2.4.4 لكنه لا يُظهر علامة الإثبات ضد 2.4.5.
يبقي هذا المختبر خادم الحمولة محليًا عمدًا بدلاً من استخدام مضيف حمولة عام.
ترفض download_url() الخاصة بووردبريس وواجهة HTTP API الخاصة بووردبريس بعض أسماء مضيفات Docker الخاصة والمنافذ غير القياسية افتراضيًا. غالبًا ما تستخدم سكربتات الاستغلال العامة عناوين حمولة HTTPS عامة، مما يتجنب ذلك القيد. هذا المختبر لا يفعل ذلك.
لإبقاء إعادة الإنتاج محلية بالكامل، يثبّت سكربت البذر (seed) مساعد MU plugin محليًا صغيرًا يقوم بما يلي:
payload و payload.local80 و 9100لا يقوم هذا المساعد بتعديل الكود المصدري لـ Breeze. تستخدم كل من الخدمة القابلة للاستغلال والمُصححة إصدارات حقيقية من إضافة Breeze مثبتة عبر WP-CLI.
المساعد موجود فقط لجعل مختبر Docker حتميًا ومحليًا فقط.
هذا المستودع مخصص للبحث الأمني المحلي وعرض الأعمال فقط.
ضوابط السلامة:
localhost وخدمات شبكة Dockercmd=تطبع حمولة إثبات المفهوم معلومات وقت تشغيل PHP غير ضارة:
CVE-2026-3844_LEAST_HARM_PHP_EXEC_PROOF_<nonce>
php_sapi=apache2handler
user=www-data
uid=33
pid=<process id>
host=<container hostname>
يُثبت ذلك سياق تنفيذ الكود دون تشغيل أوامر قشرة.
requestsتثبيت تبعية Python:
python3 -m venv .venv
source .venv/bin/activate
pip install -r poc/requirements.txt
يجب أن يحتوي requirements.txt على:
requests
بناء المختبر وتشغيله:
docker compose down -v --remove-orphans
docker compose up -d --build
فحص حالة الخدمات:
docker compose ps
الخدمات المتوقعة:
vuln healthy http://127.0.0.1:8081
patched healthy http://127.0.0.1:8082
payload running http://127.0.0.1:9100
vuln_db healthy
patched_db healthy
فحص سجلات البذر:
docker compose logs --tail=120 vuln
docker compose logs --tail=120 patched
أسطر السجل المتوقعة:
[seed] WordPress ready at http://localhost:8081 with Breeze 2.4.4
[seed] WordPress ready at http://localhost:8082 with Breeze 2.4.5
التحقق من تثبيت ووردبريس:
docker compose exec vuln wp core is-installed --allow-root --path=/var/www/html
docker compose exec patched wp core is-installed --allow-root --path=/var/www/html
التحقق من إصدارات Breeze:
docker compose exec vuln wp plugin get breeze --field=version --allow-root --path=/var/www/html
docker compose exec patched wp plugin get breeze --field=version --allow-root --path=/var/www/html
المتوقع:
2.4.4
2.4.5
التحقق من الشرط المسبق للثغرة:
docker compose exec vuln wp option pluck breeze_advanced_settings breeze-store-gravatars-locally --allow-root --path=/var/www/html
docker compose exec patched wp option pluck breeze_advanced_settings breeze-store-gravatars-locally --allow-root --path=/var/www/html
المتوقع:
1
1
التحقق من أن ووردبريس يمكنه جلب خدمة الحمولة المحلية:
docker compose exec vuln wp eval '
$r = download_url("http://payload:9100/proof-cve3844.php");
if (is_wp_error($r)) { var_dump($r->get_error_message()); exit; }
echo $r . PHP_EOL;
echo file_get_contents($r);
@unlink($r);
' --allow-root --path=/var/www/html
إذا لم يكن proof-cve3844.php موجودًا بعد، أنشئ أي ملف مؤقت في payload/ أو شغّل إثبات المفهوم مرة واحدة.
التشغيل ضد الخدمة القابلة للاستغلال:
python3 poc/poc.py --base-url http://127.0.0.1:8081
النتيجة المتوقعة للنظام القابل للاستغلال: