In our previous article we have learned about basic of Blind SQL Injection using untrusted data parsing. Today we will learn in detail about Standard SQL Injection (or Classical SQL Injection) attack in detail. Lets revisit what we have learned in previous article, we have learned about (OR 1=1) i.e. always true condition.
|Standard SQL Injection | Injection attacks – Owasp #1 Vulnerability|
Consider an example that we have a table named “users” which contains login credentials and SQL query which validates data from login table is something like below:
SELECT * FROM Users WHERE Username='$username' AND Password='$password'
If the query returns a value it means that inside the database a user with that set of credentials exists, then the user is allowed to login to the system, otherwise access is denied. The values of the input fields are generally obtained from the user through a web form. Suppose we insert the following Username and Password values:
$username = 1' or '1' = '1
$password = 1' or '1' = '1
Then the query will become something like:
SELECT * FROM Users WHERE Username='1' OR '1' = '1' AND Password='1' OR '1' = '1'
If we suppose that the values of the parameters are sent to the server through the GET method, and if the domain of the vulnerable web site is www.example.com, the request will be something like below:
After a short analysis we notice that the query returns a value (or a set of values) because the condition is always true (OR 1=1). In this way the system has authenticated the user without knowing the username and password.
In some systems the first row of a user table would be an administrator user. This may be the profile returned in some cases.
Above one was the typical example of SQL Injection which nowadays is not that much effective as most of developers use Encryption on password, usually MD5. So do imposing an encryption on passwords can protect databases? Answer is straight forward “NO”. Lets consider an another example, which contains encryption employed in it. Say developer uses below SQL Query to authenticate users on website:
SELECT * FROM Users WHERE ((Username='$username') AND (Password=MD5('$password')))
Now above query has two issues for Hackers to hack into this, first parenthesis and second one MD5 Encryption both highlighted in red. So first of all lets solve the problem of parenthesis. First of all we need to identify correct number of parenthesis specially opening ones, it is quite easy just keep on adding closing parenthesis until we get the correct number of closing parenthesis but why? Simply because we wish to bypass the second problem :D yes we want to comment the MD5 encryption within the query to bypass the authentication. Every DBMS has its own syntax for comments, however, a common symbol to the greater majority of the databases is /*. In Oracle the symbol is “–“.
In this case we will use below username and password to bypass:
$username = 1' or '1' = '1'))/*
$password = foo
So the query will become something like below:
SELECT * FROM Users WHERE ((Username='1' or '1' = '1'))/*') AND (Password=MD5('$password')))
Now due to the inclusion of a comment delimiter in the $username value, the password portion of the query will be ignored i.e. commented.
And the URL Request to execute above query will be something like :
This may return a number of values. Sometimes, the authentication code verifies that the number of returned records/results is exactly equal to 1.
In the previous examples, this situation would be difficult (in the database there is only one value per user).
In order to go around this problem, it is enough to insert a SQL command that imposes a condition that the number of the returned results must be one. (One record returned) In order to reach this goal, we use the operator “LIMIT <num>”, where <num> is the number of the results/records that we want to be returned. With respect to the previous example, the value of the fields Username and Password will be modified as follows:
$username = 1' or '1' = '1')) LIMIT 1/*
$password = foo
This will result into a query something like below:
SELECT * FROM Users WHERE ((Username='1' or '1' = '1')) LIMIT 1/* /*') AND (Password=MD5('$password')))
In order to execute above query, URL will be something like below:
http://www.example.com/index.php?username=1'%20or%20'1'%20=%20'1')) LIMIT 1/*&password=foo
The above URL will fetch the first value from the users table and will allow hackers to bypass the authentication of website.
That’s all for today. We will learn more about SQL Injection Exploitation techniques in later articles. Keep Learning!