Android StrandHogg

一、 漏洞概述

近期,挪威一家安全公司(Promon)披露了一个Android任务栈劫持漏洞。该漏洞影响所有的安卓版本,包括最新的安卓10,研究人员同时发现有36个恶意app正在利用该漏洞,同时top 500的app都处于危险中。虽然Google已经从Google Play中删除了这些恶意app,但是该漏洞目前还没有被修复。StrandHogg漏洞利用安卓多任务系统中的弱点来使恶意app可以伪装成设备中的其他app来发起攻击。

二、 攻击方式

1.程序劫持:当目标应用lanchMode为standard或singleTop时,通过设定恶意程序taskAffinity与目标Activity一致,攻击者可以轻松劫持目标程序。

2.任务隐藏:对任意已运行目标程序,如果设定恶意程序的程序名称及taskAffinity与目标程序保持一致,且lanchMode设定为singleInstance,则恶意程序运行后可以构建与目标程序同名的返回栈,并以不同任务ID存在于后台,从而可将目标任务隐藏于后台

三、 漏洞原理

此漏洞与app的lanchMode和Android的taskAffinity控件设置有关,Android源码中对lanchMode的处理主要位于ActivityStack。cpp文件的startActivityUncheckedLocked函数中。该函数的执行流程如下,首先对sourceRecord进行判断(当应用从桌面启动时,该值为null),如果为null,则进行launchMode的判断。之后launchMode判定的关键代码显示,当launchMode为LAUNCH_SINGLE_INSTANCE时将调用findActivityLocked()函数,其他情况将调用findTaskLocked()函数。当launchMode为standard或singleTop时,其执行流程如下,首先进入findTaskLocked()函数,该函数将对当前已有任务的栈顶Activity进行遍历。当任务affinity与当前启动Activity一致时,返回该返回栈栈顶Activity,并赋给intentActivity。

在launchMode为standard或singleTop的处理流程中,将调用moveTaskToFrontLocked()函数将intentActivity所指后台任务移动到前台。最终系统将调用resumeTopActivity Locked()函数,该函数最终会调用当前返回栈栈顶Activity的onRestart()函数。当launchMode设置为standard或singleTop时,倘若后台有同名返回栈存在,将返回该返回栈栈顶Activity,且直接对当前栈顶Activity执行重启动请求。

判定缺陷分析:设定singleTop与standard会出现启动已有任务,而自身目标程序无法启动的关键原因在于findTaskLocked()函数。一般来说,新启动的应用程序后台理应不存在其所需的任务,因此intentActivity应被置空。此时后面的判断机制将不被执行,因设定taskAffinity使后台存在了所需任务,intentActivity不再为空,函数返回值为当前返回栈中的顶端Activity,后面的判断机制依次执行,最终直接执行resumeTopActivityLocked(),使得顶端Activity被置于前台,而非创建所需的Activity。

根本原因在于Activity启动流程过程中,未考虑到后台有同名任务存在的情况。当后台出现相同任务,该判定逻辑便不再严谨。

四、 漏洞复现

  1. 通过恶意app扫描手机已安装的app的信息,获取文件管理和facebook的app包名
  2. 编写恶意app,恶意app启动就偷偷一次启动多个伪造的文件管理和facebook界面的activity, 属性allowTaskReparenting设置为"true",属性taskAffinity设置为步骤1获取的包名。
  3. 安装恶意app,打开后再打开facebook和文件管理,发现弹出的activity是恶意app启动时压入任务栈里的activity(即2中伪造的文件管理和facebook界面的activity)
  4. 伪造facebook登录界面为钓鱼攻击,伪造文件管理界面是伪装成合法app时请求不同的权限

五、演示视频