-1

I've been working on a project with a few friends. Our assignment was to find the Username and Password credentials to log in to a fake database

Here is the source code:

<?php
include "config.php";
$con = mysqli_connect("localhost", "sql1", "sql1", "sql1");
$username = $_POST["username"];
$password = $_POST["password"];
$debug = $_POST["debug"];
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($con, $query);

if (intval($debug)) {
  echo "<pre>";
  echo "username: ", htmlspecialchars($username), "\n";
  echo "password: ", htmlspecialchars($password), "\n";
  echo "SQL query: ", htmlspecialchars($query), "\n";
 if (mysqli_errno($con) !== 0) {
 echo "SQL error: ", htmlspecialchars(mysqli_error($con)), "\n";
  }
  echo "</pre>";
}

if (mysqli_num_rows($result) !== 1) {
  echo "<h1>Login failed.</h1>";
} else {
  echo "<h1>Logged in!</h1>";
  echo "<p>Your flag is: $FLAG</p>";
}

?>

The proctor gave us a hint asking "What happens if username or password contains a single quote '?

I have tried everything from ' or 1=1--

to things like ' OR a=1--

if anyone could help I would greatly appreciate it!

kero
  • 10,647
  • 5
  • 41
  • 51
TylerRutherford
  • 51
  • 2
  • 2
  • 3
  • And what happened? You might want to add `LIMIT 1` as you're only checking if there is exactly one row retrieved – kero Oct 29 '14 at 20:56
  • First, you should validate the content you got, ensure you get a valid username and HASH PASSWORDS !! Then you could use a ' escaping function like addslashes() but there is better ways depending the lib (here mysqli) – Loenix Oct 29 '14 at 20:57
  • then what do you suggest I do to validate the content – TylerRutherford Oct 29 '14 at 20:58
  • [Here is some documentation](http://php.net/manual/en/security.database.sql-injection.php) on what you're trying to achieve. Best of luck. – Baldvin Th Oct 29 '14 at 20:58
  • add LIMIT 1 to what? – TylerRutherford Oct 29 '14 at 20:59

1 Answers1

0

your problem is located in the select statement:

SELECT * FROM users WHERE username='$username' AND password='$password'

Imagine a user providing the name ' OR 1=1 LIMIT 1 -- (note the space after --) It would always exactly return ONE result row - so the login is valid, cause the query executed would be:

SELECT * FROM users WHERE username='' OR 1=1 LIMIT 1 -- ' AND password='$password' 

mysql will ignore the comment, so the query is:

SELECT * FROM users WHERE username='' OR 1=1 LIMIT 1

You should escape the values before using them:

$username = mysqli_real_escape_string($link, $_POST["username"]);

See this fiddle as example: http://sqlfiddle.com/#!2/fd8be/1 (One resultrow -> Your logic would say: "Logged in!" - without even knowing any username and/or password.)

dognose
  • 20,360
  • 9
  • 61
  • 107
  • 1
    You should rewrite this using Prepared Statements and you should talk about Password Hashing, otherwise this is not a bad answer. – DampeS8N Oct 29 '14 at 21:02
  • Those credentials still weren't valid. What would you recommend I do? – TylerRutherford Oct 29 '14 at 21:03
  • 1
    @TylerRutherford A First step would be: just echo the query instead of executing it, and check it for any malformated things. Then you can *reverse engineer* the required injection. But since I do not know, if you try to inject your own system, or something else, I will not do the task for you :) – dognose Oct 29 '14 at 21:07