0

I'm carrying out a code review of a site and have found a possible SQL injection vulnerability. I should point out that this is for a CTF exercise so this might be a bit of a noob question. The code below queries the database for the username and password and if it finds a match on both it allows you to login.

    $username = mysql_real_escape_string((string) $_POST["username"]);
    $password = md5($_POST["password"]);

    $query = @mysql_query("SELECT * FROM user WHERE username='$username' AND pwd='$password'");

    if (@mysql_num_rows($query) !== 1) {
        $html = "Your username or password is wrong<br>".ShowLoginForm();
        return;
    } else {
        $html = "Logged in. <a href='index.php'><font color=\"#9CCFEC\">continue</font></a>";
    }

I have found that it is possible to log in as any user if the following code is injected directly to the database:

SELECT * FROM user WHERE username='admin' OR 1=1 '' AND pwd='anyrandomtext'

The challenge here is breaking out of the mysql_real_escape_string() statement and to do so I would like to see exactly what is being passed to the server once the input has been modified by this function. Is there a way to do this? The site is running on Apache.

  • Don't use the error suppression operator (@) as it hides error messages that may be helpful in debugging your code. You should also always write your code so it does not generate any PHP errors including notices. – John Conde Mar 15 '17 at 12:17
  • `md5()`is obsolete for hashing passwords and should *not be used*. PHP provides [password_hash()](http://php.net/manual/en/function.password-hash.php) and [password_verify()](http://php.net/manual/en/function.password-verify.php), please use them. And here are some [good ideas about passwords](https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet). If you are using a PHP version prior to 5.5 [there is a compatibility pack available here](https://github.com/ircmaxell/password_compat). – John Conde Mar 15 '17 at 12:18
  • [Please, don't use `mysql_*` functions in new code](http://stackoverflow.com/questions/12859942/). They are no longer maintained [and are officially deprecated](https://wiki.php.net/rfc/mysql_deprecation). See the [red box](http://uk.php.net/manual/en/function.mysql-connect.php)? Learn about [*prepared statements*](https://en.wikipedia.org/wiki/Prepared_statement) instead, and use [PDO](http://php.net/pdo) or [MySQLi](http://php.net/mysqli) - [this article](http://php.net/manual/en/mysqlinfo.api.choosing.php) will help you decide which one is best for you. – John Conde Mar 15 '17 at 12:18
  • Even [if you are escaping inputs, its not safe!](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) Use [prepared parameterized statements](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). – John Conde Mar 15 '17 at 12:18
  • 1
    No problem - it's not my code, like I said it's part of a CTF exercise and it's got a few vulnerabilities baked in intentionally. The authentication mechanism used here is abysmal... Thanks for the input - fast fingers! – Calum Thomson Mar 15 '17 at 12:21
  • If the remote page is using either the default character set or changing it via `mysql_set_charset` then there's nothing to break. However this information is missing from this code so who knows. – apokryfos Mar 15 '17 at 12:27
  • @CalumThomson Yeah, I only posted my comments because there are others who will try to use this code because they don't know how to code and *hopefully* this prevents them from using code that is obsolete and dangerous. – John Conde Mar 15 '17 at 12:40

1 Answers1

0

Dunno what you "found" but in the code snippet you posted here there is no vulnerability.

The challenge here is breaking out of the mysql_real_escape_string() statement

Mission impossible.

There is no breach and nothing to break. Move on to the next exercise.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345