Qualys Blog

www.qualys.com
4 posts

Bash Shellshock Command Injection Vulnerabilities

Shellshock (CVE-2014-6271)

Bash or Bourne Again Shell is prone to a remote code execution vulnerability in terms of how it processes specially crafted environment variables. Most Linux and Unix based systems are vulnerable since the Bash shell is one of the most common installs on a Linux system and is widely used. A lot of programs like SSH, telnet, CGI scripts allow bash to run in the background allowing the vulnerability to be exploited remotely over the network which makes it more scary. Refer to Wolfgang’s post BASH Shellshock vulnerability – Update5 for more details on the vulnerability.

Continue reading …

Hacking into WordPress Using a Vulnerable Plug-in

WordPress is currently the most popular blogging system in use on the Web, powering over 60 million websites worldwide. There are over 15,000 WordPress plug-ins that extend the functionality of WordPress. But these plug-ins also add numerous security risks making the website vulnerable to attacks. Although core WordPress vulnerabilities exist and may be more challenging to find, most WordPress attacks these days are results of plug-in vulnerabilities followed by default passwords and obsolete software.

Recently, I started exploring various WordPress plug-ins to test if installing a plug-in made the site more vulnerable, and to determine how big of a concern the security of the plug-in was. I started with a few of the popular and top-rated plug-ins. During that exercise, I discovered an HTML Code and Script Injection Vulnerability in the WP Photo Album Plus plug-in.

Continue reading …

Risks of Vulnerabilities in Example Scripts Bundled with Software

A lot of software comes bundled with various supporting files. These may include programming examples, help files, and scripts that make installation and configuration easy. These supporting files are supposed to be removed in production environments after the installation and configuration is complete. But many organizations may not have the resources to identify and remove these non-essential example files from their production environments. The actual software may be security hardened, but many times these supporting files contain vulnerabilities.

Apache Struts2 Example App Cross-site Scripting Issue

struts2I came across one such issue recently with the example applications in Apache Struts2. I was developing a QualysGuard vulnerability signature for one of the Struts2 advisories when I noticed different examples that come bundled with the full distribution of Struts. Upon browsing the various sample applications and reviewing the source code of a few pages, I discovered a cross-site scripting vulnerability in one of the pages in the “struts2-showcase” example. Here I will describe how someone with malicious intent could exploit cases like this if the examples are not restricted or removed.

The vulnerability has no remarkable threat impact since these examples are not intended to be deployed in a production environment. However, it is still an issue if the example applications are not removed, making the system vulnerable to execution of script code.

Background

Apache Struts2 is a framework for creating Java web applications. The full distribution package of Struts2 is bundled with example applications like “struts2-showcase”, “struts2-blank”, “struts2-mailreader” and so on and so forth. If these example applications are not removed, “viewSource.action” in “struts2-showcase” example is prone to a cross-site scripting vulnerability that could allow a malicious user to execute arbitrary HTML and script code.

The issue is that input passed via the 'config' and 'className' parameters in '/struts2-showcase/viewSource.action' is not properly sanitized before it is returned to the user. This can be exploited to execute arbitrary HTML and script code in a user’s browser session in the context of a vulnerable site.

Proof of Concept

GET /struts2-showcase/viewSource.action?config=<script>alert("QualysXSS")
</script>&className=<script>alert("QualysXSS2")</script> HTTP/1.1\r\n\r\n

Sample Request

http://10.40.2.159:8080/struts2-showcase/viewSource.action?config=<script>
alert("QualysXSS")</script>&className=<script>alert("QualysXSS2")</script>

Struts XSS1

Struts XSS2

Upon receiving the sample request (see A), processing on values assigned to "config" and "className" parameters is done in viewSource.java and the input is rendered to the user via viewSource.jsp. The input is not sanitized, resulting in script code execution. For instance, for the sample request, alert boxes are popped up (see B). Below is a snippet of the HTML source code from the resulting output. As you can see below, the <script> tags are not properly escaped, allowing arbitrary script code to be executed in the context of the application.

    -------- Snippet of Output from the Sample Request ----------
      <script language="JavaScript"
      type="text/javascript">djConfig.searchIds.push("one");</script>

      <div dojoType="struts:BindDiv"
      id="two" label="Configuration"
      showError="true" parseContent="true">

      <h3><script>alert("QualysXSS")</script></h3>

   </pre>
      </div>
      <script language="JavaScript"
      type="text/javascript">djConfig.searchIds.push("two");</script>

      <div dojoType="struts:BindDiv"
      id="three" label="Java Action"
      showError="true" parseContent="true">

      <h3>/<script>alert("QualysXSS2")</script>.java</h3>

    --------------------------------------------------------------

Exploit Tested On

  • Apache Struts2 2.3.1.2
  • Apache Struts2 2.3.1.1
  • Apache Struts2 2.2.1.1

Solution

The issue was reported to the Struts Security Team and has been fixed in Struts Version 2.3.3.

There are quite a few applications which usually get deployed without many restrictions, leaving them vulnerable to being exploited. Caution should be taken to change or disable “defaults” and/or “example applications” so that they don’t become a source for compromise. The bottom line is that deploying example applications bundled with software straight out of the box can be risky, and administrators should be careful during installation. Such example applications should be removed and never used in production environments.

Apache HTTP Server Reverse Proxy/Rewrite URL Validation Issue

Today Apache acknowledged another reverse proxy issue (CVE-2011-4317) which I discovered while creating a QualysGuard vulnerability signature for an older problem CVE-2011-3368. Depending on the reverse proxy configuration, the vulnerability could allow access to internal systems from the Internet.

While reviewing the patch for the older issue CVE-2011-3368, it appeared that it was still possible to make use of a crafted request that could exploit a fully patched Apache Web Server (Apache 2.2.21 with CVE-2011-3368 patch applied) to allow access to internal systems if the reverse proxy rules are configured incorrectly. I submitted an advisory and proof of concept to Apache and Apache made the issue public today.

For a good description of the older CVE-2011-3368 issue as well as how a reverse proxy works please check the excellent blog post by Context.

Here is a description of the new issue CVE-2011-4317 and its proof of concept.

Apache’s patch for CVE-2011-3368

The patch for CVE-2011-3368 (see Figure 1) is straight forward and self explanatory. The “server/protocol.c” file was modified. The patch looks at the request being sent and returns a HTTP 400 Response (Bad Request) if the URL does not begin with a forward slash “/”.

— httpd-2.2.21/server/protocol.c
+++ httpd-2.2.21/server/protocol.c
@@ -640,6 +640,25 @@

     ap_parse_uri(r, uri);

+    /* RFC 2616: +     *   Request-URI    = "*" | absoluteURI | abs_path | authority
+     * +     * authority is a special case for CONNECT.  If the request is not
+     * using CONNECT, and the parsed URI does not have scheme, and
+     * it does not begin with '/', and it is not '*', then, fail
+     * and give a 400 response. */
+    if (r->method_number != M_CONNECT
+        && !r->parsed_uri.scheme    <– A
+        && uri[0] != '/'
+        && !(uri[0] == '*' && uri[1] == '\0')) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                      "invalid request-URI %s", uri);
+        r->args = NULL;
+        r->hostname = NULL;
+        r->status = HTTP_BAD_REQUEST;
+        r->uri = apr_pstrdup(r->pool, uri);
+    }
+
     if (ll[0]) {
         r->assbackwards = 0;
         pro = ll;

Figure 1

This part of the code takes care of the issue for CVE-2011-3368. However; if you carefully look at the patch, it does not process URIs that have a scheme (see Figure 1, A). So, if a malformed URL request with a scheme was constructed, it would still be possible to bypass security and gain access to systems on the internal server provided that the reverse proxy rules were incorrectly configured.

Proof of Concepts

Target: Fully patched Apache Web Server (Version 2.2.21) with CVE-2011-3368 patch applied, with a reverse proxy set up and incorrectly configured RewriteRule/ProxyPassMatch rules.

Rewrite rules in httpd.conf:

RewriteRule ^(.*) http://10.40.2.159$1
ProxyPassMatch ^(.*) http://10.40.2.159$1

Example 1:

GET @localhost::<PORT> HTTP/1.0\r\n\r\n
where <PORT> is any port number being requested.

To demonstrate the proof of concept, Tomcat was set up to run on port 8880 on the internal server. Please note that any application could be running on any port on the internal server and a malicious user could use the PoC to request access to an application running on that port.

Access to internal web server can be possible by using a crafted request like:
GET @localhost::8880 HTTP/1.0\r\n\r\n

The screenshot below shows that a basic query with the crafted request (see Figure 2, B) to the target results in access to the page at 8880 (see Figure 2, C).


Figure 2

Upon receiving the request, Apache translates the URL by applying the rewrite rules. The "uri" extracted is ":8880" which gets appended, resulting in the URL

http://10.40.2.159:8880

The "uri" extracted in this case is everything following the first occurrence of the colon (:) in the request. Since the crafted request has 2 colons (::), the second colon is treated as being part of the URI.

To view the URI being extracted based on the rewrite rules, “RewriteLogLevel” was set to 3 in Apache configuration file. The rewrite translation logs get written to the log file. The first step to come up with the crafted request was to review the log file by sending different requests and studying how the rewrite translation was working. In the case of Example 1, since everything following the first colon (:) was being treated as the URI, a second colon was appended with a port number to see the response. The server treated the second “:” as being part of the URI and since there was an application already running on the port, it was possible to gain access to the page.

Example 2:

GET <random_string>:@<internalservername> HTTP/1.0\r\n\r\n
where <random_string> is any string, <internalservername> is the domain of an internal server being requested.

Access to internal web server can be possible by using a crafted request like:
GET qualys:@qqq.qq.qualys.com HTTP/1.0\r\n\r\n

The screenshot below shows that a basic query with the crafted request to an internal website (see Figure 3, D) allows access to the page remotely (see Figure 3, E).


Figure 3

Upon receiving the request, Apache translates the URL by applying the rewrite rules. The "uri" extracted is "@qqq.qq.qualys.com" which gets appended, resulting in the URL

http://10.40.2.159@qqq.qq.qualys.com

The "uri" extracted in this case is everything following the first occurrence of the colon (:) in the request. This is treated as <username>@<host> giving access to the internal <host> if no authentication is required.

Patch

Apache fixed this issue in Version 2.2.22.

Workaround

Until a patch is applied, configuring the reverse proxy rules in the apache configuration file correctly will prevent this issue from occurring. For example, in the above case, if the reverse proxy rules (RewriteRule or ProxyPassMatch directives in httpd.conf) are configured as follows, the proof of concept will not work.

RewriteRule ^(.*) http://10.40.2.159/$1
ProxyPassMatch ^(.*) http://10.40.2.159/$1