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 , 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:

bbcodetest

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="  " />
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.

Advertisements

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.

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:



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.

PHP ‘socket_connect()’ Function Stack Buffer Overflow – CVE-2011-1938

A nice simple vulnerability today: CVE-2011-1938. I’m amazed I didn’t see this the first time around?

The vulnerability describes a buffer overflow within the PHP ‘socket_connect()’ function. The source file for this function can be found at /ext/sockets/sockets.c and the problem was with the way that PHP handled AF_UNIX connections.


PHP_FUNCTION(socket_getpeername)
{
zval *arg1, *arg2, *arg3 = NULL;
php_sockaddr_storage sa_storage;
php_socket *php_sock;
struct sockaddr *sa;
struct sockaddr_in *sin;
#if HAVE_IPV6
struct sockaddr_in6 *sin6;
char addr6[INET6_ADDRSTRLEN+1];
#endif
struct sockaddr_un *s_un;
char *addr_string;
socklen_t salen = sizeof(php_sockaddr_storage);

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|z", &arg1, &arg2, &arg3) == FAILURE) {
return;
}
...
case AF_UNIX:
memset(&s_un, 0, sizeof(struct sockaddr_un));

s_un.sun_family = AF_UNIX;
memcpy(&s_un.sun_path, addr, addr_len);
retval = connect(php_sock->bsd_socket, (struct sockaddr *) &s_un, (socklen_t) XtOffsetOf(struct sockaddr_un, sun_path) + addr_len);
break;

As you can see, the memcpy() function copies the user supplied path into “s_un.sun_path”, a mere 108 bytes (default on Linux systems) worth of space allocated for the path. The inevitable happens and we are able to overflow the buffer and take over the function return address.

The PHP development team have since patched this problem, by simply adding bounds checking to the user supplied buffer:


case AF_UNIX:
if (addr_len >= sizeof(s_un.sun_path)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Path too long", php_sock->type);
RETURN_FALSE;
}

memset(&s_un, 0, sizeof(struct sockaddr_un));

s_un.sun_family = AF_UNIX;
memcpy(&s_un.sun_path, addr, addr_len);
retval = connect(php_sock->bsd_socket, (struct sockaddr *) &s_un, (socklen_t) XtOffsetOf(struct sockaddr_un, sun_path) + addr_len);
break;

Learning Ruby

I have just purchased the book ‘The Ruby Programming Language’ to start my journey with Ruby. Really there are 2 reasons as to why I have chosen to learn this language:

  • Metasploit
  • Web Development
  • Metasploit has often been a bit of a black-box for me, and coming from a C / Python development background, many of the concepts seemed quite alien, forcing any bespoke exploits to be cobbled together using Python (I have lost count of the amount of times I have had to write a TCP Client in Python).

    The second reason may seem a bit strange to people in the web development world. Most people opt for PHP / Asp.NET as their core development framework, so why Ruby ? Well I learn by Doing, and what better way to practice my new found ruby skills than by throwing myself in at the deep end with some Ruby on Rails programming.

    Initial opinions of this language are favorable.. I mean who can deny that Ruby offers some sensible (but initially strange) ways of doing things. You have no idea how strange I found it to write:

    
    
    1.upto(20) { |i| print “Number #{i}\n” }
    
    
    Insead of the usual
    
    
    while(i < 20):
    print “Number %d” % (i)
    On top of this, I have the worrying abstract world of the MVC methodology to cope with when learning Rails. Whilst I have some exposure to .NET web application programming, nothing quite gets you ready for what MVC framework in a new language has to throw at you… wish me luck 🙂