CVE-2020-0267 StrandHogg 1.0漏洞分析

一、漏洞背景

  • 研究人员在Android操作系统中发现一个最新漏洞,并命名为StrandHogg,攻击者可利用该漏洞伪装成合法的应用程序,目前已被BankBot等多个恶意木马积极利用。

二、漏洞细节

  • 在Android系统中,Activity作为向用户展示可视内容的组件,它是以任务的方式进行组织的。Android提供了允许开发者干预Activity任务的一些方式,当这种机制被恶意程序利用后,就会产生意想不到的效果。
  • 在默认情况下,每个应用程序的所有Activity都位于同一个任务栈中,这个任务栈的名称和该应用程序的包名相同。在AndroidManifest.xml中定义Activity,或者使用Intent来启动一个Activity时,开发者可以对这个Activity的任务和返回栈行为进行修改。例如在AndroidManifest.xml中可以为Activity指定launchMode属性,含义如下:
    • standard,该值为默认值,这种情况下该Activity可以被多次实例化,每个Activity实例可以属于不同的任务,并且一个任务也可以具有多个该Activity实例。(多次创建,不同分属,相同归属)
    • singleTop,这种情况下,如果Activity的实例已经存在于当前任务的栈顶,则Android会通过调用其onNewIntent()方法将Intent传递到该实例,而不是创建该Activity的新实例。该Activity可以被实例化多次,每个Activity实例可以属于不同的任务,一个任务也可以具有多个该Activity的实例,当然由于上述的特性,在一个任务栈中不会存在两个相邻的该Activity的实例。(栈顶复用,不同分属,相同归属,栈中不邻)
    • singleTask,这种情况下,在创建Activity时候,Android将创建一个新任务,并在新任务的底部实例化该Activity。但是,如果Activity的实例已经存在于单独的任务中,则Android同样会调用其onNewIntent()方法将Intent传递到现有实例 ,而不是创建新实例。所以一次只能存在一个该Activity的实例。(任务复用,独立任务,全局唯一)
    • singleInstance,这种情况下,和singleTask类似,但系统不会将任何其他Activity添加到该Activity所在的任务中。该Activity始终是其任务的唯一的成员。由该任务开始的任何该Activity都在单独的新任务中打开。(独占任务,全局唯一)
  • 如前所述,使用Intent来启动Activity时,也可以携带标志来修改Activity任务的行为,可以修改行为的标志有:
    • FLAG_ACTIVITY_NEW_TASK:相当于使用了launchMode=singleTop
    • FLAG_ACTIVITY_SINGLE_TOP:相当于使用了launchMode=singleTop
    • FLAG_ACTIVITY_CLEAR_TOP:如果正在启动的Activity已经在当前任务中运行,那么Android将清除任务栈中该Activity以上的所有其他Activity,并调用其onNewIntent()方法将Intent传递到现有实例。没有和该标志对应的launchMode值。
  • 然后,在AndroidManifest.xml中定义Activity时,还可以指定taskAffinity属性,用于指定该Activity对于特定任务的亲和性,默认情况下该参数不进行指定,即Activity对其他任务不具备亲和性。因为任务的名称是形如包名的形式,所以指定的taskAffinity属性看起来也是一个包名的形式。
  • 此外,在AndroidManifest.xml中定义Activity时,还有allowTaskReparenting属性,该值为布尔类型,默认为false,为true表示当该Activity所亲和的任务进入前台时,该Activity可以从它原来的任务转移到它所亲和的任务。由于具有singleTasksingleInstance启动模式的Activity只能在任务栈底,因此该属性仅对于standardsingleTop模式有效。
  • 由于有了这些属性,当一个Activity设置了taskAffinity为另一个应用的包名,并且launchModesingleTopallowTaskReparenting为true的时候,或出现这样的现象:首先启动这个Activity,并将其放入后台运行返回桌面,再点击另一个应用,你会发现这个Activity又出现在屏幕上。正是因为Android对任务栈的重排机制,导致了这样的结果。
  • 详细可参考Android官方的文档:任务和返回栈 – Android Developers

三、漏洞验证

  • 编写一个应用程序,对其MainActivity设置taskAffinity为被攻击应用的包名,并且allowTaskReparenting为true,启动该Activity并放入后台运行。当打开被攻击应用时,该Activity将会被显示出来,而不是被攻击的应用。

四、漏洞影响

  • 该漏洞允许攻击者编写应用程序仿冒合法的应用程序,通过编写极其相似的界面,可以诱骗用户输入密码,或通过向用户申请相关权限,进行隐私窃取。所有Android版本都受影响。

五、漏洞补丁

  • 根据研究者的文章,Google认为这是一个正常的功能特性,所以Google仅仅是下架了Google Play上相关的恶意应用,并不会修复这个问题。在这种情况下,建议用户特别警惕无故要求重新登录账号以及重新授权权限的请求,并且保证仅从官方的应用市场下载应用。
  • 更新:在Android 11版本安全公告中,Google已公开披露此漏洞,级别为Critical,分配了CVE-2020-0267编号跟踪,同时漏洞也在Android 11中被修补:现在taskAffinity字段只对相同UID的应用有效,也就是说,只有共享UID的应用才可以使用该方法进行界面的替代。