2

I'm trying out SQL Injection on my localhost. I have a simple HTML form, with a username, password and a submit button. So after clicking on the submit, user is redirected from login.html to a page called login.php:

<form method="post" action="login.php"> 

Below is a snipped of my PHP code:

$connect = mysqli_connect($dbhost, $dbuser, $dbpass) or die("Unable to connect to '$dbhost'");
mysqli_select_db($connect,$dbname) or die("Could not open the database '$dbname'");

$message="";
$username = $_POST["uname"];
$pass_raw = $_POST["password"];
$password = md5($pass_raw);

$result = mysqli_query($connect,"SELECT *  FROM students WHERE uname='" . $username . "' and password = '". $password."'");
$row = mysqli_fetch_array($result);

if(is_array($row)) {
    echo "Congratulations! you have logged in!";
    printf("Your First Name %s and Last Name is %s", $row[3], $row[4]);
    printf("Your SSN is %s ", $row[5]); 
} else {
    $message = "Invalid Username or Password!";
    echo "invalid user ";
}

I'm able to login to the if I enter the right user and password. I'm trying to perform SQL Injection, but I'm unable to. I have tried using ' or ''=' but I'm still not able to login. I'm trying this out in Kali, which comes pre-installed with MariaDB.

  • Can you make it return the actual SQL queries it runs? That way, you will be able to see what the queries look like after your injection attempt. It will help you find the problem. – Anders Apr 13 '18 at 9:58
  • In which field are you trying the injection? Do note that password field is hashed so the only field in this case it would work is the username field. – bradbury9 Apr 13 '18 at 11:26
6

In MariaDB the comments must be followed by a space:

From a '-- ' to the end of a line. The space after the two dashes is required (as in MySQL).

Please try ' OR 1=1 --[space].

  • It worked. When I entered ' OR 1=1 --[space] in the username field. It retrieved the first row of information! – oceans25 Apr 13 '18 at 17:07
3

First thing to note here is that you can only inject in the username, and not in the password. Any payload you put into the passwrod will be destroyed in the hashing.

So what happends if set the username to ' OR '' = '? Let's write it out:

SELECT * FROM students WHERE uname='' OR '' = '' AND password = '$password'

Due to the fact that AND has higher precedence than OR in SQL, it gets interpreted as this:

SELECT * FROM students WHERE uname='' OR ('' = '' AND password = '$password')

As you can see, both the left and right sides of the OR will always be false unless there is a user without a name or you provide an existing password.

Instead, try making an injection so you end up with a query similar to one ot these, depending on if you want to specify a username or not:

SELECT * FROM students WHERE uname='' OR uname='admin' -- ' AND password = '$password'
SELECT * FROM students WHERE uname='' OR 1=1 -- ' AND password = '$password'

So what is the lesson here? Always write out the query that you think your injection will result in. Analyze it and make sure the SQL actually does what you want it to do.

1

Seems your username is vulnerable password is safe.

Try 'or 1=1--, so it comments the query after the username.

  • I tried it. Still doesn't work. – oceans25 Apr 13 '18 at 3:31
  • @oceans25 Can you clarify what "doesnt' work" mean? Do you get the "Invalid username or password!" page? – Anders Apr 13 '18 at 9:57
  • Correct. When I enter 'or 1=1-- in the username and/or the password field, the "Invalid user" message is displayed. – oceans25 Apr 13 '18 at 17:01
0

When you enter the single quote character in a SQL injection attack, you are escaping the code of the page to continue processing. If you initially entered ' or ''=', you have no inserted valid SQL to enable your database to return a valid result. The first quote exits the "username" variable, which equates to:

$result = mysqli_query($connect,"SELECT * FROM students WHERE uname='' or ''='' and password = '". $password."'");

If you instead use ' or 1=1 -- then your resultant expression is: $result = mysqli_query($connect,"SELECT * FROM students WHERE uname='' or 1=1 --' and password = '". $password."'");

In SQL, everything after the double-hyphen is a comment and is ignored, so we could technically omit everything after them. But the meaningful expression ends up select * from students where uname='' or 1=1. 1=1 of course evaluates to "true" so then we select * from students where uname is set.

The only reason you don't see all records is because this vulnerable application prints the first row of your results. To collect more than one record, you would need to start modifying your injected query to ' or a* --, ' or a% -- or similar, depending on the SQL server you're testing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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