cve-2019-2234组件暴露漏洞分析

前几天学长扔给了我个漏洞去玩玩,上午抽空分析了下。

这个漏洞的分析整体难度不大,是个组件暴露问题,由checkmarx团队发现(说实话感觉这个漏洞有点没意思,大佬就直接掠过吧)

问题出现在google camera上,影响范围是pixel2,pixel3以及三星的部分手机,身边没有该漏洞环境的可复现环境,就在这里分析以下,做个笔记。

checkmarx对此的报道在这:https://www.checkmarx.com/blog/how-attackers-could-hijack-your-android-camera

checkmarx提交漏洞的具体时间表:

图一
D:\project\boke\Dawuge.github.io\img\in-post\intentfuzz\1

所以对应着尽可能地去找2019.7.4以前google camera的apk,由于在PC端google play官网下载不了相应的apk,需要在其他类似镜像的网站下载,这里我选了在apkmirror网上下载6.14号更新的apk

图二

直接拖入jadx。按漏洞信息描述是暴露了以下组件,其他应用可以无需任何权限就调用它。

1
2
3
4
5
6
7
8
9
10
11
12
13
com.google.android.apps.camera.legacy.app.activity.main.CameraActivity 
com.android.camera.CameraLauncher
com.android.camera.CameraActivity
com.android.camera.activity.CaptureActivity
com.android.camera.VideoCamera
com.android.camera.CameraImageActivity
com.android.camera.CameraVideoShortcutActivity
com.android.camera.CameraDeepLinkActivity
com.android.camera.SecureCameraActivity
com.google.android.apps.camera.legacy.app.settings.CameraSettingsActivity
com.google.android.apps.camera.legacy.app.refocus.ViewerActivity
com.google.android.apps.camera.photobooth.activity.PhotoboothActivity
com.google.android.libraries.social.licenses.LicenseMenuActivit

直接用jadx展开显示代码包,发现只有com.google.android开头的包名可以直接对应漏洞的描述,可以知道部分组件使用了别名,那就翻看AndroidManifest.xml。

图3

搜索可以定位这几个别名对应的targetactivity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<activity-alias android:name="com.android.camera.CameraLauncher" android:targetActivity="com.google.android.apps.camera.legacy.app.activity.main.CameraActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
</activity-alias>

<activity-alias android:name="com.android.camera.CameraActivity" android:targetActivity="com.google.android.apps.camera.legacy.app.activity.main.CameraActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="com.android.keyguard.layout" android:resource="@layout/keyguard_widget"/>
</activity-alias>

<activity-alias android:label="@string/image_intent_label" android:name="com.android.camera.activity.CaptureActivity" android:targetActivity="com.google.android.apps.camera.legacy.app.activity.CaptureActivity" android:visibleToInstantApps="true">
<intent-filter>
<action android:name="android.media.action.IMAGE_CAPTURE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="com.android.keyguard.layout" android:resource="@layout/keyguard_widget"/>
</activity-alias>

<activity-alias android:label="@string/video_intent_label" android:name="com.android.camera.VideoCamera" android:screenOrientation="user" android:targetActivity="com.google.android.apps.camera.legacy.app.activity.CaptureActivity" android:visibleToInstantApps="true">
<intent-filter>
<action android:name="android.media.action.VIDEO_CAPTURE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity-alias>

<activity-alias android:name="com.android.camera.CameraImageActivity" android:targetActivity="com.google.android.apps.camera.legacy.app.activity.CameraImageActivity" android:visibleToInstantApps="true">
<intent-filter>
<action android:name="android.media.action.STILL_IMAGE_CAMERA"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.VOICE"/>
</intent-filter>
<intent-filter>
<action android:name="android.media.action.STILL_IMAGE_CAMERA"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="launch-camera" android:host="com.google.android.GoogleCamera" android:path="/still-image"/>
</intent-filter>
<meta-data android:name="com.android.keyguard.layout" android:resource="@layout/keyguard_widget"/>
</activity-alias>

<activity-alias android:name="com.android.camera.CameraVideoShortcutActivity" android:targetActivity="com.google.android.apps.camera.legacy.app.activity.CameraImageActivity">
<intent-filter>
<action android:name="android.media.action.VIDEO_CAMERA"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.VOICE"/>
</intent-filter>
<meta-data android:name="com.android.keyguard.layout" android:resource="@layout/keyguard_widget"/>
</activity-alias>

<activity-alias android:name="com.android.camera.CameraDeepLinkActivity" android:targetActivity="com.google.android.apps.camera.legacy.app.activity.CameraDeepLinkActivity" android:visibleToInstantApps="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="store.google.com" android:path="/product/pixelcamerateam1"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
</intent-filter>
<meta-data android:name="com.android.keyguard.layout" android:resource="@layout/keyguard_widget"/>
</activity-alias>

<activity-alias android:name="com.android.camera.SecureCameraActivity" android:targetActivity="com.google.android.apps.camera.legacy.app.activity.SecureCameraActivity">
<intent-filter>
<action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.VOICE"/>
</intent-filter>
<intent-filter>
<action android:name="android.media.action.IMAGE_CAPTURE_SECURE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="com.android.keyguard.layout" android:resource="@layout/keyguard_widget"/>
<meta-data android:name="android.media.still_image_camera_preview_service" android:value="com.google.android.apps.camera.prewarm.NoOpPrewarmService"/>
</activity-alias>

发现对应的别名和targetactivity的对应关系是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
com.android.camera.CameraLauncher -->              com.google.android.apps.camera.legacy.app.activity.main.CameraActivity

com.android.camera.CameraActivity --> com.google.android.apps.camera.legacy.app.activity.main.CameraActivity

com.android.camera.activity.CaptureActivity --> com.google.android.apps.camera.legacy.app.activity.CaptureActivity

com.android.camera.VideoCamera --> com.google.android.apps.camera.legacy.app.activity.CaptureActivity

com.android.camera.CameraImageActivity --> com.google.android.apps.camera.legacy.app.activity.CameraImageActivity

com.android.camera.CameraVideoShortcutActivity --> com.google.android.apps.camera.legacy.app.activity.CameraImageActivity

com.android.camera.CameraDeepLinkActivity --> com.google.android.apps.camera.legacy.app.activity.CameraDeepLinkActivity

com.android.camera.SecureCameraActivity --> com.google.android.apps.camera.legacy.app.activity.SecureCameraActivity

加上之前无别名的组件,一共是以下activity组件,其中上半部分无别名的组件因为直接android:exported = “true”导致组件直接暴露,同时都没有设置android:permission,下半部分的情况有,android:exported = “ture”直接暴露的,也有组件原来的exported属性是false,但是alias别名对应的组件没有直接设置exported,但是设置了intent-filter,即默认exported为true,但是使其响应的intent需符合intent-filter的所有条件。

1
2
3
4
5
6
7
8
9
10
11
com.google.android.apps.camera.legacy.app.activity.main.CameraActivity 
com.google.android.apps.camera.legacy.app.settings.CameraSettingsActivity
com.google.android.apps.camera.legacy.app.refocus.ViewerActivity
com.google.android.apps.camera.photobooth.activity.PhotoboothActivity
com.google.android.libraries.social.licenses.LicenseMenuActivity
---------------------------------------------------------------------
com.google.android.apps.camera.legacy.app.activity.main.CameraActivity
com.google.android.apps.camera.legacy.app.activity.CaptureActivity
com.google.android.apps.camera.legacy.app.activity.CameraImageActivity
com.google.android.apps.camera.legacy.app.activity.CameraDeepLinkActivity
com.google.android.apps.camera.legacy.app.activity.SecureCameraActivity

说实话,分析到这就感觉到这个漏洞原理应该还是比较简单的,因为它的组件暴露可以直接造成个人隐私泄露影响。具体功能逻辑也比较简单,就是有混淆,上jadx反混淆,遇到奇葩函数时,去jeb里看其smali源码,基本上就能摸清程序的逻辑了。

其利用举个例子,比如这里的com.google.android.apps.camera.legacy.app.activity.CameraImageActivity,我们已经知道com.google.android.apps.camera.legacy.app.activity.main.CameraActivity是主活动了,代码中的字符串已经暴露了它的用途,具体分析不再累述,而看CameraImageActivity发现它是直接调用CameraActivity的,所以说我们只要发出符合CameraImageActivity的intent,那么就可以间接启动CameraActivity进行拍照活动了。

图4
图5

再看上面个提到的官方描述时间线,能够体会到该漏洞等级之所以升级也应该得益于checkmarx的exp(即vuln app)构造的好。

看完了一个漏洞,拿一个实例试一下,某订票软件。分析发现其中的一个暴露组件,于是构造intent,先启动程序,然后查看包名,在附上android:name。

1
2
<activity android:name="com.MobileTicket.wxapi.WXPayEntryActivity" android:exported="true" android:launchMode="singleTop" android:screenOrientation="portrait" android:configChanges="orientation|screenSize"/>
<activity android:name="com.MobileTicket.wxapi.WXEntryActivity" android:exported="true" android:taskAffinity="com.MobileTicket" android:launchMode="singleTask" android:screenOrientation="portrait" android:configChanges="orientation|screenSize"/>

图6
图7

2333,居然是个测试组件

到这里想起来之前所看过的一个intent fuzzer,虽然说这工具的威力可能不大(厂商一般都会无视只能引起崩溃的问题),但这里也可当一个工具来学习针对性的fuzz了,具体可以看我之前写过的一篇文章

https://www.anquanke.com/post/id/197083

顺便整理了下其他组件暴露的问题,感觉有点启发,那些组件暴露的问题都只能算是一个切入口,真正鉴定它是否是一个漏洞的标准取决于应用自身的逻辑(即是否是一些敏感功能),颇有点像一条路径上的各个分叉,看顺着分叉能够达到的程度大小就差不多决定了这是否是个漏洞,只不过上面这个漏洞的分支程度不深(一个转换就可以(怪不得这洞没人分析orz))。