release 0.4
Contents
Requirements
You will need the following perl modules :
- LWP::UserAgent
- DBD::SQLite
- WWW::Mechanize
And a proper Term::ReadLine package is definitely recommended (yet not mandatory)
Or, if you are on a debian system :
apt-get install libwww-perl libdbd-sqlite3-perl libwww-mechanize-perl libterm-readline-gnu-perl
You will probably also want to install sqlite3, the command line interface for SQLite 3.
How to use
When starting a new session (new target), the simplest way is to copy conf.pm to targethost.conf.pm, edit it the way you want, then : ./sqlsus -c targethost.conf.pm
If you don't want to run sqlsus interactively, use the -i switch, i.e. : ./sqlsus -c targetconf.pm -i 'select version()'
Note that conf.pm will be sourced first, then whatever configuration file you specified.
This allows you to have a tiny configuration file only overriding the values different from the default ones.
Inband / Blind
Inband means that the answer will be seen via the same channel the injection took place (the result of the query will be in the HTML)
Blind means that the result cannot be directly read, and that we have to guess what it is.
To make both of them really fast, sqlsus uses some neat features, to address the fact that MySQL does not support stacked queries and that there was no SLEEP function before MySQL 5.0.12
On Inband mode, sqlsus will stack as much subqueries it can per query as long as it doesn't hit either max_subqueries or max_sendable.
On Blind mode, sqlsus will :
- match each item against a set of regex, to lower the character space to use to bruteforce the item.
- find the length of the item
- bruteforce each character with the character space found (or using default_range if none were)
Tasks are divided per thread (actually, process) :
- match RE + find length
- bruteforce char
sqlsus will take care that threads remain as busy as possible, and as long as it makes sense (avoid unneeded hits).
Note that in inband mode, it is generally a good idea to make the real query return nothing (append AND 1=0 for example)
Commands
You can break a command by using Ctrl+C.
start
In inband mode, this command will find the columns for UNION. That means that, up to a configurable value, sqlsus will inject a query with one more item at each iteration, using sql's HEX() function, and looking at the HTML for the hex values, to be sure that it has been parsed by the SQL server.
In all modes, it will fill %target, which is a hash containing useful variables about the target (by default: current_user(), database() and version())
use
alias to set database, allows you to change the current database to another one and still be able to use all the commands transparently.
get
If the target database is MySQL 5 or newer, and you can read from the system tables, then this command will help you fetch the database structure :
tables
Get the names of the tables for the current database
columns [table_name]
Get the names of the columns [for the specific table]
count [table_name]
For (the specified|each) table that show db will display, get count(*) to know how many items are inside (useful to detect interesting tables).
db
Same as get tables + get columns + get count.
privs
Get the privileges for the user.
databases
Get the names of all the databases.
brute
If the target database is older than MySQL 5, then this command will help you bruteforce the database structure :
tables
Bruteforce the name of the tables, prefix with table_prefix.
sqlsus will take its input from a dictionary, defined in brute_table_dict, and depending on the configuration (uc_first and uc_all) will, for each item tried, try the uppercase and/or uppercase_first version of the word.
If the dictionary attack fails, it will be replaced by an exhaustive bruteforcer (chars a to z).
columns
same as for tables, but only try one case per item, since MySQL discards the case for the columns.
show
This command shows items already grabbed through get, brute or start :
target
Show the target variables (by default : user / database / version)
privs
Show the privileges associated with the user
db
Show the db (with tables / columns / count if available)
all
Same as show target + privs + db
tables
Show the tables of the target database
columns [table_name]
Show the columns of the target database [for the specific table]
describe is an alias to show columns.
set
Allows you to set some variables on the fly, such as document_root (cf takeover demo)
These variables override what is inside the configuration file.
usage: set variable value or set variable "value"
select
Just type a normal SQL SELECT query, and sqlsus will cut it, re-arrange it.
In inband mode, sqlsus will use as many subqueries it can fit in max_sendable, limited to max_subqueries per query.
You can see how the queries are injected by turning debug mode on : set debug 1
The result will be printed in a mysql shell like box, and stored into the session database.
find
On MySQL >= 5, find the tables that have a certain column. You can use SQL wildcards.
eg: find "pass%" will find all the tables in the target database that have at least one column starting with pass
eval
eval perl code from within sqlsus, this allows you to play with the (dirty) internals of sqlsus.
!
execute a command on the local system
download
If you have the FILE privilege, you can download any world readable file, via SELECT LOAD_FILE.
download is just a simpler way to do that, since it removes the unneeded HTML and stores the file in a local tree, starting at files_path
eg: download /etc/passwd will display the remote file /etc/passwd and store it in your local system at $PWD/$server/$files_path/etc/passwd
upload
If nothing has been done yet, depending on the configuration (upload_directories set or not), sqlsus will crawl the website looking for directories, and try to upoad the PHP uploader on each one (smartly).
If the tiny PHP uploader has been uploaded (via SELECT INTO OUTFILE), then sqlsus will upload the requested file via POST through it (be aware of possible POST size restrictions).
If the target file has a relative path (eg: upload shell/backdoor.php backdoor.php), sqlsus will output the URL to access the file.
clone
usage: clone [table [column,column,..]] clone current database [or just a table [and just some columns]] to a local SQLite database
It can be resumed over sessions, it will start after the last fetched row, up to count(*).
backdoor
You will find a PHP backdoor ready to use in shell/backdoor.php.
To use it, upload it first of course, and then use : ./control_backdoor URL_TO_BACKDOOR [sql credentials]
See the takeover demo for an example on how to use it.
It is really simple and straight forward, 3 modes : exec, php, sql (eg: use mode php to switch to the php mode)
- exec : try to execute via any available system()-like function the command (won't work in safe_mode)
- php : eval php code
- sql : inject SQL queries (SELECT, UPDATE, CREATE, DROP...) in a mysql-like shell.
You can use a file as input, by using < file inside the shell.
Configuration file
Generic options
url_start
Start of the URL : what is before the injection point.
Note that sqlsus will inject this way : url_start . injection . url_end
So if you need a space between the injection point and the start / stop of the URL, put it, no space will be created for you, in order to shorten the query as much as possible.
Note that you may want to add a AND 1=0 at the end of url_start, so that the original query returns nothing, which is usually a good idea when it comes to UNION.
url_end
End of the URL : what is after the injection point.
Again, if needed, prepend a space.
user_agent
The user agent to use for HTTP queries
eg: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
blind
If the injection is blind, set this variable to 1, and set string_to_match accordingly
string_to_match
In blind mode, string to be found in the HTML when the statement is true
Example : What will be seen in the HTML for http://host/script?id=1 AND 1=1 but not for http://host/script?id=1 AND 1=0
post
Set to 1 if you want to use POST instead of GET.
debug
Set to 1 if you want debug messages, such as when sqlsus sends a request to the server.
null_substitute
Character (not string !) to display when the data is NULL.
hex_encode_strings
Set to 1 to encode strings in their hex equivalent.
Ex: "sqlsus" will become 0x73716c737573
processes
Set to the number of children sqlsus should spawn (only used in blind injection)
http_proxy
Set to the URL of the HTTP proxy you want to use, or leave blank if you don't need any.
cred_realm, cred_user, cred_password
realm, username and password required on a simple HTTP auth.
max_sendable
Maximum sendable chars to the server, usually 4096 for GET, and way more for POST.
max_subqueries
Maximum number of subqueries per query, to disable the usage of subqueries, set it to 0
convert_spaces
Convert spaces to /**/
cookie
Cookie to use, separate name=value pairs with ;
sleep_after_hit
Number of seconds to sleep after each hit to the web server. Set it to 0 to disable.
This is a simple sleep(), after each url fetching.
Note that you can use floating values, because sqlsus uses Time::HiRes
Data
datapath
Set to the directory where session data (including log file) should go.
These files will be written under ./server/$datapath
filespath
Set to the directory where the files downloaded via download should go.
These files will be written under ./server/$filespath
Inband mode
max_select_cols
Maximum number of columns to try in the union statement before exiting.
columns
columns usable for injection using UNION. This is a perl array.
The first value that is 1 in the array will be used as the injection point, the others will be used as is.
Unless this variable is set, sqlsus will auto-detect the suitable number of columns as well as wish can be used for injection.
union_select
string to use for UNION, because sometimes UNION ALL SELECT is not what you want.
Blind mode
verbose_blind
Set to 1 to display the progress of data fecthing.
default_range
Default character space to use when bruteforcing an item, if no regex matched the item.
The characters are ASCII numbers separated by a comma.
regex_rlike
regexs to test against each item retrieved on a blind injection, and the corresponding ASCII values. They will be tried in order, and the values must be sorted.
max_length
Maximum length of an item above which sqlsus will stop guessing.
Takeover
document_root
Set it to the document root of the target web server, so that sqlsus knows where to upload the PHP uploader.
upload_directories
Set it to the directories that should be tried to upload the PHP uploader, we need a writable for everybody directory.
Leave the array empty to let sqlsus crawl the website for candidate directories, and set max_depth.
crawler_depth
Maximum depth sqlsus should go to, when crawling the website.
uploader
If the PHP uploader has already been uploaded, set this variable to the URL.
Note you shouldn't need to set this variable here, since it will be remembered across sessions.
Core
target_at_start
Array of target keys to get when using start
You may want to reduce it to database only when you are in blind mode, to limit the number of hits for mandatory information.
SQLite backend
You can access the SQLite backend directly from the command line with SQLite3.
The queries and the associated table are stored in the table queries.
The real names of the columns are stored in the table tables.
databases structure in table databases, history in table history, privileges in table privileges, and variables in table (how surprising) variables.
To store queries results, sqlsus does not use real column names directly to avoid several possible issues, some of them being reserved words and quotes (eg: if you provide "select NULL", sqlsus would have to create a column named NULL, which won't be allowed.)
When you use clone, the resulting tables / columns, are actual real names, so you can "edit" the database with SQLite3 directly.
Known bugs / limitations
sqlsus won't work on binary data, this is because it focuses on shortening the query as much as possible, and as a result only uses two chars (\x05 and \x07) as separators. A binary mode switch will be added in a future release.