Deep Link Exploitation: Introduction & Open/unvalidated Redirection

Sanatsu
Mobis3c
Published in
6 min readJul 20, 2021
Deeplink

What is a Deep Link?

A deep link is a link that takes you to a specific content. Most web links are deep links.

Ex: Link & Deep Link

image by branch.io
In Android, A deep link is a link that takes you directly to a specific destination within an app.

Types of Deep links in Android

There are 2 types of deep links in android and are classified as Explicit and Implicit deep links.

Explicit Deep Link

An explicit deep link is a single instance of a deep link that uses a PendingIntent to take users to a specific location within your app.

An Explicit deep link is a deep link created by the same application when clicked, takes you to the content directly within the application.

Ex: A notification or An app widget

Explicit Deep Link: App Widget
Explicit Deep Link: App Notification

Implicit Deep Link

An implicit deep link refers to a specific destination in an app when the deep link is invoked.

An Implicit deep link is a deep link in the form of URI when clicked, takes you to the content directly within the respected application.

Ex: when a user clicks a link, Android can then open your app to the corresponding destination (Play store link).

Implicit Deep Link: URL redirected to target application

Deep links in Android

All Deep links related to android are stored in AndroidManifest.xml File.

To create a Deep link to your app content, An intent filter containing the elements and attribute values are added to the AndroidManifest.xml file.

Before going to the elements and attributes, let us see what is an Intent filter.

An Intent is an object passed to launch an activity or get an existing activity to do something new.While an Intent filter describes a capability of the component(like activities, services, and broadcast receivers)

An Intent is a messaging object you can use to request an action from one app component to another app component. Although intents facilitate communication between components in several ways, there are three fundamental use cases:

  • Starting an activity

An Activity represents a single screen in an app. You can start a new instance of an Activity by passing an Intent to startActivity(). The Intent describes the activity to start and carries any necessary data.

  • Starting a service

A Service is a component that performs operations in the background without a user interface. With Android 5.0 (API level 21) and later, you can start a service with JobScheduler.

For versions earlier than Android 5.0 (API level 21), you can start a service by using methods of the Service class. You can start a service to perform a one-time operation (such as downloading a file) by passing an Intent to startService().

  • Delivering a broadcast

A broadcast is a message that any app can receive. The system delivers various broadcasts for system events, such as when the system boots up or the device starts charging. You can deliver a broadcast to other apps by passing an Intent to sendBroadcast() or sendOrderedBroadcast().

The following XML snippet shows how you might specify an intent filter in your manifest for deep linking. The URIs “example://gizmos” and “http://www.example.com/gizmos” both resolve to this activity.

Deep link in Android Manifest.xml

In the above image, we can see the deep link for an activity.

  1. The URIs “example://gizmos” and “http://www.example.com/gizmos” both resolve to the activity named”com.example.android.GizmosActivity”.
  2. Intent-filter defines the capability of a activity component based on the type of URI.
  3. <action> Specify the ACTION_VIEW intent action, so that the intent filter can be reached from Google, DuckDuckGo or Any other Search Engine.
  4. <category> Include the BROWSABLE category. It is required in order for the intent filter to be accessible from a web browser. Without it, clicking a link in a browser cannot resolve to your app.

Also include the DEFAULT category. This allows your app to respond to implicit intents. Without this, the activity can be started only if the intent specifies your app component name.

5. Add one or more <data> tags, each of which represents a URI format that resolves to the activity. At minimum, the <data> tag must include the android:scheme attribute.

You can add more attributes to further refine the type of URI that the activity accepts. For example, you might have multiple activities that accept similar URIs, but which differ simply based on the path name. In this case, use the android:path attribute or its pathPattern or pathPrefix variants to differentiate which activity the system should open for different URI paths.

DeepLink: Open/unvalidated Redirection

Demo Time

For this demo, we will be using the intentionally vulnerable android application called InsecureShop.

As we learn’t all deeplinks in android are stored in AndroidManifest.xml file, let us start by opening the apk in jadx-gui to read the manifest.xml.

From the above image, we now know that DeepLink will be handled based on the data tag defined in the intent filter i.e., android:scheme must be present.

so let us search for the android:scheme in the manifest file and can see we found only 1 deeplink.

deeplink in manifest file

from the above image we can understand that the deeplink invokes webview by looking at the activity name. if you don’t remember what webview is, then check here.

The above uri will look like insecureshop://com.insecureshop which invokes the webview activity. In Jadx, hold ctrl and click on the activity name to open the code in new tab.

webview source code 1
  1. onCreate() is a life cycle event in Android. There are 6 core set of life cycle events in Android’s activity lifecycle onCreate(), onStart(), onResume(), onPause(), onStop(), and onDestroy() which are self-explanatory.
  2. webview settings for the defined webview activity.
  3. getIntent() fetches the intent and stores in intent object.
  4. intent.getData() fetches the uri and stores in uri object and checks if uri is empty.
webview source code 2
uri format
  1. checks for path if it has /web in it and execute the respective code.
  2. checks for path if it has /webview in it and execute the respective code.
  3. finish the checks, if both check fails and webview will not be loaded.

if 1 or 2 passes, it will fetch the uri and extract the value from the url query and store it on data variable and will be loaded via webview.

From the above image, we will try to complete the uri to load the arbitrary web page in the webview.

insecureshop://com.insecureshop/web?url=https://3kal.medium.com (or)

insecureshop://com.insecureshop/webview?url=https://3kal.medium.com

we will use ADB to initiate the webview with our uri and we need to be logged into the insecureshop application.

if you are not able to find the credentials, then here it is shopuser:!ns3csh0p , once we login the screen looks like below.

insecureshop post login

Using ADB we launch webview activity by passing the uri as data to it.

adb shell am start -W -a android.intent.action.VIEW -d “insecureshop://com.insecureshop/web?url=https://3kal.medium.com"

Webview loads the arbitrary uri as shown below:

webview

There are so many issues that can be exploited via deeplinks, which we will see in future articles.

--

--