Introduction to Deep Links
In many scenarios an application
needs to deal with web based URLs in order to authenticate users using Oauth
login, create and transport session IDs and various other test cases. In such
scenarios, developers configure deep links, aka, custom URL schemas that tell
the application to open a specific type of URL in the app directly. This only
works in Android v6.0 and above. The intent filter to accept URIs that have
example.com as the host and http:// as URL scheme is defined in an Android
Manifest file as follows:
<intent-filter
android:label="@string/filter_view_http_gizmos">
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"
/>
<!-- Accepts URIs that begin with
"http://www.example.com/gizmos” -->
<data android:scheme="http"
android:host="www.example.com"
android:pathPrefix="/gizmos" />
<!-- note that the leading "/" is required for pathPrefix-->
</intent-filter>
Pay focus to data android:scheme=”http” and android:host=”<domain>”
Similarly, intent filter to define
a custom scheme (eg: to open URLs that open with example://gizmos.com) is as follows:
<intent-filter android:label="@string/filter_view_example_gizmos">
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<category
android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "example://gizmos”
-->
<data android:scheme="example"
android:host="gizmos" />
</intent-filter>
In this article, we’ll be looking
at how an attacker can exploit poor implementation of URL schemas to conduct
various attacks.
Where can it go wrong?
Oftentimes developers use deep
links to pass sensitive data from a web URL to an application like usernames,
passwords, and session Ids. An attacker can create an application that fires
off an intent and exploit this custom URL scheme (deep link) to perform attacks
like:
•
Sensitive data exposure
•
Session hijacking
•
Account takeovers
•
Open redirect
•
LFI
•
XSS using WebView implementation of a Deep Link
For example, a poor implementation
would be: example://api.example.com/v1/users/sessionId=12345
Here,
One can change the session ID to 12346 or 12347, and in the application, that
particular user’s session would open as to which that session ID corresponds.
This Url could be obtained while traffic analysis and a rogue application/HTML
phishing page could trigger that activity and perform account takeover.
Let’s see a basic real-time
demonstration of exploiting deep links using drozer.
Demonstration
I
have coded this small application that I initially built to demonstrate android
hooking and added a deep link scheme to call this activity. To download this
app follow here. Ideally, you must decompile this app and figure out what the
URL scheme is from the Manifest file. Here is how the application looks like.
Read the instructions given in the screenshot.
Now, you’ll notice that you won’t
be able to open the activity directly using the button below. Hence, we’ll have
to exploit deeplink to launch the activity.
The first step here would be to
view the manifest file and check which URL scheme is being used. For that I run
the following drozer command:
run app.package.manifest in.harshitrajpal.deeplinkexample
Note here, the <data scheme=””> has a value “noob” so maybe we can fire an intent
with a data URL containing a URL of this scheme so that it launches this
activity?
Note: It is to be noted that any
activity that is declared under an intent filter is by default exported and
hence can be called via a rogue app that fires off that particular intent.
Developers must also be very mindful of the fact that mere URL authentication
is not sufficient due to this fact.
To view exported activities:
run app.activity.info -a
in.harshitrajpal.deeplinkexample
We see DeepLinkActivity being used
here.
We can launch this activity using
our DeepLink exploitation technique. On exploring its source code we see that
it is accepting data URL with an intent to perform some action. This action
could be authentication, webviews, etc. But for he purpose of demonstration, I
have coded a simple 10+50 sum calculator (that we saw in the android hooking
article)
First, let’s see what happens when
we open a generic URL:
run app.activity.start --action android.intent.action.VIEW --data-url
http://google.com
As visible, the intent is fired up
in a browser.
Now, let’s form another query in
drozer that’ll fire up DeepLinkActivity.java in our application using deeplink.
run app.activity.start --action android.intent.action.VIEW
–data-uri noob://harshit.com/auth=sum
This is a random URL that doesn’t
mean anything and doesn’t perform any action. I’ve just demonstrated that an
authentication action can be performed using deep links like this.
As you can see, this URL has fired
up the application class that I had created. This is because Android Manifest
has directed the android system to redirect any URL that begins with the scheme
“noob://” to open up with my
application DeepLinkExample
Now, an attacker could host a
phishing page with “a href” tag that
contains a URL of this scheme, sends this page to a victim via social
engineering, he could steal his session ID using this. In the screenshot below
you can see one such URL that I’ve crafted to steal session key from the
DeepLinkExample app using noob:// scheme.
<html>
<body>
<a
href="noob://hello.com/yolo?=auth&session=exampleKey">click
here to exploit</a>
</body>
</html>
Let’s host this using our python
server
python3 -m http.server 80
Let’s open this HTML link on our
mobile browser. We see something like this:
Now, let’s see another intentionally vulnerable application called InjuredAndroid created by b3nac (Follow here). This application also has a vulnerable Deep Link activity. Since it is in intent-filter it is exported by default. Hence, we can launch this activity directly using the drozer.
run app.activity.info -a b3nac.injuredandroid
We see DeepLinkActivity is
exported. We try to call it using drozer
run app.activity.start --component b3nac.injuredandroid
b3nac.injuredandroid.DeepLinkActivity
We now, take a look at its manifest file to discover the scheme that’s being used.
run app.package.maifest in.harshitrajpal.deeplinkexample
Here, we see the flag11 scheme being used in
DeepLinkActivity.
Now, to open this activity using
this custom URL scheme, we can do something like:
run app.activity.start --action android.intent.action.VIEW
--data-uri flag11://abc.com
Alternatively, it can also be exploited using an HTML phishing page and social engineering attack:
<html>
<body>
<a href="flag11://hello.com/yolo?=auth&session=exampleKey">click
here to exploit</a>
</body>
</html>
python3 -m http.server 80
Now, clicking on this link in a
browser, we see that DeepLinkActivity successfully opens up!
How to avoid misuse of insecure deep link implementation
The measures are as follows: -
• Since deep links are configured
within the app, a developer could have a secret value communicated to the app
by a remote back end server over a secure transmission protocol.
• Verification of Deep Links as
App Links can be done by setting android:autoVerify=”true”
in the manifest file
• One can include a JSON file with
the name assetlinks.json in your web server that is described by the web URL
intent filter
Conclusion
In the article, we learned how to
exploit deep links to eventually cause critical damage. In a well-built
application, Deep Link could just be the perfect butterfly effect that leads to
many critical vulnerabilities. In the references below, you’ll find some real
time bug bounty reports that include deep link abuse. Thanks for reading.
References
https://hackerone.com/reports/401793
https://hackerone.com/reports/583987
https://hackerone.com/reports/855618
https://www.nowsecure.com/blog/2019/04/05/how-to-guard-against-mobile-app-deep-link-abuse/
0 comments:
Post a Comment