SQL injection (SQLi) is a web security vulnerability that allows an attacker to interfere with an application’s queries that makes to its database. It generally allows an attacker to view data that they are not normally able to retrieve. This might include data belonging to the other users, or any other data that the application itself can access. In many cases, an attacker can modify or delete this data causing persistent changes to the application’s content or behavior.
It is one of the most common vulnerabilities in web penetration testing. The tools that we used to exploit SQLi are SQLMap, Burp Suite, and online tools. Here, we tried to automated the injection and came across a few problems on the journey. Before addressing the problems, let’s look at the scenario.
About The Application:
The application that we are up against is a portal to deal with suppliers and vendors. Which has various functionalities such as details of suppliers/vendors. Additionally, the creation, modification, deletion, approval, and rejection of tickets generated by other users over an issue, they(supplier/vendors) face during the course of action.
SCENARIO:
This web application has a table displaying the issues raised by the other users and it has search functionality.
The first problem here is, all the request that is been sent to the server is encrypted. Hence, automating this becomes a problem as the request is encrypted. Note that it is sent without query-parameter format i.e: key=value.
The second problem is, to automate, even if we solve the 1st problem SQLMap will only accepts the query parameter format which is not present.
We begin with searching for the issues raised by a specific user’s SSOID that contains 175, and the issues raised by that particular user are returned. (Figure 1)
Figure 1
To test, we entered 175’ and it returned no result. With this behavior, we now suspect a possible SQL injection. As we know the request is sent in the encrypted format, we tried to balance the query through web interface only with a “- -” (double-dashed comment) i.e., 175’- –. Due to this, we successfully got the result of the user.
For further confirmation, we injected a Boolean-based payload. First, we injected a query that returns ‘FALSE’ i.e., 175’ AND 1=2–. The data is not returned as shown in Figure 2.
Figure 2
Later, we injected a query that returns ‘TRUE’ i.e., 175’ AND 1=1–. hence, we got the result of the user. Out of all this, we identified that SQL injection is possible. (Figure 3).
Figure 3
To automate the exploitation, we will use SQLmap. As the request body is encrypted, we can’t just use SQLMAP as it is. To achieve this, we need to decrypt the encryption. As encryption is done on the client side, we looked for the key in the .js file and we found the key in the aes.js file. This was a manual process as we searched it through certain keywords. We observed that the developer must replicated the publicly available code from the internet and didn’t change the key. To make SQLmap work, we’ve added a parameter. (e.g., itest=QWERTYUIOP==)
As we now have the key. We decrypted the encryption using an online tool and we got the request body in plain text.
To get SQLmap working, we need a plaintext request which we decrypted manually through an online tool. The server only understands the encrypted data. Now to send the encrypted format to the server, we came up with an optimized solution! We created a tamper script that has a fix plaintext http body. Insert the payload, encrypt the entire http request body again and send it to the server.
We explicitly told SQLmap to use only Time-Based Queries to analyze the received data.
After SQLmap encrypts the request body it looks like this “itest=QWERTYUIOP==”. Since the server only understands this (“QWERTYUIOP==”) format, we made Burp Suite a middleman and removed “itest=” using its feature Match & Replace.
In the above scenario, the problems faced during the process are addressed below:
A. Request Body gets encrypted so we cannot use tools like SQLmap directly for the exploitation. Need to find the key as encryption is done on the client side.
To decrypt the encrypted data, a key is required. We analyzed all the .js files. We found out they are using AES with EBC cipher mode. We found the key but it was encoded in Base64 format. With the help of online tools or Burp suit’s Decoder, we’ve attained the cipher key.
B. Request format for SQLmap differs from the Server acceptance format.
The legitimate request body format for a server is (e.g., QMBCIIOJKLMNBVCZAQWER==). However, SQLmap only understands parameter value (e.g., Q=” Ownux”) to execute the SQL injection. Hence, we need to explicitly add “itest=” before the request body.
C. Need to Encrypt the data with a payload before sending it to the server.
Doing it manually as a POC was tedious. Also, instead of decrypting the response, we wrote a script that crafts the http request body with payload from an already decrypted text and then encrypted it using the SQLmap’s Tamper functionality. Now comes the data exfiltration which also requires decryption, instead we explicitly told the SQLmap to run only Time-Based queries.
D. Make the request in a server-acceptable format.
After the request data is encrypted using SQLmap the server still accepts encrypted data (e.g., QMBCIIOJKLMNBVCZAQWER==). To convert the request, we used Burp suite’s match & replace functionality and we defined the rule like this:
Find: “Q=”
Replace: <none>
by this, the request sent from burp would look from this “Q=QMBCIIOJKLMNBVCZAQWER==” and will be change to this “QMBCIIOJKLMNBVCZAQWER==” which is in a server acceptable format.
TO SUM UP:
A few of the problems faced through the process are encryption of the request body which makes the process of exploiting SQLi harder, and so on. In a quest to find the solutions to the problems, we found out that SQL injection is possible and we could retrieved the data of the user. To automate this, we wrote a tamper script that is compatible with the application’s environment. And that’s how we were able to automate the SQL injection by bypassing client-side encryption.