Web server compromising very rarely means exploiting only one critical vulnerability, as can be seen for example in Hollywood movies. On the contrary, this type of compromising is usually possible due to a chain series of less serious, sometimes almost absurd, vulnerabilities. In this article, we will describe a real-life scenario in which it was exactly the chain of several vulnerabilities leading to a complete compromise of the web server.
A number of automated tools can be used during web application penetration testing. These tools are able to find the basic errors in the application. But in case of more complex applications or errors, the misuse of which requires a more detailed understanding of the application’s principle of operation, automated tools are not effective. This article will be about compromising a web server, which was enabled by a number of minor vulnerabilities.
The tested page is the login gateway providing user authentication for several applications. After logging in, a simple user interface will be displayed, together with a list of links to applications assigned to the given user.
There are not many input fields or forms in the application that could be tested for classic vulnerabilities such as XSS or SQL injection. One of many errors in web applications is also the presence of pages and functionalities that the average user cannot click to through the application. For this reason, it is advisable to have a dictionary containing typical and frequently used subpage names, such as e.g. admin, dev, logs, etc. at hand. We can then try to insert words from this dictionary, e.g. to the URL address. After enumerating the URLs in this way, we get one interesting URL - /settings.
After a quick search in the downloaded JS code, the following suspicious code snippets can be found:
Because the JS code authenticates these privileges on the client side, they can be easily added, e.g. by editing the responses received from the server with some web proxy. So let's adjust the original privileges to the following:
After loading the /settings page with new permissions, we can see the hidden functionalities.
Many of these functionalities disclose sensitive data such as various keys and configurations of associated applications, etc. Some functionalities can be expanded to identify the aforementioned sensitive data, but it is not possible to change its status - probably because these requests are rejected by the server. But we will focus only on one functionality and that is Templates/Visual. This functionality is used to view and edit templates and some other documents responsible for the look of the application.
If we could edit these templates, we can edit the page itself and insert in anything according to our needs. We will choose the footer.hbs template and when we open it, we can see the template editor.
It looks that we can edit the HTML code directly. To test this, we try to insert the JS code into the page. The resulting footer.hbs code looks as follows:
After saving the template, we try to refresh the page in the browser and immediately after it’s been loaded, a window with our text appears. This window is shown to any user who is loading this page at this time.
In addition to being able to execute JS code in browser of any user, to monitor his/her activities, and to modify the appearance of the page, etc., we can use templates to insert user data available to the template engine into the page. We insert the following code into the template, which iterates through the object user and lists all its attributes.
After loading a page with this template, specific data will be listed in the HTML comment.
In addition to the login, we came to know a lot of other data and even the user password hash. We could send all this data to our server with another short piece of JS code, thus collecting information about the users.
Besides attacks on the users, the template engine allows template loading. However, because it does not check the type of file it is loading, it is possible to load a file that is not a template, e.g. /etc/passwd.
After saving the template and refreshing the page, the following text with information on the users of the system appears in the page source code.
Apart from editing the templates displaying pages before and after the user logs in, it is also possible to edit the templates used for resetting the password. Specifically, we can edit the password recovery e-mail template and add an image to this e-mail directing to our server and containing the generated password in its URL.
Now all we have to do is learn the victim's login and use the password recovery functionality to request a new password. Even though our victim will receive the generated e-mail, in case his/her e-mail client allows displaying images from external domains, our server will receive a query for an "image" with the new password hidden in its name.
During the testing, we managed to obtain up to 10 unique passwords in a very short time – we are speaking about mere few hours.
In addition to editing templates and reading the files that are not templates, we can finally try to edit some files and thus get e.g. ability to execute remote commands. But first we need to get some more information about the target device. One possibility can be (since we know it's a UNIX-like system) to read the /proc/self/cmdline and proc/self/environ files. These files may contain information which may be useful in directing the attack further.
Contents of the /proc/self/cmdline file:
Contents of the /proc/self/environ file:
We know from the abovementioned files that this is a Tomcat server, under which user the server is running, and among other information, we discovered the paths to several key directories. To get even more information, we went and tried to read the command history file.
Shortened contents of the /opt/tomcat-idp/.bash_history file:
Besides other things, it is possible to read the configuration files of Tomcat and other configuration files. All this information helped us to understand the layout of the directory structure and helped to plan the next steps. First, we thought of writing the file to the root directory, which we would then run using a web server. However, this option failed due to a lack of writing rights. Other trial-and-error scenarios, which are often an integral part of testing, followed. In the end, it turned out that we had a simple, though not completely direct, solution right before our eyes all the time. Since we know from the history of user commands that administrators have been logging in to this account on a regular basis, we can edit the .bashrc file. This file contains BASH commands that are executed immediately after the user logs in.
Modified contents of the /opt/tomcat-idp/.bashrc file:
This modification does nothing more than send an HTTP query to our server, telling us that our victim actually executed this command. In a real scenario, this harmless command could be replaced with downloading of a malware, running a reverse shell, or performing another malicious action. After a while, this query actually came to our server in the end, which would make us successful if we were an attacker.
As we can see, sometimes even an innocent-looking site can hide a number of vulnerabilities inside. While these vulnerabilities themselves can be serious due to disclosing sensitive information, they do not present as great a risk as when they are used jointly. Moreover, it needs to be said that several times, the "human factor" was required in the procedure described here.
Automated tools are able to find some of the listed vulnerabilities, but they cannot understand their nature and therefore their impact, or, alternatively, the misuse thereof in sort of a chain of vulnerabilities aiming to compromise the machine. As we have demonstrated, the server can be compromised and in case the attacker later obtains the ability to execute arbitrary commands and use the server for malicious purposes (such as sharing malware), he can try to escalate his privileges, or start attacking the internal network.