SQLInjections are my favorite web exploit because databases hold all the goodies to a system. With password reuse to common, if you pop a password for a user in a SQL DB from a website, it’s highly probable that user has the same password for their Active Directory credentials, including administrators.
First let’s talk about fuzzing. Fuzzing is the process of testing for errors and information in general. A simple example in Mutillidae is seeing if a user exists.
In the intial login page, the form will tell you that an account does not exist or a password is incorrect, not both at the same time. So if I enter “hello” as a username, it says this account does not exist.
However if I put in “Jeremy” with no password, it returns saying my password is incorrect. So we know Jeremy is a user.
Now that we know what fuzzing is, lets try it with actual SQL commands.
SQL Databases have special characters. They’re specific (some shared) to each specific SQL DB (MySQL, SQLLite , PostgreSQL), but an example of special characters for MySQL are:
\0An ASCII NUL (0x00) character.
\'A single quote (“
\"A double quote (“
\bA backspace character.
\nA newline (linefeed) character.
\rA carriage return character.
\tA tab character.
\ZASCII 26 (Control-Z). See note following the table.
\\A backslash (“
%” character. See note following the table.
_” character. See note following the table.
So if we enter a special character that isn’t properly sanitized (escaped, to prevent SQLi), we should get a SQL syntax error. Testing this out on the login page confirms.
So the query on the back end is SELECT username FROM accounts WHERE username = ‘’ AND password=”;
The first SQL Injection is very simple, and that’s entering: ‘ or 1=1 – note: there’s a space after the two hyphens.
Which logs you in as admin.
Why does this work:
The SQL query is SELECTing a username FROM the accounts table and is getting the first username in the table (the closed quotes do not specify a specific username, so it just logs you in as the first entry. This could mean admin was the first username entered or is the first name alphabetically, depending on how the SQL DB is structured. Finally, the last part of the injection “—“ (two hyphens and a space) are commenting out the rest of the query, which in this case would be AND password=, so the two hyphens tell SQL to just ignore that bit of the query since it’s a comment. The space after the two hyphens is very important because without it, SQL just thinks that’s part of the actual query (–AND password=’) which will throw a syntax error.
Similarly, this works with a known user. With fuzzing, we know jeremy is a user.
So what if put in Jeremy as a user and: ‘ or 1=1 — ?
It still logs in as admin. This is because the “or” is applied outside of brackets, so the entire statement is just ‘or 1=1 – and once again logs us in as the first record in the DB. If we do: ‘ or (1=1 and username = ‘jeremy’) — it then logs in as Jeremy.