2

I'm learning about SQL Injection, and I'm playing around on my local machine with vulnerable web application, which has login form.

How the login mechanism works is that it first searches whether there exists a user with the typed username in the database, if there exists, it returns the user data from the database, and then it checks whether what is typed in the password field is equal to the actual user password returned by the database. Please note that there is no hashing of the password involved.

The application uses a query like the one below to retrieve the user's data from the database: "SELECT * FROM accounts WHERE username = '" + username + "'". I already used something like this for the username field in the form: test' OR 1=1 LIMIT 1--, and this actually returns in the application the first user's data from the database (I checked this in debug mode). But, the login still fails, because as I said the password value that I entered, and the actual user's password don't match, simply, when it come to this line of code, it fails:

if (enteredPasswordField.Equals(usersPassword, StringComparison.Ordinal)) return SUCCESS;
else return FAILURE;

And as can be seen the user's password is not involved in the SQL query. I was thinking of starting a new SQL statement at the username field to change the users' password, but it kind of undermines the purpose. Any ideas how can I bypass this?

1
  • Make the injection such that it returns as a password what you want (e.g. replace the password collumn with a steady "hello") and use that as a password.
    – Tobi Nary
    Mar 31, 2016 at 14:18

1 Answer 1

5

Try appending a UNION SELECT to the SQL query.

A union-select allows the attacker to add a completely new select-statement. The results of that second select are appended to those of the first. When the first request returns no result, the union-select allows the attacker complete control over the result-set. Remember that a select-statement doesn't even need to mention a table and can return literals instead. SELECT * FROM accounts WHERE username = '' UNION SELECT 'admin', 'TotalyTheAdminsPassword', 'dummy', 'dummy', 'dummy', 'dummy' is completely valid.

A UNION SELECT means that the attacker needs to figure out the number of requested columns (the second SELECT needs to match the column-count of the first SELECT, or the database will throw an error) and which column represents which field, but an attacker can usually figure that out through experimentation.

6
  • That's what I had in mind.
    – Tobi Nary
    Mar 31, 2016 at 14:27
  • @ticket It won't tell you the password, but it allows you to provide the string which the program will then compare the content of the password-field with. If you want to know the password, you need some case where the application shows database results to the user, but your question doesn't mention anything like that.
    – Philipp
    Mar 31, 2016 at 14:45
  • @ticket Remember that you want the original query to return no results at all, so all results come from your union-select. So injecting the OR 1=1 into the first SELECT is counter-productive.
    – Philipp
    Mar 31, 2016 at 14:47
  • @Philipp I understand now. But as you have pointed out for this to work, the attacker needs to know the number o requested columns, and the only way to get that right is through trial-and-error? Or is there any other method?
    – user20878
    Mar 31, 2016 at 14:52
  • 1
    @ticket Most database systems have some special tables which contain meta-information about other tables, including the number and type of columns. Which tables these are and how they are structured depends on the database backend (for MySQL, it's INFORMATION_SCHEMA.COLUMNS). But again, obtaining information from the database first requires to find a situation where data from the database is shown to the user and then find an injection vulnerability in the query which produces that data.
    – Philipp
    Mar 31, 2016 at 14:59

You must log in to answer this question.