| Home | About |

Sunday, 27 May 2012

We Have Moved...

We have now moved over to posterous. The new blog can be found at: https://xpnsbraindump.posterous.com

See you there !

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.

Tuesday, 13 September 2011

C# Implicitly Typed Local Variables Internals

OK, so most .NET coders are aware that C# >= 3.0 offers the 'var' keyword to provide implicitly typed local variables. One thing that intrigues me is just how this is achieved, and is their there any performance loss/gain by choosing this method ?

Take for instance the following small C# program:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

public class nongeneric_class
{
public object Data { get; set; }
}

public class generic_class<T>
{
public T Data { get; set; }
}

public class main
{
public static void Main(string[] args)
{
const int ITERATION_COUNT = 10000000;
Stopwatch stopwatch;

// Generic Class With No Dynamic Variable
stopwatch = Stopwatch.StartNew();

for (int i = 0; i < ITERATION_COUNT; i++)
{
generic_class gc = new generic_class();
gc.Data = i;
int data = gc.Data;
}

Console.WriteLine("Generic Class With No Dynamic Variable: {0}ms", stopwatch.ElapsedMilliseconds);

// Generic Class With Dynamic Variable
stopwatch = Stopwatch.StartNew();

for (int i = 0; i < ITERATION_COUNT; i++)
{
var var_gc = new generic_class();
var_gc.Data = i;
int data = var_gc.Data;
}

Console.WriteLine("Generic Class With Dynamic Variable: {0}ms", stopwatch.ElapsedMilliseconds);

// Non-Generic Class With No Dynamic Variable
stopwatch = Stopwatch.StartNew();

for (int i = 0; i < ITERATION_COUNT; i++)
{
nongeneric_class ngc = new nongeneric_class();
ngc.Data = i;
int data = (int)ngc.Data;
}

Console.WriteLine("Non-Generic Class With No Dynamic Variable: {0}ms", stopwatch.ElapsedMilliseconds);

// Non-Generic Class With Dynamic Variable
stopwatch = Stopwatch.StartNew();

for (int i = 0; i < ITERATION_COUNT; i++)
{
var var_ngc = new nongeneric_class();
var_ngc.Data = i;
int data = (int)var_ngc.Data;
}

Console.WriteLine("Non-Generic Class With Dynamic Variable: {0}ms", stopwatch.ElapsedMilliseconds);

Console.ReadLine();
}
}


Now the obvious thing that you will notice about this program when it's run, is that the trend of generic vs non-generic timings are the same (i.e. there is no great difference between using C# 'var' keyword or not, even when comparing to boxing and non-boxing types).

The definitive answer to how this works can be found with our friendly tool ildasm.


Even with no understanding of ilasm, you can see with the disassembly of our Main() static function that the local variables types declared for both our 'var var_ngc' and 'nongeneric_class ngc' variables are exactly the same. The same goes for our 'var var_gc' and 'generic_class gc' types.

All the C# compiler is actually doing is substituting the 'var' keyword for the apropriate variable type... disappointing. Unfortunately there is no magic here :(

Thursday, 18 August 2011

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;


Sunday, 7 August 2011

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