Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I searched all over google to see how it would be possible to bypass the following (it's from the high level of security from DVWA):

<?php    

if (isset($_GET['Submit'])) {

// Retrieve data

$id = $_GET['id'];
$id = stripslashes($id);
$id = mysql_real_escape_string($id);

if (is_numeric($id)){

    $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
    $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );

    $num = mysql_numrows($result);

    $i=0;

    while ($i < $num) {

        $first = mysql_result($result,$i,"first_name");
        $last = mysql_result($result,$i,"last_name");

        echo '<pre>';
        echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
        echo '</pre>';

        $i++;
    }
  }
 }
?>

Is it possible to crack that?

Also, my other concern is on Medium level. It does have the mysql_real_escape_string() working, but when you use the same SQL injection from Low level AND you remove the quotes, it bypasses the protection. Why is that? How come it was so easy to bypass mysql_real_escape string?

The code (concise version) of the Medium level is this:

   $id = $_GET['id']; 
   $id = mysql_real_escape_string($id); 
   $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
share|improve this question

3 Answers 3

up vote 11 down vote accepted

The ‘high’ example is not exploitable. It's not a good approach (in modern code you would use parameterisation instead of calling mysql_real_escape_string, and stripslashes is a relic of an era of magical quotes that is thankfully over), but it is designed not to be immediately vulnerable.

(To SQL injection anyway. It is vulnerable to HTML-injection leading to XSS issues, thanks to those horrible echos, but that's another story.)

How come it was so easy to bypass mysql_real_escape string? [in the Medium example]

Because mysql_real_escape_string is designed to escape characters for safety when included in an SQL string literal context. Without any surrounding single quotes in the query's injection point, you're not in a string literal context, you're in a raw SQL context.

share|improve this answer
1  
The last part is very interesting. Could you expand on that string literal vs raw SQL context and how it changes things? –  markus-tharkun Oct 4 '13 at 11:01
    
@markus-tharkun because if you pass 3 OR 1=1 through mysql_real_escape string you still get 3 OR 1=1. If the query is built like $query = "$sql = select * from users where id = $id", then feeding 3 OR 1=1 will return all rows. whereas $query = "$sql = select * from users where id = '$id'" (note the quotes around $id) would prevent this type of injection. –  longneck Oct 7 '13 at 14:29

SQL Injection is not possible in this situation. This code is preventing SQLi properly and even if the platform is old or misconfigured, it should still be immune to SQLi.

... In a slightly different configuration it maybe vulnerable.

If is_numeric() was removed, mysql_real_escape_string() was replaced with addslashes(), and the server was configured to used the GBK language set, then there is the possibility of a multi-byte attack using the GBK language encoding.

share|improve this answer

Here's something interesting: The high level in DVWA is not meant to be exploitable. It's the "correct" and safe implementation of the concepts as the DVWA's author saw fit at the time. So, it's very natural that you're unable to perform SQL Injection at the high level. If you actually do, you would be discovering something new. A zero-day, maybe.

I've been playing with DVWA for years and I had to learn this the hard way.

share|improve this answer
2  
It's still a silly implementation. Three different "sanitization" functions instead of converting to the appropriate type. Presumably it's an integer, so why not simply $id = intval($_GET['id'])? –  CodesInChaos Oct 3 '13 at 18:35
    
@CodesInChaos Hey, I agree with you. I wouldn't have done it that way either, but I've tried my best to make it clear in my answer that this is (apparently) what the DVWA's authors saw fit at the time. You're welcome to ask him/them. –  Adnan Oct 3 '13 at 18:41
    
You have to be careful with intval and how it treats non numeric values. From the PHP documentation on intval: "Strings will most likely return 0 although this depends on the leftmost characters of the string". I don't see it causing an issue in this case, but it could though. –  droope Oct 10 '13 at 21:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.