Android本地数据存储:Internal Storage安全风险浅析

1. 内部存储(Internal Storage)风险描述

Android系统提供了以下四种Android应用本地存储方式:Shared Preferences、SQLite Databases、Internal Storage、External Storage等存储方式。内部存储(Internal Storage)是一种开发者可以直接使用设备内部存储器来创建和保存文件,默认情况下,以这种方式创建的文件只能被该当前程序访问,不可被其他程序或用户访问,当用户卸载该程序的时候,这些文件也随之被删除【1】;
内部存储安全风险源于:1)开发者在创建文件时没有正确的选取合适的创建模式(MODE_PRIVATE、MODE_WORLD_READABLE以及MODE_WORLD_WRITEABLE)进行权限控制; 2)开发者对“android:sharedUserId”属性的滥用,造成内部存储文件可被其他应用访问;3)开发者过度依赖Android系统内部存储安全机制,将用户信息、密码等敏感重要的信息明文存储在内部存储(Internal Storage)文件中,然后攻击者可通过root手机来进行攻击。
如果在开发中没有使用正确的创建模式创建内部存储文件,将会导致敏感信息泄露危害,如个人账户密码、身份信息以及金融账户等重要敏感信息。

2. 内部存储(Internal Storage)风险影响范围

Android所有系统

3.内部存储(Internal Storage)风险风险详情

1) 风险位置:

2) 风险触发前提条件:

使用了“android:sharedUserId”属性;
或使用MODE_WORLD_READABLE模式创建内部存储文件;
或使用MODE_WORLD_WRITEABLE模式创建内部存储文件;
或Android设备被root;

3) 本地数据存储风险原理:

a. 使用“android:sharedUserId”属性,使得其他应用可具有相同该属性值对该内部存储文件具备可读的权限;
b. 使用MODE_WORLD_READABLE模式创建内部存储文件,使得其他应用对该内部存储文件具备可读的权限;
c. 使用MODE_WORLD_WRITEABLE模式创建内部存储文件,使得其他应用对该内部存储文件具备可写的权限;
d. 获取root权限后的应用或用户对任何应用的任何模式创建的内部存储文件都具有可读可写的权限。

4. Internal Storage风险POC

1) 使用MODE_PRIVATE模式创建内部存储 (Internal Storage) 文件,因此在不具有root权限的情况下,其他应用就不能读取该应用的内部文件内容;
通过MODE_PRIVATE模式创建内部存储文件的代码片段:

通过adb shell进入系统终端,切换至su账户查看创建的内部存储文件的权限为“-rw-rw—-”,其中others的权限不可读,如下图所示:

通过adb shell进入系统终端,普通用户查看刚创建的内部存储文件,如下图所示,将提示“Permission denied”:

通过adb shell进入系统终端,切换至su账户查看创建的内部存储文件内容:

攻击应用读取其他应用的内部存储文件的代码片段:

结果显示为空:

2) 即使使用MODE_PRIVATE模式创建内部存储文件,只要其他应用与该应用含有相同的“android:sharedUserId”属性值和签名key时,其他应用在不具有root权限的情况下依然可读取该应用的内部文件内容;
受害者应用的AndroidManifest.xml内容如下:

通过MODE_PRIVATE模式创建内部存储文件的代码片段:

通过adb shell进入系统终端,切换至su账户查看创建的内部存储文件的权限为“-rw-rw—-”,其中others的权限不可读,如下图所示:

通过adb shell进入系统终端,普通用户查看刚创建的内部存储文件,如下图所示,将提示“Permission denied”:

通过adb shell进入系统终端,切换至su账户查看创建的内部存储文件内容:

攻击者应用的AndroidManifest.xml内容如下:

攻击应用读取其他应用的内部存储文件的代码片段:

3) 使用MODE_WORLD_READABLE模式创建内部存储 (Internal Storage) 文件,即使在不具有root权限的情况下,其他应用也可读取该应用的内部存储文件内容,从而造成信息泄露;
通过MODE_WORLD_READABLE模式创建内部存储文件的代码片段:

通过adb shell进入系统终端,普通账户查看创建的内部存储文件的权限为“-rw-rw-r–”,其中others具有可读权限,普通用户查看该内部存储文件内容,如下图所示:

攻击应用读取其他应用的内部存储文件的代码片段:

结果显示“thisisinternalstoragecontent”:

4) 使用MODE_WORLD_WRITEABLE模式创建内部存储 (Internal Storage) 文件,即使在不具有root权限的情况下,其他应用也可以恶意的修改该应用的内部存储文件内容,从而实施下一步攻击;
通过MODE_WORLD_WRITEABLE模式创建内部存储文件的代码片段:

通过adb shell进入系统终端,普通账户查看创建的内部存储文件的权限为“-rw-rw–w-”,其中others具有可写权限,如下图所示:

攻击应用改写其他应用的内部存储文件的代码片段:

运行攻击者应用之后,查看该内部存储文件内容为修改后的内容,如下图所示:

5) root下可任意读写应用创建的内部存储文件,因此不可将密码等用户敏感信息明文存储在内部存储文件中,以防止Android设备被root之后,造成敏感信息的泄露;

5.Android本地数据存储风险修复建议

      1. 避免使用MODE_WORLD_WRITEABLE和MODE_WORLD_READABLE模式创建进程间通信的内部存储(Internal Storage)文件;

出于安全考虑,阿里聚安全建议不要使用全局可读模式和全局可写模式创建进程间通信的文件,此处即为但不限于内部存储(Internal Storage)文件。如果需要与其他进程应用进行数据共享,请考虑使用content provider,详情参照Google官方安全指导[2]。

     2. 避免滥用“android:sharedUserId”属性;

阿里聚安全建议不要在使用“android:sharedUserId”属性的同时,对应用使用测试签名,否则其他应用拥有“android:sharedUserId”属性值和测试签名时,将会访问到内部存储文件数据 [3]。

      3. 避免将密码等敏感数据信息明文存储在内部存储(Internal Storage)文件中;

出于安全考虑,阿里聚安全建议不要将密码等敏感信息存储在内部存储(Internal Storage)文件中,即使Android系统内部存储安全机制,使得内部存储文件可不让其他应用读写,但是在Android系统root之后,该安全机制将失效而导致信息泄露。因此应该将敏感信息进行加密存储在内部存储(Internal Storage)文件中,详情参照Google官方安全指导[2]。

引用
[1]http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
[2]http://developer.android.com/training/articles/security-tips.html#StoringData
[3]http://developer.android.com/guide/topics/manifest/manifest-element.html#uid

转载自:http://jaq.alibaba.com/blog.htm?spm=0.0.0.0.VD8neA&id=58