GPLv2
GPLv2
N/A
N/A
GPL
N/A
0.6
0.9.0.9
1.0
1.41
1.0.0
1.0
Bernardo Damele, bernardo.damele at gmail dot com and Daniele Bellucci, daniele.bellucci at gmail dot com
Ferruh Mavituna, ferruh at mavituna dot com
Cedric COCHIN, cedric.cochin at gmail dot com
Nummish, nummish AT 0x90.org
Francisco Amato, famato at infobyte dot com dot ar
ZwelL, zwell at sohu dot com
Python
VB.NET
Perl
VB.NET
Perl
C++
N/A
.NET Framework 3.5
Algorith::Diff, WWW::CheckSite, Tie::CharArray
.NET Framework 1.1
Convert::EastAsianWidth, Unicode::EastAsianWidth and optionally GraphViz/IPC::Run
N/A
http://sqlmap.sourceforge.net/#download
http://labs.portcullis.co.uk/download/BSQLHackerSetup-0907.exe
http://cedri.cc/tools/SQLiX_v1.0.tar.gz (broken)
http://www.0x90.org/releases/absinthe/Absinthe-1.4.1-Source.tar.gz
http://www.infobyte.com.ar/down/ISR-sqlget-1.0.0.tar.gz
http://www.nosec.org/projects/pangolin_bin.rar (broken)
Win2k3 sp1 Sun VirtualBox image with Python 2.5 MSSQL 2005 EE, Oracle 10g EE, DB2 EC v 9.5, PostGreSQL 8.3, MySQL Community 5.0.45
Win2k3 sp1 Sun VirtualBox image with Python 2.5 MSSQL 2005 EE, Oracle 10g EE, DB2 EC v 9.5, PostGreSQL 8.3, MySQL Community 5.0.45
Win2k3 sp1 Sun VirtualBox image with ActivePerl 5.8.8 Build 822 MSSQL 2005 EE, Oracle 10g EE, DB2 EC v 9.5, PostGreSQL 8.3, MySQL Community 5.0.45
Win2k3 sp1 Sun VirtualBox image with Python 2.5 MSSQL 2005 EE, Oracle 10g EE, DB2 EC v 9.5, PostGreSQL 8.3, MySQL Community 5.0.45
Win2k3 sp1 Sun VirtualBox image with ActivePerl 5.8.8 Build 822 MSSQL 2005 EE, Oracle 10g EE, DB2 EC v 9.5, PostGreSQL 8.3, MySQL Community 5.0.45
Win2k3 sp1 Sun VirtualBox image with Python 2.5 MSSQL 2005 EE, Oracle 10g EE, DB2 EC v 9.5, PostGreSQL 8.3, MySQL Community 5.0.45
Bedirhan Urgun, urgunb at hotmail dot com
Mesut Timur, mesut at h-labs dot org
Bedirhan Urgun, urgunb at hotmail dot com
Mesut Timur, mesut at h-labs dot org
Bedirhan Urgun, urgunb at hotmail dot com
Mesut Timur, mesut at h-labs dot org
01 Aug 2008
01 Aug 2008
16 Aug 2008
15 Aug 2008
25 Aug 2008
01 Sep 2008
Command line
Command line and GUI
Command line
GUI
Command line
GUI
Resume with -o and -r command line options
Start/Stop on GUI
N/A
N/A
N/A
Start/Stop/Resume on GUI
http://sqlmap.svn.sourceforge.net/viewvc/sqlmap/doc/README.html
http://bsqlhacker.googlecode.com/files/BSQL%20Hacker%20Manual.pdf
http://www.owasp.org/index.php/Category:OWASP_SQLiX_Project#Command_line_usage
http://www.0x90.org/releases/absinthe/docs/
README file with the source
http://www.nosec.org/web/pangolin_manual (in chinese)
dbms banner, current user, current database, database users, database users password hashes
banner, current user/database
dbms banner
current user
N/A
version, current database, current user, privilege, databases, drives, localgroups, privilege of user
Yes with --dbs option
Yes with some special exploit string
N/A
N/A
Yes
Yes with databases from information menu
Yes with --tables and -D options
Yes with some special exploit string or automated attack
N/A
Yes with "Load Table Info" button.
Yes
Yes from "Datas" menu.
Yes with --columns, -D and -T options
Yes with some special exploit string or automated attack
N/A
Yes with "Load Field Info" button.
Yes
Yes from "Datas" menu.
Yes with --dump, -D, -T and optionally -C options
Yes with some special exploit string or automated attack
N/A
Yes with "Download Records" button.
Yes
Yes from "Datas" menu.
1361
1634
973
N/A
N/A
N/A
376
771
297
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
467
779
N/A
N/A
N/A
N/A
198
224
110
N/A
N/A
N/A
N/A
1626
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
224
N/A
N/A
N/A
N/A
46
N/A
N/A
N/A
N/A
N/A
20
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
20
N/A
N/A
N/A
N/A
N/A
66
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
1
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
241
39
270
470
N/A
N/A
75
74
111
139
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
33
45
N/A
36
N/A
N/A
162
163
163
N/A
N/A
N/A
N/A
35
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
163
N/A
N/A
N/A
N/A
46
N/A
N/A
N/A
N/A
N/A
20
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
20
N/A
N/A
N/A
N/A
N/A
66
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
1
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
Yes with --basic-auth option
Yes from "Settings" menu
N/A
Yes
Yes
N/A
Yes with --digest-auth option
Yes from "Settings" menu
N/A
Yes from "Authentication" menu
N/A
N/A
Yes with --cookie option
Yes
Yes with --cookie option
Yes from "Cookies" tab.
Yes with $conf::cookie, @conf::cookies options in the related session perl file
N/A
N/A
Yes from "Settings" menu
N/A
Yes from "Authentication" menu
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
N/A
Yes
Yes
Yes
Yes
N/A
Yes
Yes
Yes
N/A
Yes
N/A
N/A
Yes
Yes
Yes
Yes
Yes
Yes
N/A
Yes
N/A. Only for fingerprinting
Yes
N/A
N/A
N/A
Yes
N/A
Yes
N/A
N/A
N/A
N/A
Yes with --union-use option
N/A
N/A
N/A
Yes
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
Yes with --user-agent or -a options
Yes
Yes with -agent option
Yes
Yes with $conf::ruseragent, $conf::ruseragentfile and $conf::uagent options in the related session perl file.
Yes from "Options" menu
Yes with --referer option
Yes
Yes with -referer option
N/A
N/A
Yes by adding HTTP headers.
Yes with --proxy option
Yes
N/A
Yes
Yes with $conf::proxy_host, $conf::rproxy and $conf::rproxyfile options in the related session perl file
Yes
N/A
Yes
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
EXP
<ol>
<li>
modsecurity <= 2.1.0 bypass
</li>
<li>
full_width/half_width encoding bypass
</li>
<li>
(random) delay between connections
</li>
<li>
case transformations
</li>
</ol>
N/A
Yes with --sql-query option
Yes
Yes with -function option
N/A
N/A
N/A
Yes with --threads option
Yes
N/A. But the algorithm employed permits concurrency.
Yes
N/A. But the algorithm employed (especially table row dumps) permits concurrency
N/A
N/A
Yes
N/A
N/A
N/A
N/A
Yes with --update option
Yes
N/A
N/A
N/A
N/A
Yes with -eta option
N/A
N/A
N/A.
N/A
N/A
Yes with -f option
Yes
N/A
Yes
N/A
N/A
Yes with --method option
Yes
Yes
Yes
Yes
Yes
Yes with --method and --data options
Yes
Yes
Yes
Yes
Yes
N/A
N/A
N/A
N/A
N/A
N/A
Cookie, User-Agent
Yes
N/A
N/A
N/A
N/A
Yes with -v option
Yes from "Request History" menu.
Yes with -v option
Yes from command line window.
Yes with -v option
N/A
Yes with -v option
N/A
N/A
N/A
Yes. Produces csv and html dumps default. <br/> Plus an excellent graphical representation of the db schema under a linux distro or cygwin environment. <br/> Sqlget needs dot command for drawing directed graphs.
N/A
Yes
Yes
Yes
Yes
N/A. The exploit payload should be written manually by manipulating $conf::inj param in related session perl file
Yes
N/A
N/A
N/A
N/A
N/A
N/A
EXP
<ol>
<li>
request to test connection
</li>
<li>
requests to test url stability
</li>
<li>
request for testing whether the parameter in question is dynamic (using a numeric value: 47)
</li>
<li>
request for testing whether the parameter in question is dynamic (using single quoted string: 'NoValue)
</li>
<li>
request for testing whether the parameter in question is dynamic (using double quoted string: "NoValue)
</li>
<li>
request for tests if the parameter is numeric injectable
</li>
<li>
request for tests if the parameter is string/single quote injectable (matches with original
</li>
<li>
response's md5 or the keyword provided with --string option)
</li>
</ol>
<br/>
sqlmap utilizes the same binary search algorithm for both numeric and character injections.
How does sqlmap understand fetching is over? It tries the extra (nonexisting)character and
during the binary search ASCII value diminishes to 0, which means an extra of 6 requests
for every single output. (63, 31, 15, 7, 3, 1)
<br/><br/>
When we add the fixed 11 requests executed prior to any data fetch, the number of requests
performed for any exploit becomes;
<br/><br/>
f(n) = 7*n + 6 + 11, where
<br/><br/>
n is the length of the data being fetched,
<br/><br/>
6 is the # of requests to understand the End Of Input, and
<br/><br/>
11 is the # of requests executed prior to any data fetch.
<br/><br/>
Why 7*n? Let's look at the below sqlmap debug log, where we're trying to blindly fetch '?' character,
which is ascii 63. It takes 7 requests to find '?', although 63 is the first to be compared.
So, for length 1, 7*1+6 = 13. The binary search employed produces a fix 7 requests for all the characters!
N/A
EXP
<ol>
<li>
Finds the base MD5 of the original response, stores it both (MD5 and the original response).
</li>
<li>
Injects the actual exploit payload (let's say PENELOPE' AND '1'='1) and gets a response, evaluates MD5.
</li>
<li>
Compares the MD5s.
</li>
</ol>
<br/>
This algorithm is used in general, however, when the response changes with the actual exploit payload
(whether right payload or not), although the query works MD5s won't match. SQLiX automatically finds
the different lines (called Delta) and searches the unescaped injection string (PENELOPE' AND '1'='1
in our example) in the delta. If it's there, then it accepts as the confirmation of the existence of
the vulnerability.
<br/><br/>
Other tools accept a keyword/regex, which exists/matches both in the original response and the response
fetched via the right exploit payload.
<br/><br/>
Sqlix has a unique way of determining length of a string or ascii value of a character or what a number
is. It utilizes bitwise shifting/divison by powers of two. In mysql, sqlix uses bitwise shifting and it
shifts the argument to right by starting from 7 to 1, which makes 8 fix requests for every single dump.
<br/><br/>
In mssql this is power, which is basically the same thing as mysql.
<br/><br/>
Moreover, as shortcuts, when fetching the banner for example, sqlix locates (searches) chunks of
predetermined strings in the banner by using db specific functions (in mysql it is Locate, in mssql
it is PATINDEX). For example, sqlix searches for keywords like "Microsoft", "Debian", "community" e.t.c.
But this is not enough, so for the banner parts that can't be found in the first pass, sqlix falls back
to blind sql injection technique described above.
<br/><br/>
This algorithm is not the generally implemented binary search (bisection) and results in fix number
of requests (8) for every character. Therefore, the complexity can be determined as O(n), O(8n),
where n is the length of the single piece of information fetched.
EXP
When program searchs for an integer(not an ascii value), it is using a list of integers for comparisons.
The list goes from 0 to searching id's max limit, which have been growing by factor 2. First it founds
the searching value's number-interval then performs binary search to find it's certain location. Finally,
performs a simple check. It's practice will be on fetching username stage.
<br/><br/>
# of Reqs =O(ceiling (log n) +1 +floor(logn) + 1)
<br/><br/>
<ol>
<li>
ceiling returns the smallest whole number greater than or equal to the specified number. For example,
ceiling( 2,3) equals 3.
</li>
<li>
floor returns the largest whole number less than or equal to the specified number.For example
floor( 2,7) equals 2.
</li>
<li>
log n's base is 2.
</li>
</ol>
<br/><br/>
In detail, ceiling (log n) +1 is for determining the integer's interval and the max limit of length.
After that, finding the certain integer costs floor (logn), finally Absinthe performs one check.
<br/><br/>
Some Basic Practices
<br/>
For example; about determining 5 character username :
<br/>
<ol>
<li>
length == 0 -- > False
<br/>
</li>
<li>
length > 2 -- > True
<br/>
</li>
<li>
length > 4 -- > True
<br/>
</li>
<li>
length > 8 -- > False,*
<br/>
</li>
<li>
length > 6 -- > False
<br/>
</li>
<li>
length > 5 -- > False
<br/>
</li>
<li>
length > 4 -- > True,**
<br/>
</li>
</ol>
<br/><br/>
*At 4.step; max limit is found also the length's interval is fixing between 4 and 6.
<br/><br/>
** At 7. step; validation process goes on.
<br/><br/>
Here n=5, and there must be 7 check to find the length of the username as you have
seen following. In our formula :
<br/><br/>
# of Reqs =O( ceiling (log n) +1 +floor(logn) + 1) -- > # of Reqs = 3 + 1 + 2 + 1 = 7
N/A
N/A
EXP
<ol>
<li>
request to test connection
</li>
<li>
requests to test url stability
</li>
<li>
request for testing whether the parameter in question is dynamic (using a numeric value: 47)
</li>
<li>
request for testing whether the parameter in question is dynamic (using single quoted string: 'NoValue)
</li>
<li>
request for testing whether the parameter in question is dynamic (using double quoted string: "NoValue)
</li>
<li>
request for tests if the parameter is numeric injectable
</li>
<li>
request for tests if the parameter is string/single quote injectable (matches with original
</li>
<li>
response's md5 or the keyword provided with --string option)
</li>
</ol>
<br/>
sqlmap utilizes the same binary search algorithm for both numeric and character injections.
How does sqlmap understand fetching is over? It tries the extra (nonexisting)character and
during the binary search ASCII value diminishes to 0, which means an extra of 6 requests
for every single output. (63, 31, 15, 7, 3, 1)
<br/><br/>
When we add the fixed 11 requests executed prior to any data fetch, the number of requests
performed for any exploit becomes;
<br/><br/>
f(n) = 7*n + 6 + 11, where
<br/><br/>
n is the length of the data being fetched,
<br/><br/>
6 is the # of requests to understand the End Of Input, and
<br/><br/>
11 is the # of requests executed prior to any data fetch.
<br/><br/>
Why 7*n? Let's look at the below sqlmap debug log, where we're trying to blindly fetch '?' character,
which is ascii 63. It takes 7 requests to find '?', although 63 is the first to be compared.
So, for length 1, 7*1+6 = 13. The binary search employed produces a fix 7 requests for all the characters!
EXP
BSQL Hacker, performs binary search according to the given character set. Default character set is :
<br/><br/>
!"#$'()*+,-./0123456789;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]_abcdefghijklmnopqrstuvwxyz{|}
<br/><br/>
So that, it perfoms searching between 32 and 125
<br/><br/>
O log(125-32) = O log(93) = ~ 7
<br/><br/>
steps must be done to determine the searching value.But some situations,request is not equal to the step.
For example, if you present the numbers as a tree, when you are going to lef side you must perform two
checks.So that one characters may cost 12 requests or 4 requests.
<br/>
If we want to calculate the average number of requests, first we must calculate the sum request for fetching
all the characters between 32 and 126. Then, we must divide it with the number of characters.
<br/><br/>
<pre>
for(int i=32;i<126;i++)
{
sum+=BinarySearch(array,i);
}
printf("%d",sum/(126-32)));
</pre>
<br/><br/>
For example that piece of code can calculate the average of request for a character, which is:
<br/><br/>
7
EXP
<ol>
<li>
Finds the base MD5 of the original response, stores it both (MD5 and the original response).
</li>
<li>
Injects the actual exploit payload (let's say PENELOPE' AND '1'='1) and gets a response, evaluates MD5.
</li>
<li>
Compares the MD5s.
</li>
</ol>
<br/>
This algorithm is used in general, however, when the response changes with the actual exploit payload
(whether right payload or not), although the query works MD5s won't match. SQLiX automatically finds
the different lines (called Delta) and searches the unescaped injection string (PENELOPE' AND '1'='1
in our example) in the delta. If it's there, then it accepts as the confirmation of the existence of
the vulnerability.
<br/><br/>
Other tools accept a keyword/regex, which exists/matches both in the original response and the response
fetched via the right exploit payload.
<br/><br/>
Sqlix has a unique way of determining length of a string or ascii value of a character or what a number
is. It utilizes bitwise shifting/divison by powers of two. In mysql, sqlix uses bitwise shifting and it
shifts the argument to right by starting from 7 to 1, which makes 8 fix requests for every single dump.
<br/><br/>
In mssql this is power, which is basically the same thing as mysql.
<br/><br/>
Moreover, as shortcuts, when fetching the banner for example, sqlix locates (searches) chunks of
predetermined strings in the banner by using db specific functions (in mysql it is Locate, in mssql
it is PATINDEX). For example, sqlix searches for keywords like "Microsoft", "Debian", "community" e.t.c.
But this is not enough, so for the banner parts that can't be found in the first pass, sqlix falls back
to blind sql injection technique described above.
<br/><br/>
This algorithm is not the generally implemented binary search (bisection) and results in fix number
of requests (8) for every character. Therefore, the complexity can be determined as O(n), O(8n),
where n is the length of the single piece of information fetched.
EXP
Absinthe extracts strings letter by letter. It simply performs binary search between 19433 and 0.
<br/><br/>
That is, from 19433 to 76 or 38, 9 or 10 checks will always be performed and this is generally unnecessary
because there isn't any ascii alphabet character is bigger than 122. Finally, there will be a simple
check costs one request.
<br/><br/>
Our equation should be 9 + log(152-76) or 10 + log(76-38) and both of them can be showed that :
<br/><br/>
10 <= # of Reqs <= 15
N/A
N/A
EXP
<ol>
<li>
request to test connection
</li>
<li>
requests to test url stability
</li>
<li>
request for testing whether the parameter in question is dynamic (using a numeric value: 47)
</li>
<li>
request for testing whether the parameter in question is dynamic (using single quoted string: 'NoValue)
</li>
<li>
request for testing whether the parameter in question is dynamic (using double quoted string: "NoValue)
</li>
<li>
request for tests if the parameter is numeric injectable
</li>
<li>
request for tests if the parameter is string/single quote injectable (matches with original
</li>
<li>
response's md5 or the keyword provided with --string option)
</li>
<li>
requests are for matching paranthesis, ?
</li>
<li>
requests for matching column count
</li>
<li>
request for validating the inband injection with injecting a "__START_23424_STOP__" string into the output for parsing
</li>
<li>
requests get colum names and types from the requested table from requested database (second one is for confirmation)
</li>
<li>
actual request to get the data (second one is for confirmation) in one concat, so it's easy to parse the output.
</li>
<ol>
N/A
N/A
N/A
EXP
<b>,'abc','1970-01-01 00:00:00' from -- " ]]></b>
<br/><br/>
is used as a template for fetching both schema and actual table rows. <VALUE> is comprised of values
fetched with [__] spilled between (for parsing).
<br/><br/>
There are two phases of exploitation; fetching db schema and fetching actual rows according to the db schema.
First phase takes 1 reqeuest (for MSSQL it takes 1 + # of databases), second phase takes n requests, where n
is the # of tables in the schema fetched during the first phase. By manipulating the schema file n can be
reduced to critical tables. Over all, complexity of sqlget union algorithm can be described as O(n)+1,
where n is the number of tables and 1 is for the initial schema fetching (k for MSSQL).
N/A
N/A
EXP
It is a time based attack and the characters must be identified by waiting time. One character identifies
by 2 request. It's not a suitable method for busy or which have long response time servers.
N/A
N/A
N/A
N/A