BOOK THIS SPACE FOR AD
ARTICLE ADwe will see how the largest e-commerce website in Iran can be vulnerable to SQL Injection, we present the techniques and methods that we used to exploit the vulnerability, abusing IDOR to have vanilla SQL injection
Digikala is an Iranian e-commerce company based in Tehran. By 2017, 62% of Iran’s households have been connected to the Internet and this development is driving demand for Internet services that mirror Western digital platforms such as Amazon. Digikala is ranked by Alexa as Iran’s 3rd most visited website. It is also the largest e-commerce platform in the Middle East. It has 1,700,000 unique visitors per day, and 85% of Iran’s ecommerce now takes place on Digikala
Where did the story begin?
The story begins where digikala launches an online game for a certain holiday in Iran, it’s like Halloween but it’s not, the goal for digikala was to get more users.
we’ll see lots of these events which for some kind of event a company will launch a campaign or a game to attract more users and often the new code is not tested for security issues and gets added to the main application which if vulnerable, well you know the drill (bug in the house)
from now to forward I will put some pictures and some of them are in Persian and I try to circle them and translate the words so you could understand better
The prizes awarded to the winners of this game can be seen in the image below, and the winners of the game are the ones who can get the most points.
BTW for the time this vulnerability was discovered getting a ps4 was a great deal so you could say it was the ps5 of it’s time :D
And what is the game about?
The game is exactly the same as the Chrome browser T-Rex, except that it uses a motorcycle character instead of T-Rex.
A little more technical
A friend suggested why not figure out how the game actually works, I was curious to check out the internals of this game, and after playing around, which also happened to get a low score, I noticed the part of the page that showed the highest score:
The first question that came to my mind was how this score is sent to the server and stored there?
I fired up burp, checked the exchange packages, and started playing again.
As shown in the image above, 2 interesting parameters with the newscore and user_id letters are being sent to the server, and in response, a True value is returned.
A brief examination of these parameters revealed that:
User_id parameter: plays the role of user ID and therefore I could change the value of other users by changing its value (IDOR vulnerability)
Newscore parameter: sends the final score of each game round to the server as Base64 and uses the equal sign (=) in the above image Url Encoded to the value of 3D%.
in order to decode this we can use burp suite decoder
So far, we have found a vulnerability, and that was a change in our own or other users’ rating. But was this the only vulnerability? No!
The impression I had on the server side code to update the user rating was as follows:
With this in mind, I started testing the server for SQL Injection; But there was a problem. The code written on the server-side returns only one of the two answers true or null.
This is where I continued to try to find the Blind SQL Injection vulnerability.
(For the sake of confidentiality, I can not provide information from the Digikala database. So from now on, assuming our database is MySql)
Next, I used the Time Based technique to check if the server was vulnerable. In this technique, using database commands such as the Sleep () function, it can be determined whether the sent query is running on the server side or not.
Next problem?
Assume that this vulnerability exists. Is it right to execute the sleep command on the largest store website in the country? Absolutely not!
So what do we do? It became a difficult issue! Of course, even if we went through the sleep method, there was still no way out! Extracting data from the database with the above techniques was really time consuming.
Well, let’s review it again:
Our vulnerability is Blind and the server returns only a True or Null response.We can not use the Time Based technique for the problem space.To solve these two problems, we can use the score parameter itself to receive information! But what do I mean?
This means that instead of sending a score to the server, for example, instead of newscore = 1000, we send a command to the database and then go to the output of that command in our profile, which shows the “highest score”!
What request should we send (what SQL statement should be used)?
newscore=user()The user() function in the MySql database returns the current user of the database. Therefore, we base code the above function and send it.
Response:
What happened? The values were correct, so why didn’t we get the True answer?
These problems occur the programmer configured data storage type for the newScore column in the database to Integer, so if you want to save a string (such as the string “current user” of the database) in that cell, You will encounter an error.
How to solve the problem of the above limitation?
Since we can only put the number inside the score cell, why don’t we convert the information we want (database username) into a number?
For this purpose, you can use the ascii() function inside MySql, which returns the numeric code of a character (a letter of a word).
Here because we have a word like root@localhost , we have to use another function with it called substring().
This function receives 2 inputs, and in order to extract from a source to a destination from the received string, we can say that the output of the SQL statement is converted to the ascii() code,and store that as our new updated score.
Finally, each time it is updated for each word, we have to convert our score from ascii code to “letter” and see the answer of our desired function by putting the output aside.
In the Python script below, we performed these steps automatically.
Anything can be inside the payload and it depends on the database. For example, waitfor and you must specify the amount of delay. waitfor delay ’00: 00: 10 ′
As much as I could, I tried to keep the content simple so that the content could be easily transferred. I hope this post has a good educational load for you and finally do not forget that you should always think outside the box 🙂