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?

  • 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 at 20:10
  • look at my edit – Joe Santiago Mar 3 at 20:14

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'
SELECT null, password, null, ... FROM login WHERE email = 'admin@example.com'

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).

  • but it returns a column with name "password" with all the passwords. I want a column with name "first_name" with all the passwords.... – Joe Santiago Mar 3 at 21:15
  • @JoeSantiago Just use an AS clause on the password column. – Polynomial Mar 3 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! – Joe Santiago Mar 3 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 at 21:43
  • thanks a lot! I do understand now!! Amazing! Thanks – Joe Santiago Mar 3 at 21:51

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.