1

I am setting up a website with SQL injection vulnerabilities for testing purposes. However, I want to configure a Blind SQL injection only. I have this PHP code:

<?php
    $news_id = $_GET["id"];

    $conn = mysqli_connect("localhost","root","","db");
    $result = mysqli_query($conn,"SELECT * FROM News WHERE id='" . $_GET["id"] . "'");
    $count  = mysqli_num_rows($result);
    if($count==0) {
            $message = "Invalid ID";
            header( 'Location: id_not_found.html' );
    } else {
            $message = "Correct ID!";
            $m = mysqli_fetch_assoc($result);
    }
?>


<html>
    <head>
            <link rel="stylesheet" type="text/css" href="mystyle.css">
            <title>NEWS</title>
    </head>
    <body>
            <h1>NOTICIA</h1>
            <div style="background-color:#c6c6c6;color:black;padding:20px;">
                    <h2><?php echo $m["title"]; ?></h2>
                    <p><?php echo $m["body"]; ?></p>
                    <p><?php echo $m["datetime"]; ?></p>
            </div>
    </body>
</html>

In my opinion, It seems that this code only has a Blind SQL vulnerability because It only prints the names of the columns of News Table, so If user insert some query, the results won't be printed.

However, when I do this injection:

http://localhost:8080/web_base_de_datos_asig/check_newsid.php?id=-1' UNION SELECT NULL,NULL,user(),NULL-- kyGC

The current user is printed because the query is returned the next array:

Array ( [0] => [id] => [1] => [title] => [2] => root@localhost [body] => root@localhost [3] => [datetime] => ) 

So, How can I program only a Blind SQL Injection? I really don't know how to do that.

UPDATE I write a dirty solution. However, It works (but I would like to get another solution more interesting). The fact is that, when data is returned, I do another query to the database asking for every parameter. If it exists, the data can be printed because It only contains true information (not, for example, db username).

   $result2 = mysqli_query($conn,"SELECT * FROM News WHERE title='" . $m["title"] . "' and body='" . $m["body"] . "' and datetime='" . $m["datetime"] . "'");
   $count2  = mysqli_num_rows($result2);
Miguel.G
  • 377
  • 1
  • 6
  • 20
  • 1
    Wouldn't it better to just avoid SQL Injection using a [prepared](http://php.net/manual/en/mysqli.prepare.php) statement? Why would anyone explicitly need to use the "functionality" of SQL Injection? – LukStorms Dec 02 '18 at 11:34
  • 3
    For testing purposes probably means he wants to demonstrate a website where SQL injections are possible without any feedback. probably for a school presentation. – Jared C Dec 02 '18 at 11:41
  • You need to read the description of [Blind SQL Injection](https://www.owasp.org/index.php/Blind_SQL_Injection) - It demonstrate a method of stealing data using a true/false tests that will help an attacker to determine how to attack your website. As the above comment stated - Instead of wasting your time on developing a validation logic for a specific type of SQL Injection, you should simply avoid it and use prepared statements – Alon Eitan Dec 02 '18 at 11:58
  • 1
    As @JaredC says, it is for a presentation. – Miguel.G Dec 02 '18 at 16:42
  • 1
    @LukStorms I used prepared statements with MySQLi and, obviously, it works fine. However, I want a PHP code with these type of vulnerability for training/school purposes. – Miguel.G Dec 02 '18 at 16:44
  • @AlonEitan I know how Blind SQL Injection works. I developed some exploits to get blind data in Oracle and MySQL. However, I don't know how to implement the vulnerability for training/school purposes. – Miguel.G Dec 02 '18 at 16:45
  • 1
    @Miguel.G Thanks for clearing that up. +1 – LukStorms Dec 02 '18 at 16:46
  • Thanks both of you! I know that when someone read these kinds of post the questions come :) – Miguel.G Dec 02 '18 at 16:46
  • 1
    How about just not echoing out the results of the sql. Perhaps this is a user login form in which case your sql might be `'SELECT 1 FROM users WHERE userid ='" . $_GET["userid"] . " and pass=" .$_GET["pass"] . "';'` I feel so dirty even writing that. Then your PHP just says "username not found" or "password is incorrect" or similar. Then your SQL injection attack is to make decisions based on that error message popping or not. – JNevill Dec 03 '18 at 15:04
  • Hi @JNevill, thanks for your answer! This is a nice solution, yes. It fixs in my requeriments. May I use it. However, I would like to know how to do it when the webpage has to print out some query results. I think there is not an unique solution because it depends of the code (that is why I have to write this dirty solution). So, in a couple of days I will close this issue. – Miguel.G Dec 03 '18 at 15:33
  • I think that's the entire point of "Blind" here though. Is that you are hacking/injecting a SQL vulnerability where you don't see any output besides an error message, or determining which page loads (an error page, a login page, return to the home page, etc). If you can see results, then those results can be hacked via injection and it's no longer "Blind" to the hacker. Essentially your SQL result set doesn't make it to the user, it's interpreted entirely by the server that then makes decisions based on that interpretation. The hacker has to reverse engineer. – JNevill Dec 03 '18 at 15:39
  • At the wikipedia entry (I know... it's just wikipedia) this is stated as *"When the database does not output data to the web page, an attacker is forced to steal data by asking the database a series of true or false questions."* That *"no output data to the web page"* is the key here, I believe. As soon as you `echo` any part of that result set, the hacker is no longer blind. And login forms are a VERY typical example of this sort of thing. – JNevill Dec 03 '18 at 15:42

1 Answers1

0

You are confusing error handling with payloads. Blind SQL injection does not mean that you cannot exploit it with a union clause, it means that if an error occurs (for example if apostrphe is injected), you won't see any error message or any sign of an SQL injection. For example, you would see a regular "incorrect ID" or "no results found" message. If you are aiming for a SQL injection that does not return any textual results to the user, you are aiming for a binary SQL injection, for example: a login screen. Bare in mind that both binary SQL injection and textual (text-returned) SQL injection can be either blind or descriptive (errors are printed back to the user).

Gil Cohen
  • 836
  • 7
  • 12