This is a mirror of official site: http://jasper-net.blogspot.com/

SQL injection with raw MD5 hashes (Leet More CTF 2010 injection 300)

| Tuesday, November 30, 2010
The University of Florida Student Infosec Team competed in the Leet More CTF 2010 yesterday. It was a 24-hour challenge-based event sort of like DEFCON quals. Ian and I made the team some ridiculous Team Kernel Sanders shirts at our hackerspace just before the competition started. The good colonel vs. Lenin: FIGHT!

Here’s a walkthrough/writeup of one of the challenges.

Injection 300: SQL injection with raw MD5 hashes
One challenge at yesterday’s CTF was a seemingly-impossible SQL injection worth 300 points. The point of the challenge was to submit a password to a PHP script that would be hashed with MD5 before being used in a query. At first glance, the challenge looked impossible. Here’s the code that was running on the game server:

<?php
require "inc/mysql.inc.php";
?>
<html>
<head><title>Oh, Those Admins!</title></head>
<body><center><h1>Oh, hi!</h1>
<?php
if (isset($_GET['password'])) {
$r = mysql_query("SELECT login FROM admins WHERE password = '" . md5($_GET['password'], true) . "'");
if (mysql_num_rows($r) < 1)
 echo "Oh, you shall not pass with that password, Stranger!";
else {
 $row = mysql_fetch_assoc($r);
 $login = $row['login'];
...


The only injection point was the first mysql_query(). Without the complication of MD5, the vulnerable line of code would have looked like this:

$r = mysql_query("SELECT login FROM admins WHERE password = '" . $_GET['password'] . "'");

If the password foobar were submitted to the script, this SQL statement would be executed on the server:

SELECT login FROM admins WHERE password = 'foobar'

That would have been trivial to exploit. I could have submitted the password ' OR 1 = 1; -- instead:

SELECT login FROM admins WHERE password = '' OR 1 = 1; -- '

…which would have returned all the rows from the admins table and tricked the script into granting me access to the page.

However, this challenge was much more difficult than that. Since PHP’s md5() function was encrypting the password first, this was what was being sent to the server :

SELECT login FROM admins WHERE password = '[output of md5 function]'

So how could I possibly inject SQL when MD5 would destroy whatever I supplied?

The trick: Raw MD5 hashes are dangerous in SQL
The trick in this challenge was that PHP’s md5() function can return its output in either hex or raw form. Here’s md5()’s method signature:

string md5( string $str [, bool $raw_output = false] )

If the second argument to MD5 is true, it will return ugly raw bits instead of a nice hex string. Raw MD5 hashes are dangerous in SQL statements because they can contain characters with special meaning to MySQL. The raw data could, for example, contain quotes (' or ") that would allow SQL injection.

Read more: cvk | nc -l -p 80

Posted via email from .NET Info

0 comments: