
Apache OpenMeetings 9.1.0 - مرتفع - عن بُعد - IDOR - حفظ تقويم تسجيل الدخول يستبدل الموعد ويغلق الغرفة العامة
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · openmeetings-calendar-save-idor
الفئة: IDOR الوصول: عن بُعد
Apache OpenMeetings 9.1.0 (9773c59e) - Apache Software Foundation
يمكن لأي مستخدم LOGIN إرسال POST /services/calendar/ مع معرّف موعد (appointment) يعود لشخص آخر مع حذف owner. فحوى التحقق في عملية الحفظ (save predicate) لا يقوم بتحميل المالك المخزَّن مطلقًا. بعد ذلك يقوم CalendarMapper ثم RoomMapper بكتابة closed / ispublic / name على الغرفة المرتبطة. وبذلك يستطيع مستخدم مسجَّل أن يستبدل اجتماع شخص آخر ويغلق غرفة مؤتمرات عامة.
| المعرّف | لا يوجد CVE بعد |
| الفئة | IDOR |
| الوصول | عن بُعد (LOGIN REST موثَّق) |
| CWE | CWE-639، CWE-284 |
| CVSS | مرتفع: 7.6 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:L |
| المنتج | Apache OpenMeetings |
| المتأثر | 9.1.0 (9773c59e1af327bf988018e661f456ae9997c29f) |
| المصادقة | LOGIN (التسجيل الذاتي الافتراضي يمنح هذه الصلاحية) |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1:18150 فقط. apache/openmeetings:min-9.1.0 مع Temurin 21. |
ثبَّتُ الوسم 9.1.0، وأزلتُ الطبقة 9773c59e1af327bf988018e661f456ae9997c29f (2026-07-14). أحدث إصدار GA. Java 21. ليس master.
سجِّل (المعالج allowFrontendRegister=true) أو احصل على أي كلمة مرور LOGIN. يُصدر POST /openmeetings/services/user/login معرّف جلسة SID. معرّفات المواعيد متسلسلة. معرّف الغرفة العامة 2 هو غرفة المؤتمرات الافتراضية.
| الطريقة | نقطة الوصول | الصلاحية |
|---|---|---|
POST /services/calendar/?sid= نموذج appointment JSON، مع حذف owner، وid الضحية | فحوى CalendarWebService.save (CalendarWebService.java:310-329) | السلامة (مُثبتة مختبريًا): استبدال العنوان والأوقات والأعضاء. المختبر: أصبح العنوان OPENMEETINGS-CALENDAR-SAVE-WITNESS، والمالك 2→3. |
نفس عملية الحفظ؛ room.closed=true | RoomMapper.get يكتب على الكيان المُدار (RoomMapper.java:62-92) ثم dao.update | السلامة + التوافر (مُثبتة مختبريًا): غرفة المؤتمرات العامة أصبحت closed=true وisPublic=false بشكل دائم. أعاد SOAP GET /room/2 ذلك. |
GET المهاجم للعنوان/النطاق بعد الحفظ | DTO الاستجابة هو الصف بعد الكتابة | الاستطلاع (مُثبت مختبريًا): عنوان الشاهد. نطاق الضحية فارغ بعد سرقة الملكية. |
مُثبت مختبريًا مقابل مُستنتج: استجابة الحفظ HTTP 200، والعنوان، وسرقة الملكية، وإغلاق الغرفة كلها مختبريًا. بتات السعة / الإشراف على نفس الـ mapper مُستنتجة.
يتطلب: مسار شبكي إلى /openmeetings/services. حساب LOGIN. معرّف موعد ضحية (متسلسل، أو أنشئ واحدًا وانتظر). التسجيل المفتوح الافتراضي.
| السطح | السبب |
|---|---|
DELETE /calendar/{id} | المالك أو SOAP/ADMIN. لا يستطيع LOGIN العادي حذف مواعيد الآخرين. |
| قراءات النطاق / التالي / العنوان | مقيَّدة بالمالك. لا يحصل المهاجم على قراءة نظيفة للصف الأصلي. |
| تسجيل MP4 | قائمة تحكم وصول مختلفة (RecordingResourceReference). |
| القائمة حسب userid عبر SOAP فقط | Right.SOAP. المستخدمون المسجَّلون افتراضيًا لا يملكونها. |
| الحفظ غير الموثَّق | يحتاج performCall إلى SID مع LOGIN. |
أغلق الإصدار 9.1.0 الثغرة CVE-2026-49488 (قراءة نظام الملفات عبر fuid في السبورة). واصلت البحث في معرّفات كائنات REST. حذف التقويم يتحقق من a.isOwner(sd.getUserId()). أما حفظ التقويم فيتحقق من مالك DTO الطلب، أو من كونه null. يقوم CalendarMapper.get بتحميل appointmentDao.get(dto.getId()) دون نطاق مالك. ثم يقوم RoomMapper بتوسيخ كيان JPA للغرفة قبل dao.update.
حساب تكامل LMS هو حساب SOAP الذي يسرد كل موعد. هذه البقايا هي LOGIN مقابل المالك.
cd lab
./run.sh
Loopback https://127.0.0.1:18150/openmeetings. مسؤول Docker الرسمي om_admin / 1Q2w3e4r5t^y. TLS موقّع ذاتيًا. آخر سطر من الشاهد:
SUCCESS OPENMEETINGS-CALENDAR-SAVE-WITNESS
حمّل الموعد المحفوظ قبل الحفظ. اشترط a.isOwner(caller) ما لم يكن SOAP/ADMIN. لا تطبّق كتابات RoomMapper على غرفة لا يستطيع المتصل إدارتها. تعامل مع المالك المحذوف على أنه "أبقِ المالك المحفوظ"، وليس "يصبح المتصل هو المالك".
Abraxas Labs - https://abraxaslabs.tech - https://github.com/abraxas - https://x.com/abraxas_null - [email protected]
المورّد: [email protected]