前几天学长扔给了我个漏洞去玩玩,上午抽空分析了下。
这个漏洞的分析整体难度不大,是个组件暴露问题,由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))。