Android应用安全防御

Android应用的安全隐患包括代码安全、数据安全、组件安全、WebView等几个方面。

1. 代码安全

代码安全主要是指Android apk容易被反编译,从而面临软件破解,内购破解,软件逻辑修改,插入恶意代码,替换广告商ID等风险。我们可以采用以下方法对apk进行保护:

1.1 代码混淆

  代码混淆可以在一定程度上增加apk逆向分析的难度。Android SDK从2.3开始就加入了ProGuard代码混淆功能,开发者只需进行简单的配置就可以实现对代码的混淆。

1.2 Apk签名校验

  每一个软件在发布时都需要开发人员对其进行签名,而签名使用的密钥文件时开发人员所独有的,破解者通常不可能拥有相同的密钥文件,因此可以使用签名校验的方法保护apk。Android SDK中PackageManager类的getPackageInfo()方法就可以进行软件签名检测。

1.3 Dex文件校验

  重编译apk其实就是重编译了classes.dex文件,重编译后,生成的classes.dex文件的hash值就改变了,因此我们可以通过检测安装后classes.dex文件的hash值来判断apk是否被重打包过。

  (1)读取应用安装目录下/data/app/xxx.apk中的classes.dex文件并计算其哈希值,将该值与软件发布时的classes.dex哈希值做比较来判断客户端是否被篡改。

  (2)读取应用安装目录下/data/app/xxx.apk中的META-INF目录下的MANIFEST.MF文件,该文件详细记录了apk包中所有文件的哈希值,因此可以读取该文件获取到classes.dex文件对应的哈希值,将该值与软件发布时的classes.dex哈希值做比较就可以判断客户端是否被篡改。

  为了防止被破解,软件发布时的classes.dex哈希值应该存放在服务器端。

  另外由于逆向c/c++代码要比逆向Java代码困难很多,所以关键代码部位应该使用Native C/C++来编写。

1.4 逆向工具对抗

  对apk进行重打包常用的工具是apktool,apktool对于后缀为PNG的文件,会按照PNG格式进行处理,如果我们将一个非PNG格式文件的文件后缀改为PNG,再使用apktool重打包则会报错。

1.5 调试器检测

  为了防止apk被动态调试,可以检测是否有调试器连接。在Application类中提供了isDebuggerConnected()方法用于检测是否有调试器连接,如果发现有调试器连接,可以直接退出程序。

  以上是使用比较多的几种保护方法,单独使用其中一种效果不大,应该综合运用。

1.6 加壳保护

  使用加壳程序防止apk逆向是一种非常有效的方式,也是一个趋势。Jack_Jia在《Android APK加壳技术方案》一文中详细阐述了Android apk加壳原理以及几种加壳方案的具体实现。我们可以利用这几种方案对apk进行加壳。

  不过这种加壳方式是在Java层实现的,被反编译的风险仍然很大。为了克服这个缺点,今后可以研究采用如下思路来进行保护:

  将核心业务逻辑代码放入加密的.jar或者.apk文件中,在需要调用时使用Native C/C++代码进行解密,同时完成对解密后文件的完整性校验。如果需要更加安全的保护方法,可以考虑对so文件(Native C/C++代码编译得到的文件)进行加壳。Android so加壳主要需要解决两个问题:

  (1)对ELF文件加壳;

  (2)对Android SO的加载、调用机制做特殊处理。

  其实不管是Linux还是Windows,加壳的思路基本是一致的,简单点无非加密+拆解+混淆,复杂点如Stolen Code + VM等。所以确定好一个加壳方案之后,剩下的就是了解elf的文件结构和加载机制,然后自己写一套壳+loader。

  Android上的loader是/system/bin/linker,跟linux上的ld有一些区别。但主要过程还是一致的:map + relocate + init。

  Android so主要充当的角色是通过JNI与java交互,所以主要是作为一个库存在(也有一些so是可执行的),然后被Android runtime加载,并能被java层调用。所以对elf加完壳之后,还要对Android so做一些特殊处理:

  1. Android so被System.LoadLibrary()加载之后,会将so的信息存储在一个全局链表里,所以要保证脱壳后的so能被这个链表访问到。

  2. Android so库函数被java调用有两种方式:一种是通过registerNative注册,另一种是通过javah命名规则命名(参考http://blog.csdn.net/sno_guo/article/details/7688227)。所以一个通用的加壳方案要保证所有的库函数都能被调用,前者好解决,后者需要花点功夫。

  解决掉这两个问题之后,基本上一套Android SO加壳框架就成形了,后续就可以增加各种Anti tricks来完善壳的强度。

参考文档:http://www.colordancer.net/blog/2014/01/05/android-native-so%E5%8A%A0%E5%A3%B3%E6%8A%80%E6%9C%AF/

2. 数据安全

2.1 存储安全问题

  关于数据存储可能出现的问题包括如下几点:外部存储(SD卡)上的文件没有权限管理,所有应用都可读可写。开发者把敏感信息明文存在 SD 卡上,或者动态加载的payload放在SD卡上。

(1)明文存储敏感数据,导致直接被攻击者复制或篡改。

  • 将隐私数据、系统数据明文保存在外部存储
  • 将软件运行时依赖的数据保存在外部存储
  • 将软件安装包或者二进制代码保存在外部存储
  • 使用全局可读写(MODE_WORLD_READABLE,MODE_WORLD_WRITEABLE)的内部存储方式,或明文存储敏感信息(用户账号密码等)。

(2)不恰当存储登陆凭证,导致攻击者利用此数据窃取网络账户隐私数据。

  解决方案:

  • 对这些数据进行加密,密码保存在内部存储,由系统托管或者由用户使用时输入。
  • 对应用配置文件,较安全的方法是保存到内部存储;如果必须存储到SD卡,则应该在每次使用前检验它是否被篡改,与预先保存在内部的文件哈希值进行比较。
  • 应用如果需要安装或加载位于SD卡的任何文件,应该先对其完整性做验证,判断其与实现保存在内部存储中的(或从服务器下载来的)哈希值是否一致。
  • 如果要跨应用进行数据共享,有种较好的方法是实现一个Content Provider 组件,提供数据的读写接口并为读写操作分别设置一个自定义的权限。
  • 对于登录凭证的存储,使用基于凭据而不是密码的协议满足这种资源持久访问的需求,例如OAuth。

Android数据存储机制

       存储方式

描述

数据保密性

Shared preferences

用来存储一些简单配置信息的一种机制,使用Map数据结构来存储数据,以键值对的方式存储,采用了XML格式将数据存储到设备中。例如保存登录用户的用户名和密码。只能在创建它的应用中使用,其他应用无法使用。不能指定存储文件的位置,创建的存储文件保存在/data/data/<package   name>/shares_prefs文件夹下。支持的存储类型有:Boolean、Float、Integer、Long、String等

可以设置四种模式:

MODE_PRIVATE(默认模式,文件只能让创建的应用程序访问)、

MODE_WORLD_WRITEABLE、

MOED_WORLD_READABLE、

MODE_APPEND

内部存储

在设备内存中存储数据。通常这些数据不允许被其它应用甚至终端用户访问。即使重启设备,这些数据仍然存在,不过当终端用户卸载程序后,这些数据就会被删除。

可以设置三种模式:

MODE_PRIVATE(默认模式)、MODE_WORLD_READABLE、

MODE_WORLD_WRITABLE

外部存储

外部存储(SD卡)的数据是全局可读的。设备用户和其它应用都能读取、修改、删除这些数据

数据默认是全局可读的

SQLite数据库

如果需要使用数据库的搜索和数据管理功能,则可以使用SQLite数据库存储机制

程序内部可以任意访问,外部程序不能访问

网络存储

通过web服务器存储和获取数据

基于web 服务器的设置

2.2 传输安全问题

  • 不使用加密传输

  最危险的是直接使用HTTP协议登录账户或交换数据。例如,攻击者在自己设置的钓鱼网络中配置DNS服务器,将软件要连接的服务器域名解析至攻击者的另一台服务器在,这台服务器就可以获得用户登录信息,或者充当客户端与原服务器的中间人,转发双方数据。

  • 使用加密传输但忽略证书验证环节

  如开发者在代码中不检查服务器证书的有效性,或选择接受所有的证书。例如,开发者可以自己实现一个X509TrustManager接口,将其中的CheckServerTrusted()方法实现为空,即不检查服务器是否可信或者在SSLSoketFactory的实例中,通过setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIET),接受所有证书。这可能是因为开发者使用了自己生成的证书,客户端发现证书没有和可信CA 形成信任链,出现了CertificateException等异常,从而不得不做出这种选择。这种做法可能导致的问题是中间人攻击。

  我们在对敏感数据进行传输时应该采用基于SSL/TLS的HTTPS进行传输。由于移动软件大多只和固定的服务器通信,我们可以采用“证书锁定”(certificate pinning)方式在代码更精确地直接验证服务器是否拥有某张特定的证书。实现“证书锁定”的方法有二种:一种是实现X509TrustManager接口,另一种则是使用keystore。具体可以参考Android开发文档中的HttpsURLConnection类的概述。

3. 组件安全

  android应用内部的Activity、Service、Broadcast Receiver等组件是通过Intent通信的,组件间需要通信就需要在Androidmanifest.xml文件中配置,不恰当的组件配置、组件在被调用时未做验证、在调用其他组件时未做验证都会带来风险。

  可能产生的风险包括:

  (1)恶意调用

  (2)恶意接受数据

  (3)仿冒应用,例如(恶意钓鱼,启动登录界面)

  (4)恶意发送广播、启动应用服务。

  (5)调用组件,接受组件返回的数据

  (6)拦截有序广播

  比如:调用暴露的组件发短信、微博等。

  解决办法:

   (1)最小化组件暴露

  不参与跨应用调用的组件添加android:exported="false"属性,这个属性说明它是私有的,只有同一个应用程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务。

(2)设置组件访问权限

  对参与跨应用调用的组件或者公开的广播、服务设置权限。只有具有该权限的组件才能调用这个组件。

   (3)暴露组件的代码检查

  Android 提供各种API来在运行时检查、执行、授予和撤销权限。这些API 是 android.content.Context 类的一部分,这个类提供有关应用程序环境的全局信息。

4. WebView

  存在的漏洞:

  • 恶意App可以注入JavaScript代码进入WebView中的网页,网页未作验证。
  • 恶意网页可以执行JavaScript反过来调用App中注册过的方法,或者使用资源。

  漏洞利用:

  • 恶意程序嵌入Web App,然后窃取用户信息。
  • 恶意网页远程调用App代码。更有甚者,通过Java Reflection调用Runtime执行任意代码。

  解决方式:

  1、如果无需与JS交互,请删除对addJavascriptInterface函数的调用;

  2、在载入页面时对URL进行白名单判定,只有存在白名单中的域才允许导出或调用相关的Java类或方法。

  参考资料:http://www.zhihu.com/question/22933619

5. SQL注入

  使用字符串连接方式构造SQL语句就会产生SQL注入。

  解决方法:使用参数化查询。

  举例:http://www.maxwithcoco.com/notes/mobile-sec/apk-drozer-contentprovider

5. 其他漏洞

  ROOT后的手机可以修改App的内购,或者安装外挂App等。

  Logcat泄露用户敏感信息。  

  恶意的广告包插件(可能存在后门、WebView漏洞等)

  UXSS漏洞:

  UXSS漏洞可以绕过同源策略访问存储在Android应用目录/data/data/[应用包名]/下的所有内容。

    如果产生该漏洞的是web浏览器,则攻击者可以利用该漏洞窃取浏览器存储的所有cookie信息以及其它信息。

    测试代码:

    代码地址:https://github.com/click1/uxss

    在线测试地址:http://uxss.sinaapp.com/index.php

    解决方法:

    1、服务端禁止iframe嵌套X-FRAME-OPTIONS:DENY。详见:http://drops.wooyun.org/papers/104

    2、客户端使用setAllowFileAccess(false)方法禁止webview访问本地域。详见:setAllowFileAccess(boolean)

    3、客户端使用onPageStarted (WebView view, String url, Bitmap favicon)方法在跳转前进行跨域判断。

    4、客户端对iframe object标签属性进行过滤。

  详情可参考:http://www.80vul.com/webzine_0x06/PSTZine_0x06_0x05.txt

Android系统安全防御

1. 操作系统安全问题

  • Android root问题
  • 系统漏洞,补丁更新不及时
  • 认证机制问题

2. 系统安全解决方案

2.1 权限管理与隔离

  对运行在Android系统上的应用程序进行权限的细粒度管理和隔离,防止越权行为的发生和滥用权限获取敏感数据。

  可以采用MACMandatory Access Control)强制访问控制模型实现。它是一个针对Linux的安全加强系统SELinux中使用的安全模型,即任何进程想在SELinux系统中干任何事情,都必须先在安全策略配置文件中赋予权限。凡是没有出现在安全策略配置文件中的权限,进程就没有该权限。GoogleAndroid 4.4上正式推出了一套以SELinux为基础的系统安全机制SEAndroid。所以如果我们要定制一个Android系统,可以采用具有SEAndroid安全机制的Android 4.4版本。

2.2 内核与应用层漏洞防护

  增加补丁更新功能,如果发现漏洞,及时提醒用户进行系统补丁更新。

2.3 恶意程序检测与防护

  建立一套恶意代码防护模型,对运行在Android系统上的恶意程序进行检测,抵御恶意代码的入侵。

2.4 数据安全存储与传输:

  对Android系统上的数据存储和数据传输进行加密保护,保证终端上数据能够安全地使用。

  

原文地址: http://www.cnblogs.com/goodhacker/p/3864680.html

Android应用与系统安全防御相关推荐

  1. 《深入解析Android 5.0系统》——第1章,第1.2节安装开发包

    本节书摘来自异步社区<深入解析Android 5.0系统>一书中的第1章,第1.2节安装开发包,作者 刘超,更多章节内容可以访问云栖社区"异步社区"公众号查看 1.2 ...

  2. nokia android 8,疑似诺基亚8再曝光:预装Android 8.0系统

    [TechWeb报道]8月4日消息,之前诺基亚公布了诺基亚8手机,并且确认蔡司镜头认证.现在最新消息,来自GeekBench数据发现一款诺基亚机型,搭载骁龙835处理器,预装Android 8.0系统 ...

  3. 基于ubuntu16.04多用户编译android N(android 7.1)系统提示ninja_wrapper错误问题

    基于ubuntu16.04多用户编译android N(android 7.1)系统提示ninja_wrapper错误问题 Ubuntu 1604系统除了root,还有kandi和sundi两个用户, ...

  4. ios 边录音边放_关于Android和iOS系统OneNote支持边录音边记笔记的需求和建议

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 请问Android和iOS系统的OneNote什么时候能像Windows10系统里一样,支持边录音边记笔记.录音完毕后点击笔记时,能自动定位到相应的录音时 ...

  5. QEMU KVM 虚拟机移植之性能提高篇小结(android 虚拟机双系统方案)

    一.提升性能核心要素 1.将OPENGL 接口进行穿透调用,下面对opengl穿透做个小结 2.在arm开发板上打开kvm特性,这个qcom&mtk都是实现了的,只需要打开开关即可 二.AND ...

  6. Android P 图形显示系统

    Android P 图形显示系统(一)硬件合成HWC2 Android P 图像显示系统(二)GraphicBuffer和Gralloc分析 Android P 图像显示系统(三)Android HW ...

  7. Android O限制系统全屏进一步遏制手机勒索

    一.引言 近期谷歌发布了最新手机操作系统Android O的开发者预览版,一如往常,Android O又带来了多项新功能与优化升级,其中一项有关系统窗口管理的优化给Android手机勒索软件带来了严重 ...

  8. android 个人理财系统,基于Android的个人理财系统的设计与实现

    摘要: 在当今,全球经济的蓬勃发展带来了金融理财领域的巨大变革和创新,新的金融理财工具和理财观点层出不穷.对个人而言,从认识钱到管理钱(个人理财)是每个人的必修课.在Android系统应用如此火热的情 ...

  9. android系统自动构建,[系统集成] Android 自动构建系统

    一.简介 android app 自动构建服务器用于自动下载app代码.自动打包.发布,要建立这样的服务器,关键要解决以下几个问题: 1. android app 自动化打包 android 的打包一 ...

最新文章

  1. 慌!年中总结完全没思路,这份安全汇报让你抄作业
  2. 收汇核销系统无法与服务器连接,出口收汇核销网上报系统一直都无法与服务器建立连接.doc...
  3. java类怎么删除对象_在java中删除一个对象?
  4. 【总结】那些只要发送口令就能获取的有三AI大包视频和图文资料,你都存下来了吗...
  5. laravel中单独获取一个错误信息的方法
  6. Yes, Prime Minister 打表找规律-质数
  7. [OS复习]文件管理2
  8. oracle数据泵还原命令,Oracle Linux环境中使用数据泵的形式还原Oracle数据库
  9. boost::container模块实现显式实例集的测试程序
  10. 进销存设计之——单据的数据表结构设计
  11. 如果让我做一回产品经理。。。
  12. 【动态规划】【多重背包】[HDU 1291]悼念512汶川大地震遇难同胞――珍惜现在,感恩生活...
  13. 热插拔服务器电源维修,无需关停系统即可热插拔,TE Connectivity推出滑轨电源连接器...
  14. 阿里巴巴合伙人闻佳:创新背后的文化与组织
  15. JavaScript进阶学习(二)—— 基于原型链继承的js工具库的实现方法
  16. 什么叫直播秒开?如何实现秒开?
  17. 基于SSM的校园二手交易平台
  18. 红山区智慧城管系统正式上线运行
  19. MySql Undo日志 - 对聚簇索引进行CUD操作
  20. 基于clamp.js封装vue指令,处理多行文本的溢出

热门文章

  1. shell获取当前进程pid和上一个进程pid
  2. Python学习笔记:Day14 完成Web App
  3. Matlab练习:timer(定时器3)
  4. X11: Linux跨网络运行XWindow程序
  5. Ubunt16.04 搭建 GPU 显卡驱动 + CUDA9.0 + cuDNN7 详细教程
  6. tsp遗传算法 c语言,【分享】遗传算法解决TSP问题的源程序
  7. 基于暗通道优先算法的去雾应用Matlab
  8. Delphi之面向对象的界面复用技术
  9. 将FORMSTYLE类型由FSNORMAL变为FSMDICHILD时,窗体的VISIBLE自动设为TRUE.且create之后,自动运行onshow事件。
  10. 在stringgrid的drawcell事件处理过程中,给单元格赋值时,要用textout输出,不要像一般给cell[i,j]赋值那样。