SQL Injection – It really does work

Well I can’t believe it, after all these years of writing PHP websites with MySQL I finally had a site that was worth the effort to buy an SSL cert and test for SQL Injection. This attack has always facinated me because of it’s simplicity and destructive capability.

So here was what happened. I wrote in a quick “recover password” feature that would take a little pressure off of the company staff. It was supposed to be a helpful feature not one that would cause me this much work! Basically you put your email address in and the site would generate a random password, change it in the database, and then send you off a nice email telling you what your new password is. Simple right?

Well when it came down to it the lines below were a very quick and easy down fall.

$sql = mysql_query("select count(*) from users where email = '".$email."'" or die(mysql_error());
$results = mysql_result($sql, "0");

Yeah, I know right. You can see it now. Well I was writing a ton of code that day so back off 😛 As you guessed it all you have to do is enter

' OR ''='

in the “email” field and whala! You have been injected. So what actually happened you ask? Well a little further down in the page I would reset the password then check to see what their “email” address was and send them their new password … or every FREAKN’ USER!


//code to send email
$sql = "select * from users where email = '".$email."'";
$emailResults = mysql_query($sql, $conn) or die(mysql_error());
while ($emailArray = mysql_fetch_array($emailResults)) {
$emailPassword = genRandomString();
$emailName = $emailArray['name'];
$emailAddress = $emailArray['email'];
$emailSubject = "Password Request";
$emailMessage = "

J00 have been Inj3cted!

";
$emailHeaders = "From: Lazy Admin\r\n";
$emailHeaders .= "MIME-Version: 1.0\r\n";
$emailHeaders .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
mail($emailAddress, $emailSubject, $emailMessage, $emailHeaders);
}
//end of the email code
//Update the database
$sql = "update users set password = '".sha1($emailPassword)."' where email = '".$email."'";
$emailResults = mysql_query($sql, $conn) or die(mysql_error());
header( 'Location:index.php');

So really how do you go about fixing this? Well first you go back to a backup of your MySQL database and restore the bloody users table. Then I had to change my PHP so that it actually did some verification of user input. You know you can never trust them users 😀

So when the user entered the one field (I know it was only one field and I was too lazy to verify it, I am not proud of this you know) and posted it to the PHP page all I have to do is quickly check to see if there are any escape characters that are used for SQL injection. I first thought of using a preg_mod command but that quickly started to look like a bad idea. So now I asked my friend Google what I should do. Well go figure you ask a question and you get an answer! PHP has got this neat little thing called mysql_real_escape_string. So I changed the first SQL query to this, and then cranked up all the SQL injection filters on my Tipping Points!


$sql = sprintf("select count(*) from users where email = '%s'", mysql_real_escape_string($email));
$sql = mysql_query($sql) or die(mysql_error());
$results = mysql_result($sql, "0");

I hope others can see this and learn from it. Please don’t make the same dumb ass mistakes that I do or all my hard blogging is in vein.

Leave a Reply

All Work on this site is not to be reproduced without written permision from Nick Schroedl.