Activity-exported安全

Activity(exported安全)

安卓应用Activity的安全风险

android:exported(导出安全)*Implicit Intent(隐式)android:lauuchMode(Activity启动设置)Flag_ACTIVITY_NEW_TASK(Activity启动设置)android:taskAffinity(Activity启动设置)
安全绕过Activity劫持返回劫持信息泄露信息泄露
拒绝服务 信息泄露返回劫持返回劫持
信息泄露
....

android:exported

Activity是否可由其他应用的组件启动"true"表示可以,"false"表示不可以。若为"false",则 Activity只能由同一应用的组件或使用同一用户ID的不同应用启动

默认值取决于Activity是否包含Intent过滤器。没有任何过滤器意味着Activity只能通过指定其确切的类名称进行调用。这意味着Activity专供应用内部使用(因为其他应用不知晓其类名称)。因此,在这种情况下,默认值为" false"。另一方面,至少存在一个过滤器意味着Activity专供外部使用,因此默认值为"true"。

该属性并非限制Activity对其他应用开放度的唯一手段。您还可以利用权限来限制哪些外部实体可以调用 Activity(请参阅 permission属性)。

漏洞点和原理

假设场景

45747-p0nkhf4q6m8.png

一个安卓设备中安装应用A应用B,应用A有两个ActivityLogin AcitvityMain Activity,也就是应用A启动后的第一个页面, X Acitvity可导出属性为true,并且定义了intent filter设置action的值为budi,在应用B里面通过intent的方式并将值设置成budi,这就意味着应用B的代码可以调用应用AX Activity

  • 如果应用B参数值设置成恶意的,可能会导致 X Acitvity报错抛出异常崩溃退出,进而影响应用A的正常使用这样调用方式可能会存在本地拒绝服务
  • 如果应用A必须要求用户必须先访问一个密码锁,才能访问X Activity,而应用B通过代码直接访问X Activity,这就会导致绕过安全限制
  • Activity调用之后可以访问一个结果给调用者,如果调用结果包含敏感信息就可能会出现泄露风险,如:应用B调用应用AX acitvity返回一个敏感信息给应用B时可能会导致信息泄露
  • 加入X Activity接受一个URL参数,并通过该URL下载一个文件到本地,应用B传给X Acitvity是一个恶意的URL,导致X Activity下载一个后门App到本地有可能会应用A整个安卓设备的安全性出现安全威胁,业务漏洞。当然还有一种情况X Activity包含Webview组件(Webview有一个远程命令执行漏洞),如果应用B传递给X Acitvity是一个恶意的URL,可能会导致命令执行漏洞

在我们进行黑盒测试或者代码审计时,首先是查看安卓应用的主配置文件AndroidManifest.xml检查所有Activity的可导出属性,这里分为两种情况

AndroidManifest.xml(No Intent filter)

没有定义Intent filter过滤器,他的可导出属性指定为true时,可以被外部组件调用

21229-5y2zer5gmds.png

AndroidManifest.xml(Intent filter)

定义Intent filter过滤器,此时可导出属性的默认值为true,也可以被外部组件调用

86814-83gh1x0wba8.png

测试方法

黑盒:

先逆向获取AndroidManifest.xml查看

可以通过原始adb shell进行调用测试

am start -a android.intent.action.MAIN -n package/component
am start -n com.android.mypackage/com.android.mypackageLaunchMeActivity

示例

(假装是个正常的App)

在我们代码审计时,拿到源码首先需要检查他的主配置文件(AndroidManifest.xml)查看有的Activity的可导出属性,这里是给出两个示例的Activity

分别是SecurityActivityDoSActivity,这两个都定义了intent-filter,可导出默认属性都为True,接下来看下实际的使用过程.

33872-hugu18ehhw4.png

首先查看MainActivity,查看第一段代码有个button注册了一个点击事件调用了SecurityActivity,并且传递了1个参数值

47380-f2w2bxq2ziq.png

跟入SecurityActivity查看定义,也很简单意思是取出参数值source,并将参数值设置到textView里面

55642-g2jqmvcel4.png

返回MainAcitvity查看第二个Button注册了点击事件调用DoSActivity传递了"number, "3"DoSActivity

65585-vf0acvk5zqn.png

跟入DoSActivity查看定义,这里可以看到这段代码用于取出参数值number,接下来对number值进行了强制转换成整数(这里就有可能抛出异常,因为有可能number传递过来的字符串不能转换成整数因此可能会影响应用正常使用)

31703-h5y3w1ih7d.png

将App安装完成后,查看第一个button会访问SecurityActivity并且传递一个参数值sourceNormal

66611-vtlrj3on2cn.png

参考效果,SecurityActivity调用源为Normal

79859-shwglq1ruf.png

在查看第二个button,会传递一个数字3DoSActivity

52102-7opqx9soscq.png

接下来就是如何编写一个恶意的App,对这个NormalApp进行攻击

攻击SecurityActivity

SecurityActivity里面的intent-filter里面的action值,new一个Intent,设置成SecurityActivityaction值,传递一个source参数值为Evil App,然后启动这个Activity就可以了

65057-lf1oejutsdi.png

攻击DoSActivity

DoSActivity里面的intent-filter里面的action值,然后传递的是一个number参数,值为Evil App,然后在启动Acitvity

88296-h0cjhcjxjtt.png

运行一下查看效果(攻击app)

91835-r8kv3ej4slg.png

第一个button,这样就可以看到NormalApp里面的securityActivity,相当于绕过了他的MainActivity(或者说LoginAcitvity需要一些认证的地方)

46531-qdj4ck9y8oj.png

第二个button,访问的是DosActivity,传递的是一个number值的Evil App在转换为整型的时候会出现报错导致NormalApp的退出

06393-73tmwa6or52.png

效果App退出,如果这个时候打开Android studio,可以看到报数字格式的Exception错误了

15017-nnl1ayw7ib.png

安全建议

  • 若不需外部应用调用Activity,明确指出该exported属性为false;
<activity
    android:name=".activity.FirstAcitvity"
    android:label="this is FirstActivity"
    android:exported="false">
</activity>
  • 若需外部应用调用,使用 signaturesignatureOrSystem权限;(都是通过校验App的证书来验证是否是授权的调用源)
<activity
    android:name=".activity.FirstAcitvity"
    android:label="this is FirstActivity"
    android:exported="false"
    android:prottectionLevel="signature">
</activity>

本文链接:

https://www.linqi.net.cn/index.php/archives/401/