Twitter
Friday
Oct032014

A Java Web App's Attack Surface to Shellshock

Amongst the chaos of trying to patch and the whirlwind of information on the Shellshock vulnerability, several of our clients raised the question - what level of exposure, if any, do our enterprise Java web applications have to Shellshock?

In case you’ve been living under a shell, here are a few links to get up to speed on CVE-2014-6271, dubbed Shellshock. Various web-based software products were proven to be vulnerable. Custom web apps running on Apache using mod_cgi or mod_cgid where CGI scripts are either written in Bash, or spawning subshells are also easy targets (if a vulnerable version of Bash is still installed). Web apps written in PHP, Python, or Java could be vulnerable if they make calls to functions such as popen() or system(), as these are backed by calls to /bin/sh -c. Since it is common for systems to create symbolic links from /bin/sh to /bin/bash it could still lead to these applications being susceptible to the Shellshock vulnerability.  

Despite Java apps being implicated as potentially vulnerable, our gut reaction was the exposure for a typical Java web app would likely not be critical or systemic, but rather on a case by case basis. Further, we always advise our clients that any Java web app spawning external processes be closely audited and better more secure alternatives be considered irrespective of this Bash vulnerability. With that said, we still wanted to do a little bit of research to back this up and this blog post shares some of these results. On to the details …

Two main conditions must be met to exploit the Shellshock vulnerability :

  1. The system runs a vulnerable version of Bash shell
  2. An attacker injects a persistent or volatile malicious environment variable into directly or indirectly invoked Bash shell

Applications running Apache ‘mod_cgi’ are remotely vulnerable to Shellshock due to HTTP request headers (e.g. User-Agent header) being set as environment variables. During the request processing Apache receives an HTTP request header and sets the values as environment variables that are visible within the script handler provided by mod_cgi. The combination of user controllable environment variables through HTTP data and the behavior of command executions spawning shells creates a high potential for exploitable Shellshock scenarios within CGI applications to be a likely scenario.

However, Java web application containers like Apache Tomcat, handle the request parameters and headers without using the environment variables as a pipeline. To verify the previous statement GDS performed a set of tests on Apache Tomcat (v8.0.12,7.0.55) and JBoss Application Server (v7.4). The tests included using a python script that injects a Shellshock payload into HTTP request headers and query parameters on a selected endpoint. A simple JSP page was built to iterate through the environment variables to confirm that the request headers did not lead to an environment variable being tainted with user input. As expected, this was confirmed and significantly reduces the potential for Shellshock to be exploited in a Java web app via the typical HTTP header payloads

POC.JSP:

… snip …

Enumeration<String> HeaderName = request.getHeaderNames(); %>

<H1> Headers</h1>

<% 

 String headerName , headerValue  ;

while(HeaderName.hasMoreElements()){

  headerName  = HeaderName.nextElement();

  headerValue = request.getHeader(headerName);

  // Save Header

  headerMap.put(headerName, headerValue);

 %><H1> Env Variables </h1><%

for(Map.Entry<String,String>  entry : System.getenv().entrySet()){ %>

  <%=entry.getKey()%> <%=entry.getValue()%><br>

<%

for(Map.Entry<String,String> headerEntry : headerMap.entrySet()){

  if(entry.getValue().contains(headerEntry.getValue())){

  finding.put(entry.getKey(), headerEntry.getKey() +":"+ headerEntry.getValue());

}}}

// Register Logs

for(Map.Entry<String,String> entry : finding.entrySet()){

  writer.append(entry.getKey()+":"+"{"+entry.getValue()+"}");

}

…snip …  

Tester.py :

…snip …

def start:

request_headers =  {}

for header_key in INPUT.HEADERS:

for reuqest_method in INPUT.METHODS:

  request_headers = copy.copy(INPUT.HEADERS)

  request_headers[header_key] = INPUT.HEADERS[header_key]+INPUT.PAYLOAD

  self.__client.request( request_method,"/ POCs_Headers.jsp",headers=request_headers )

  self.__logfile.write(self.__client.getresponse().read())

… snip …

Java’s ‘Runtime.exec’ method seemed like the most obvious place to start as a high-risk function that could work as a stepping stone for exploitable scenarios of Shellshock. ‘Runtime.exec’ uses the ProcessBuilder class to execute the command passed to it. The following outlines the function execution flow for executing the submitted command.

Runtime.exec function flow :

- > Runtime.exec(String command)

- > Runtime.exec(String command, String envp, File dir)

- > ProcessBuilder.start(String[] cmdArray, Map<String,String> env, String dir, …)

- > UnixProcess( final byte[] prog, …. )

- > forkAndExec( … )

Unlike command execution APIs found on PHP or Perl where a shell will be invoked regardless of the string passed in, Java’s Runtime.exec does not work in this manner. Runtime exec will perform an exec of the submitted string value and therefore a Shellshock vulnerability could only occur if Bash is invoked by the running process by calling ‘/bin/bash’, symbolic links to ‘/bin/bash’ or any executable that may invoke Bash at some point. 

In the event that an environment variable within the application server process is user controllable it would cause the application invoking the following code to be vulnerable to the Shellshock vulnerability (as discussed above, this is not the case for the application servers we looked at):

Runtime.getRuntime().exec( "/bin/bash" ) ;

Runtime.getRuntime().exec( "/script.sh" ) ; # Where script.sh uses !#/bin/bash 

Another exploitable scenario but also very unlikely would be if a malicious environment variable is passed as the second parameter within the ‘Runtime.exec’ method.

Runtime.getRuntime().exec(

  new String[]{"/bin/bash"},

  new String[]{"P=() { :;}; echo 'vulnerable' > message"}

);

Runtime.getRuntime().exec(

  new String[]{"/script.sh"},

  new String[]{"P=() { :;}; echo 'vulnerable' > message"}

);

What follows is a sample code snippet that if present in a web app would be remotely exploitable via Shellshock:

… snip …

Enumeration<String> HeaderName = request.getHeaderNames();

String headerName , headerValue ;

while(HeaderName.hasMoreElements())

{

 if ( headerName.nextElement().equals(“HOST”)){

 headerValue = request.getHeader(headerName);

 Runtime.getRuntime().exec(

  new String[]{“/bin/bash”,”-c”,”/bin/process_host”}, new String[] {headerValue});

 }

} 

Although not impossible, it’s unlikely that a developer would pass the environment variable intentionally via a HTTP header.

In conclusion, while there are certain scenarios where a Java web app could be vulnerable to Shellshock, these are likely to be one off edge cases. This is primarily due to application servers not setting environment variables with HTTP request data and also the fact that Runtime.exec does not invoke a shell unless explicitly set by a developer or indireclty used by any invoked script. Organizations should ensure that Bash is patched to the latest version and not vulnerable to Shellshock. Additionally, identify if any of the following methods or functions are called using a shell (e.g. /bin/bash/, /bin/sh, shell scripts) and ensure user input is not passed in as any parameters unless it undergoes stringent input validation. 

  • Runtime.exec
  • ProcessBuilder.start

  • UnixProcess

  • forkAndExec

It is also recommended to pass in a empty String array as the environment to these functions in order to prevent the possibility of the application server’s environment being tainted with user input. By passing an empty array as the environment it will provide an extra layer of protection in the event the application server’s environment variables can be compromised

Tuesday
Sep232014

Auditing Scala for Insecure Code with FindBugs

Here at GDS we have noticed an increase in the use of the Scala programming language by our clients. We have been looking for good tools to perform static analysis of Scala to facilitate our code audits. Although there are static analysis tools for Scala, they are not capable of identifying security issues with their out of the box rule-sets. In this blog post we cover how FindBugs can be leveraged to scan Scala for the purposes of identifying insecure code patterns.

Why FindBugs?
FindBugs is an open source static analysis tool that detects bugs in Java applications. Unlike static analysis tools PMD or Jlint, FindBugs operates on bytecode rather than source code. Because Scala classes compile to Java bytecode, this means we can run FindBugs against them! Additionally, FindBugs exposes a plugin interface making it possible to write custom bug detectors to find vulnerabilities in Scala applications. It is possible to run FindBugs without custom detectors against a Scala code base, however there will certainly be false positives and false negatives since the bug detectors are tuned against javac compiler generated bytecode. To start finding security flaws we need to write Scala specific detectors. Finally, because FindBugs is a well-known open source project already common to developer toolchains, the learning curve for extending is potentially reduced and existing development workflows do not need to be altered. It is also worth mentioning that FindBugs is integrated into the enterprise security static analysis tool Fortify SCA, and so the approach we suggest here could be a low cost alternative for these organizations. 

Implementing Your First Security Detector
We will implement a very small ‘Hello World’ detector which does nothing more than to flag every time a dangerous MongoDB function is executed. We will be writing a rule targeting Casbah, the official MongoDB driver for Scala. The Casbah library has an ‘eval’ method which can lead to the execution of arbitrary Javascript code if unvalidated user input is passed in. We will walk through how to write a rule to identify potential insecure usage of the Casbah ‘eval’ method within Scala applications.

For an introductory tutorial on how to write custom detector for FindBugs have a look at https://code.google.com/p/findbugs/wiki/DetectorPluginTutorial. For the rest of this blog post it will be assumed that you know the basics shown in the above link.

  • Since we are operating on bytecode we will extend the BytecodeScanningDetector
  • We will override the visit method, since it is called every time new code is executed.
  • When we find the ‘eval’ method we will log a bug using the standard FindBugs logging interface.

We start with extending the BytecodeScanningDetector so Findbugs knows what code we are interested in.

public class HelloworldRule extends BytecodeScanningDetector {

Next, we declare the function we are looking for. Invokevirtual means that a new function is being invoked.
private final String VULNERABLE_METHOD = "com.mongodb.casbah.MongoDB.eval";
private final String FUNCTION_DECLARATION = "invokevirtual";
BugReporter bugReporter;

We also need to define a constructor which will take in a ‘bugreporter’ object which is used to report back found bugs to FindBugs.
public HelloworldRule(BugReporter bugReporter) {
 this.bugReporter = bugReporter;
}

Next we chose to implement the visit function. The documentation around this method is a bit shorthanded but the returned object “represents a chunk of Java byte code contained in a method” according to the Javadocs. Using this method allows us to analyze a function line by line.
public void visit(Code someObj) {
 ByteSequence stream = new ByteSequence(someObj.getCode());
 while (stream.available() > 0) {
   String line = Utility.codeToString(stream, someObj.getConstantPool(), true);

 We use two helper functions to identify the function call. getCommand will give us the current instruction being executed. In this example we are mainly interested in the invokevirtual instruction mentioned above. 
String command = getCommand(line);

We also use getFunction to parse out a function signature. It might look like the following:
com.mongodb.casbah.MongoClient$.apply (Ljava/lang/String;I)Lcom/mongodb/casbah/MongoClient
The signature will always start with the full package name followed by the function name. For this example, this is all we need. For more involved rules, the function arguments could also be analyzed.
String function = getFunction(line);
 if(command.equals(FUNCTION_DECLARATION) &&   
   function.startsWith(VULNERABLE_METHOD)) {

If the function matches what we are looking for we will log a bug. We state that it’s a normal priority bug and we pass in an identifier which we will define below.
    BugInstance instance = new BugInstance("MONGO_INJECTION",
      NORMAL_PRIORITY).addClassAndMethod(this).addSourceLine(this);
    bugReporter.reportBug(instance);
  }
}

protected String getCommand(String line) {
 String[] parts = line.split("\\t");
 return (parts.length > 0) ? parts[0] : "";
}

protected String getFunction(String line) {
 String[] parts = line.split("\\t");
 return (parts.length > 1) ? parts[1] : "";
}

We also need to reference our new rule so FindBugs knows where to find it. Create a new folder in the project directory and name it “etc”. Create a new file called findbugs.xml in this folder. In here we can reference the rule by adding the following text:

<FindbugsPlugin>
  <Detector class="com.package.HelloworldRule" speed="fast" />
</FindbugsPlugin>

Lastly we need to give a short description of our plugin. Create a new file called messages.xml in that same folder. Put the following content in there:

<MessageCollection>
  <Detector class="com.package.HelloworldRule">
    <Details>
      <p> A Simple Mongo Injection Detection Rule</p>
    </Details>
  </Detector>
</MessageCollection>

The plugin is now ready to go, let’s give it a test!

Running FindBugs is pretty simple, all you need to do is to download the Jar and specify the source to run against. Adding new plugins is simple as well. You can either supply the plugin jar as a command line argument or you can add it to the default plugins folder for FindBugs. For this example we’ll add it on the command line:

java -jar /path-to-findbugs/findbugs.jar -textui -pluginList /path-to-your-new-jar.jar -home . -auxclasspath /path-to-scala-installation/:casbah-alldep.jar /path-to-class-files/

It is important to specify the auxclasspath option since this is how we will specify the classpath to the Scala installation. If the auxclasspath is not set, running Findbugs on Scala code will result in various errors. Additionally we add the Casbah jar to the path since it is a dependency to our sample application. Any other dependencies to the application being scanned should be added to the auxclasspath option when running FindBugs. The sample output below shows how FindBugs will report usage of the Casbah eval function within a Scala application.

M S GDS: A Simple Mongo Injection Detection Rule.       At CasbahExample.scala:[line 18]

This is just a short introduction on how to leverage FindBugs to analyze Scala code. Hopefully this code can be used as a foundation to write more involved and more complex rules. Popular web frameworks such as Play and Vert.x run in Scala and FindBugs can certainly be used to evaluate them.

The code referenced in this blog post can be found on our GitHub page: https://github.com/GDSSecurity/Scala-Findbugs-Sample  

Thursday
Aug142014

Analysis of Mobile Application Wrapping Wrap Up

We would like to say thanks to everyone who came to our talk on Mobile Application Wrapping. We received a good amount of positive reactions and we are working hard on completing the whitepaper to accompany the presentation.

The slides for the talk have been added to our Github Repository and is available for download:

Download Slides Here

Thursday
Jul312014

Black Hat USA 2014 

GDS will be speaking at Black Hat USA 2014 on the research we have done on “Application Wrapping” within Mobile Application Management (MAM) BYOD commercial solutions and some of the short comings we have encountered. The complete abstract for the talk can be found here: 

Keep a lookout on our Twitter and Blog for details on downloading the slides and the white paper shortly after the conference. Our research will provide very useful knowledge for the “buyers, builders and breakers” in the BYOD world.

Buyers - Organizations looking to purchase a MAM solution or determine the effectiveness of their current solution will find that we will cover the major threat scenarios in BYOD deployments, common short coming and additionally equip the business with the right questions to ask to the vendors.

Builders - The vendors that are creating the MAM solutions will be able to utilize our research to verify their solutions are not suffering from critical design and implementation flaws. The talk and corresponding whitepaper will provide organization with a solid base line of security checks to validate their solution against.

Breakers - Security assessors can learn throught the walkthroughs of the vulnerabilities discovered. The MAM solution security checklist will be provided so that security firms are equipped with a strong baseline for determining the security posture of a MAM solution. 

The talk will be on August 7th, 5pm at South Seas GH.  We hope to see you there! 

Friday
Jul112014

Introducing Windows Exploit Suggester

Introduction

Privilege escalation is an art form that revolves around information gathering, and enumeration of the target host. The idea is to find the quickest, and easiest way to escalate from a local user account to that of an Administrator. A common method for escalating is using a known exploit to target a vulnerability exposed on the unpatched host. This method is probably the fastest, and with the right information and toolkit of precompiled exploits and Metasploit modules, it is a quick win during any engagement. 

Let’s assume you have access as a local user to a partially patched Windows 7 Service Pack 1 machine. Are there any public exploits available? Which one do you run? Which exploits work with 32-bit and 64-bit architecture? Are there any Metasploit modules available to gain that coveted Meterpreter session? These questions can all be answered by manually reviewing the missing patches, and comparing that to the public exploits. Unfortunately, that is exceedingly time-consuming and thus unrealistic, this is why I sought to automate the process.

After searching online for a Window’s “exploit suggester” tool, I was surprised to find that none existed! Without further ado, I introduce “Windows Exploit Suggester” or for short “winsploit”, a tool created to automate the privilege escalation exploitation process targeting unpatched systems. This script takes, as input, the Microsoft Security Bulletin Database which is available free to download and is updated constantly by Microsoft.

It also needs the “systeminfo” command output on a target Windows host. Typically a low-privilege user is able to execute the “systeminfo” command, and when assessing the patch levels of a target host, it can provide a wealth of information (including hotfixes applied!).

Finally, it cross-references the previous information to that of a static list of Metasploit modules and publicy available proof-of-concept exploits for each bulletin number. When this information is combined, the end result is the ability to quickly analyse whether or not a target Windows host is vulnerable to many publicly available exploits.

Setup & Usage

You can find this tool on GitHub under the Windows-Exploit-Suggester repository. The tool is written in Python 2.7 and requires the xlrd library (for Excel spreadsheet parsing). This is most easily installed using pip.

$ pip install xlrd –upgrade

Alternatively, it can be downloaded from the website directly (https://pypi.python.org/pypi/xlrd/0.9.3). I was unable to use the version in the Ubuntu 12.04 repositories as it was incompatible, so had to use pip directly. 

Once the dependencies have been met, we will download the Microsoft Security Bulletin Database using the —update flag. This flag just scrapes the bulletin database from Microsoft and saves it as a local Excel file and will serve as our local bulletin database.

Once we get the local database file downloaded, we will need some “systeminfo” command output from our low-privilege user. I am using an example build from a Windows 7 Service Pack 1 32-bit machine in this scenario. Once I’ve gathered this data, I’ll run the tool against it, and include the Microsoft Bulletin database file.

Looking at the raw output, there are plenty of exploits to pick from! We can weed through the client-side attacks, assuming we’re not interested in Internet Explorer bugs at this time, and focus in on MS13-053. This exploit is quite reliable, and is better known as the pprFlattenRec exploit (http://www.rapid7.com/db/modules/exploit/windows/local/ppr_flatten_rec). The best thing about it is that it’s in Metasploit!

Everything this tool does could be done manually, but it has the ability to act as a quick solution when escalating privileges on a Windows host. I have found it helpful in many instances, especially when new bulletins come out and new Metasploit modules get released.

This tool also has the ability to tell you about any exploits possible about a target operating system. For example, lets say we want to know all of the public exploits available for a Windows 2008 R2 Server Itanium. This can be achieved with the —ostext flag, which is a loose representation of the operating system, service pack, and architecture (defaults to 32-bit).

This feature is really useful when you are able to fingerprint a target’s operating system and want to know if any Remote Code Execution bugs exist. Although not necessarily privilege escalation, it is a relevant feature to the tool.

Limitations

As with any automated tool, there are always limitations. These are some that I have identified through the use of the tool and it’s capabilities.

1 DAY ONLY — Of course this relies on known bulletins, exploits, and bugs but for an unpatched host it is a quick-win that can speed up the effectiveness of privilege escalation. It requires an entry to be present within the Microsoft Security Bulletin database, and with unsupported software (XP), these entries won’t exist! 

FALSE POSITIVES — The command output also assumes that you have every feature in Windows. For example, it will flag vulnerabilities relating to IIS even if IIS is not present on the machine! It assumes that it is a fully-featured Windows installation with all services so some intelligent manual filtering will have to be made when looking for an exploit.

INACCURATE SYSTEMINFO — There is also the presence of “File 1” entries in the ‘systeminfo’ command output which will skew the results because it cannot detect the relevant hotfixes. If there are “File 1” entries, additional commands will have to be executed to gather the hotfix data (querying the system registry directly, or using wmic). Once this data is collected it can be fed into the tool using the —hotfixes flag.

Summary

In summary, targeting an unpatched host is but one method of privilege escalation, and this tool makes that process much faster for Windows hosts. Time is essential when performing assessments, so any edge can really help. Please feel free to contact me regarding any bugs, comments, concerns, or feature requests so that I can take a look at them and make the tool even better!