大话无线客户端安全之数据存储安全——Android篇

1 前言

       随着无线客户端的火热发展,大家往往将所关注的重点放到了业务本身上,而忽视了安全问题。但是随着近年来各种层出不穷的与客户端相关的攻击事件以及安全漏洞的曝出,客户端安全已经不容忽视,忽视了安全必将会受到安全的惩罚。

       而在各种安全之中数据安全更是重中之重,毫不夸张的说数据安全可以说是无线客户端安全的灵魂。用户的重要数据一旦损失掉,将会对应用乃至企业造成巨大的负面影响。例如去年发生的CSDN的用户名密码泄露事件;和无线客户端相关的有Skype Android版的用户密码、信用卡号泄露事件等,对于企业造成了不可估量的损失。

        前面会简单介绍一下文件存储可能存在的风险,后续会给出由于不注意这些安全问题在集团内和其他公司内所引发的血淋淋的例子。

        不过大家了解之后主要是为了保护我们自身客户端的安全以及一些功能的攻击手法,不要干坏事哦O(∩_∩)O~

2 Android客户端安全风险

        Android客户端上数据的存储主要分为四种:内部数据存储、外部数据存储、数据库数据存储、Content Provider数据存储(其中数据库的安全问题会有一篇文章单独介绍、Content Provider的安全问题将会列入到组件安全的文章中去)

2.1 内部数据存储

       内部数据存储主要分为两种方式:SharedPreference存储和文件存储。

       内部数据存储的安全问题主要需要注意的是创建的模式以及向文件中写入的内容。

       SharedPreference : 是一种轻量级的数据存储方式,它的本质是基于XML文件存储key-  value键值对数据,通常用来存储一些简单的配置信息。

 

       File : 即常说的文件(I/O)存储方法,常用存储大量的数据。

 

 

       内部数据存储通常较为安全,因为他们可以受到Android系统的安全机制的保护。

       Android的安全机制本质上就是Linux的安全机制,系统会为在Android系统上运行的每一个app创建一个进程,并为该进程分配一个UID。Android系统将会为每一个app创建一个特定的目录/data/data/app_package_name,这个目录的权限只与UID相关,且只有UID关联的用户才有该目录相关的权限。

       因此,在对应目录下生成的SharedPreference文件与File文件如果以正确的方式去创建将会受到Android系统权限机制的保护。

       这个正确的创建方式是指文件创建的模式,SharedPreference与文件的创建模式主要有以下三种:

        MODE_PRIVATE:这个是默认的创建模式,该进程的UID对应的用户将会对该文件拥有完全的控制的权限,而其他UID的用户将没有权限去读/写文件。

        MODE_WORLD_WRITABLE:该权限将允许设备上所有的app对于该文件拥有写的权限。

        MODE_WORLD_READABLE:该权限将允许设备上所有的app对于该文件拥有读的权限。

2.1.1 SharedPreference数据存储实例

创建SharedPreference所使用的API为:

public abstract SharedPreferences getSharedPreferences (String name,
int mode)

(UI美化不太懂,大家凑合着看吧(*^__^*) )

就是通过点击存储按钮将username:yaotong、password:tbsec以key-value对的形式存入到一个userinfo.xml的文件中(具体的代码我会通过附件给出),注意这里我创建SharedPreference的时候是以MODE_PRIVATE的模式进行创建的

 

 

 创建后的文件的路径为/data/data/com.yaotong.andgoat/shared_prefs/userinfo.xml

 查看所创建的文件的权限可以通过两种方式

1.通过DDMS查看,可以看到图中紫色的方框为应用的权限,对于owner及owner所在组具有rw的完全的读写权限,而对于others用户是没有任何权限的

2.通过Shell来查看,可以看到通过shell查看看到的权限是与ddms中看到的权限是完全相同的,这样代表应用是安全的

 

2.1.2 SharedPreference攻击实例

下面我来模拟一下攻击者来盗取以MODE_PRIVATE模式和非MODE_PRIVATE模式所创建的文件会出现什么样的效果

(1).盗取以MODE_PRIVATE模式所创建的文件

盗取的代码如下所示:

 

01 package com.yaotong.andattack;
02  
03 import android.os.Bundle;
04 import android.app.Activity;
05 import android.content.Context;
06 import android.content.SharedPreferences;
07 import android.content.pm.PackageManager.NameNotFoundException;
08 import android.view.Menu;
09 import android.view.View;
10 import android.view.View.OnClickListener;
11 import android.widget.Button;
12 import android.widget.EditText;
13  
14 public class MainActivity extends Activity {
15      
16     private EditText btn_showtext;
17     private Button btn_submit;
18     @Override
19     public void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22         btn_showtext=(EditText)this.findViewById(R.id.showtext);
23         btn_submit=(Button)this.findViewById(R.id.submit);
24         btn_submit.setOnClickListener(new
OnClickListener() {  
25     public void onClick(View v) {
26     // TODO Auto-generated method stub
27     try{
28         Context andgoatContext = createPackageContext('com.yaotong.andgoat', Context.CONTEXT_IGNORE_SECURITY);  
29         SharedPreferences sharedPreferences = andgoatContext.getSharedPreferences('userinfo',  Context.MODE_WORLD_READABLE);  
30         String username = sharedPreferences.getString('name',
''); 
31         String password = sharedPreferences.getString('password','');
32         btn_showtext.setText(username+'|'+password);
33     }catch(NameNotFoundException e){
34         e.printStackTrace();
35     }
36       }
37   });
38  }
39  
40     @Override
41     public boolean onCreateOptionsMenu(Menu menu) {
42         getMenuInflater().inflate(R.menu.activity_main, menu);
43         return
true;
44     }
1 }

当点击按钮盗取信息的时候,出现了如下的提示信息'Attempt to read preferences file /data/data/com.yaotong.andgoat/shared_prefs/userinfo.xml without permission',可以看到权限不够,无法读取文件

(2).盗取以非MODE_PRIVATE模式所创建的文件(MODE_WORLD_READABLE)

可以看到这时候others组有了对该文件读的权限

再次点击按钮盗取信息,发现盗取成功

 

2.1.3 总结

由上面的分析我们可以得出几个重要的安全相关的结论:

(1).创建文件时的权限控制

       如果在创建文件的时候没有注意控制权限,那么该文件的内容将会被其他的应用程序所读取,这样就造成了用户相关信息的泄露,SharedPreference中存储的往往是一些免登token、session id等和用户身份息息相关的重要信息,因此在创建的时候一定要注意选取好创建的模式;注意免登token也一定要具有时效性,否则与存储了明文的用户名、密码无异。

(2).SharedPreference中不要存入明文密码等重要信息

       由于有root的存在,那么root过后的手机就打破了Linux提供的沙箱机制,那么无论我们以何种方式去创建SharedPreference都已经不在安全了,如果存储的是用户明文的密码,那么用户的密码将会泄露,因此绝对不要向SharedPreference中写入任何无时效性的重要的数据;

2.1.4 File存储实例

创建文件所使用的API为:

 

public abstract FileOutputStream openFileOutput (String name,
int mode)

        由于SharedPreference的本质就是一个xml文件,只是Android系统单独为它提供了一些列便于操作的API,因此文件存储的本质与SharedPreference完全相同,所面临的安全风险和注意事项与SharedPreference完全相同,在此不再赘述。

       唯一的区别是在读取文件的时候我们在SharedPreference中使用了系统的操作

SharedPreference的相关API,而在这里,我们完全采用JAVA I/O的方式去操作文件,例子如下所示:

1 File xmlFile = new
File(“/data/data/com.yaotong.andgoat/shared_prefs/userinfo.xml”)

2.2 外部数据存储

       外部存储,通常是指将数据存入到设备的SD卡上。

       外部存储是一种不安全的数据存储机制,因为存储到SD卡上的文件默认是提供给others读文件的权限的,设备上安装的其他app只要在其AndroidMenifest.xml上声明如下的语句<uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE'></uses-permission>,那么该app就具有了对于SD卡的完全的读写权限,即是说一个app放在SD卡上的任何数据都可以被其他的app进行读/写操作,所以将重要数据存储在SD卡上具有相当大的安全隐患。

2.2.1 外部数据存储实例

操作界面和代码如下所示:当点击存储按钮的时候,'yaotong|tbsec'字符串将会被存储到相应的SD卡目录下的userinfo.txt文件中

相关代码:

01 public boolean WriteToSDcard(String file, String destDir, String szInText) throws IOException {
02         if(mExternalStorageWriteable ==
true) {
03             File mSDPath = android.os.Environment.getExternalStorageDirectory();
04             File mDestPath =
new File(mSDPath.getAbsoluteFile() + File.separator + destDir);
05             Log.e('ExternalStorageDirectory',mSDPath.getAbsoluteFile() + File.separator + destDir);
06             File mFile =
null;
07             if(!mDestPath.exists()) {
08                 mDestPath.mkdirs();
09             }
10             mFile =
new File(mDestPath + File.separator + file);
11             if(!mFile.exists()) {
12                 try
{
13                     mFile.createNewFile();
14                 }
catch (IOException e) {
15                     e.printStackTrace();
16                 }
17             }
18             FileOutputStream mOutputStream;
19             mOutputStream =
new FileOutputStream(mFile);
20             mOutputStream.write(szInText.getBytes());
21             mOutputStream.close();
22             return
true;
23         }
24         return
false;
25     }

查看SD卡中文件的方法:

通过shell查看,可以看到SD卡下所有目录others都具有读的权限

 

接下来查看我们所创建的文件,发现文件others拥有读的权限

2.2.2 总结

由上面的分析我们可以得出如下的安全结论:

(1).存储在SD卡中的数据是不安全的

       SD卡中所创建的文件默认对于others具有可读的权限,这就意味着你存储在SD卡上的一切内容是可以被其他应用所读取的;此外,只要app在其AndroidMenifest.xml文件中声明了写SD卡的权限,那么你存储在SD卡上的数据也都可以被人修改。所以,一定不要在SD卡上存储任何重要的数据,SD卡上的数据是不受Linux默认保护机制保护的。

3 和数据存储相关的客户端安全事件

不要以为安全很遥远,安全就在你的身边,包括一些大厂商都发生过类似的安全事件,我们要引以为鉴,不让类似的问题发生在我们的身上。

 

内部数据存储安全事件:

网易Android客户端导致账号密码泄露

传送门:http://www.wooyun.org/bugs/wooyun-2010-010056

 

Android手机明文存储使用过的wifi密码

 

外部数据存储安全事件:

手机QQ2012(Android 3.0)导致用户聊天记录泄露

传送门:http://www.wooyun.org/bugs/wooyun-2010-012838

 

小米MIUI系统造成用户大量敏感数据泄露

传送门:http://www.wooyun.org/bugs/wooyun-2010-08187

时间: 2024-08-31 15:47:56

大话无线客户端安全之数据存储安全——Android篇的相关文章

客户端(浏览器端)数据存储技术概览

在客户端(浏览器端)存储数据有诸多益处,最主要的一点是能快速访问(网页)数据.(以往)在客户端有五种数据存储方法,而目前就只有四种常用方法了(其中一种被废弃了): Cookies Local Storage Session Storage IndexedDB WebSQL (被废弃) Cookies Cookies 是一种在文档内存储字符串数据最典型的方式.一般而言,cookies 会由服务端发送给客户端,客户端存储下来,然后在随后让请求中再发回给服务端.这可以用于诸如管理用户会话,追踪用户信息

详解Android数据存储之Android 6.0运行时权限下文件存储的思考_Android

前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以往直接sdcard根目录上直接新建了一个xxx/cache/目录来做文件存储就会不是那么容易控制了,所以有必要重新认识一下Android文件存储的相关知识了. 背景: 有关外置sdcard的读写权限 <uses-permission android:name="android.permissi

详解Android数据存储之Android 6.0运行时权限下文件存储的思考

前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以往直接sdcard根目录上直接新建了一个xxx/cache/目录来做文件存储就会不是那么容易控制了,所以有必要重新认识一下Android文件存储的相关知识了. 背景: 有关外置sdcard的读写权限 <uses-permission android:name="android.permissi

Android编程中的5种数据存储方式_Android

本文介绍Android平台进行数据存储的五大方式,分别如下: 1 使用SharedPreferences存储数据 2 文件存储数据      3 SQLite数据库存储数据 4 使用ContentProvider存储数据 5 网络存储数据 下面详细讲解这五种方式的特点 第一种: 使用SharedPreferences存储数据 适用范围:保存少量的数据,且这些数据的格式非常简单:字符串型.基本类型的值.比如应用程序的各种配置信息(如是否打开音效.是否使用震动效果.小游戏的玩家积分等),解锁口 令密

android数据存储之文件存储方法_Android

文件存储是 Android 中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有数据都是原封不动的保存到文件当中的. 概述 文件存取的核心就是输入流和输出流. Android文件的操作模式 文件的相关操作方法 文件读写的实现 openFileOutput和openFileInput方法 /** * openFIleOutput ,openFileInput * 这两种方法同sp一样只能讲文件保存到手机内存固定的路径中, * 默认为 /data/data/<packageName

Android使用文件进行数据存储的方法_Android

本文实例讲述了Android使用文件进行数据存储的方法.分享给大家供大家参考.具体如下: 很多时候我们开发的软件需要对处理后的数据进行存储,以供再次访问.Android为数据存储提供了如下几种方式: 文件 SharedPreferences(参数) SQLite数据库 内容提供者(Content provider) 网络 首先给大家介绍使用文件如何对数据进行存储 Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中

android缓存处理-Android开发中客户端如何进行数据的存储

问题描述 Android开发中客户端如何进行数据的存储 Android开发中客户端如何进行数据的存储以达到数据的缓存来减少与服务端的交互次数,并设置缓存时间?(求大神指导,最好有完整的代码) 十分需要!求帮助! 解决方案 推荐在客户端使用sqlite来存放本地的数据.因为是数据库,所以很多底层的事情不用考虑了.要放缓存,直接建立一个字段,获取的时间,这样判断下,如果超过,就再次访问服务器获取.

大话存储系列20——数据存储与数据管理综述

存储系统又两大部分内容:数据存储 和 数据管理. 数据存储包括:存储控制器硬件.磁盘.适配器.网络传输通道.RAID管理.LUN管理等,这部分主要功能就是提供基本的裸数据存储服务: 数据管理包括:Tier.Snapshot.Clone等数据处理模块. 存储系统实时监控物理空间使用情况,一旦所有用户整体空间消耗达到临界值,则需要马上扩大物理容量.然而,对于空间使用率的监控方面,如果存储系统为NAS系统,提供的是一个基于文件协议的卷共享,则存储系统本身就可以很容易地监控存储空间的真实耗费情况,因为N

客户端数据存储----Cookie From 《高程3》

前言 本篇主要介绍Cookie技术的读书总结,但是我认为逻辑上最好会和Web Storage技术放在一起进行对比,因此后续会再总结一篇关于WEB存储的姊妹总结,敬请期待. 首先先来一段总结:Cookie用于本地数据存储,出现在服务器和浏览器交互的响应Set-Cookie头部和请求Cookie头部中,受到单域名下Cookie的数量.单个Cookie大小.性能.安全限制.子Cookie技术的出现缓解了单域名下Cookie的数量限制,关于子Cookie有一整套工具函数可以使用. HTTP Cookie