Android安全防护防护——加密算法:传送门https://www.cnblogs.com/huangjialin/p/9694488.html

组件安全

activity劫持

简单来说就是正常的activity被攻击者替换上一个假冒的activity,但是用户并不知道这是一个假冒的activity,所以用户在输入相关信息后,就直接被攻击者获取到了。通常像登录页面,支付页面,或者是其他数据较为敏感的页面都是很容易被攻击。

 activity劫持的原理有两种

第1种:手机安装了木马程序,木马程序会注册一个Receiver,响应android.intent.action.BOOT_COMPLETED这个事件,这时候木马程序中的服务就会启动一个定时器,不停的循环当前运行的进程。一旦当前的进程正是我们要劫持的,并且运行在前台,就立刻使用FLAG_ACTIVITY_NEW_TASK来启动自己的木马程序中的页面并且处于栈顶,用户看到这个页面并不知道是木马程序的页面,就将一些信息输入,从而导致泄漏。

第2种:通常启动一个activity是通过startActivity(),这个方法的参数是intent,intent的设置有两种方式,第一种是通过设置action,让系统找到接收该action的activity,然后启动。第二种是通过包名+类名的方式进行启动。

当应用通过action来启动activity的时候,木马程序可以创建一个同样的action来接收activity。Android系统中,如果存在多个activity接收同一个action时,会提供一个列表让用户选择,一旦用户选错,就进入到木马程序中的页面。从而导致隐私信息泄漏。

解决方案

1、针对第一种情况,当我们的应用程序退到后台的时候,弹出提示信息提示用户,程序已经退出到后台。

2、自己写一个写一个反劫持程序。当一些敏感的页面时候,启动一个后台服务,然后显示一个悬浮框,我们可以获取到当前运行的进程名称,来提示用户。防止被一些木马程序欺骗。

3、针对第二种情况,启动activity的时候,通过包名+类名的形式进行启动,不要使用action方式。

下面用代码简单介绍一下劫持的原理

1、在恶意程序中启动一个服务,在服务中开启一个定时器,然后不断的获取当前的进程名。

 1 /**获取当前的运行在前台的进程,并且在前台运行*/ 2 public static String getTopAppPackageName(Context context) { 3         try { 4             String packageName = ""; 5             ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 6  7             if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { 8                 final long end = System.currentTimeMillis(); 9                 final UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);10                 if (null == usageStatsManager) {11                     return packageName;12                 }13                 final UsageEvents events = usageStatsManager.queryEvents((end - 60 * 1000), end);14                 if (null == events) {15                     return packageName;16                 }17                 UsageEvents.Event usageEvent = new UsageEvents.Event();18                 UsageEvents.Event lastMoveToFGEvent = null;19                 while (events.hasNextEvent()) {20                     events.getNextEvent(usageEvent);21                     if (usageEvent.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {22                         lastMoveToFGEvent = usageEvent;23                     }24                 }25                 if (lastMoveToFGEvent != null) {26                     packageName = lastMoveToFGEvent.getPackageName();27                 }28             }29             return packageName;30         }catch (Exception e){31             return null;32         }33     }

这里简单的说明一下,Android不同的系统获取进程的方法是不一样,Google为了提高系统的安全性,不断的封堵,不过,上面的获取当前的进程名在我的魅族7.0是可以获取的,亲测。

2、然后通过获取到当前进程的显示类名,恶意程序通过监听到当前进程运行的类名是自己想要攻击的页面,就迅速的替换上自己假的activity,从而迷惑用户,窃取到用户的隐私信息。不过目前6.0以上的系统,Google不提供获取其他应用的当前类名。但是在以前的版本是可以获取的。很遗憾,由于我的系统是7.0,所以,我并没有成功的获取到其他进程的topActivity。

Service劫持,Service拒绝服务

Service劫持

Service是Android四大组件之一,没有界面,运行在后台。通常我们用来做一些耗时的任务,但是需要注意的是Service是运行在主线程中的。而通常ComponentName startService(Intent service)我们是通过这样的方式进行启动一个service。其中参数是intent。而intent的使用有两种情况

第一种:明确的说明好要启动那个服务,也就是说指定好包名和Service的名称。

第二种:通过设置action,接收到action的service就启动。

那么问题就来了,如果你设置的action,攻击者弄的service会不会也可以也接收到你的action。在Android系统中多个service接收到同一个action,则看priority值,就是谁的优先级高,谁高就先启动谁。如果priority值一样,则是谁先安装,就先启动谁。所以说如果说攻击者自己弄一个服务,然后接收action,那么很有可能这个启动的service就是伪装的。

解决方案:startService(),bindService()时直接指定类名,包名。不要使用action启动。

Service拒绝服务

如果攻击者以这种方式进行攻击的。那要么是攻击者为了显示自己的技术,要么是那家公司的老板抢了他的老婆。当然也有可能是双方是竞争关系。这种攻击的方式就是让你的程序崩溃,崩溃,崩溃。

漏洞造成的原因

Android系统中,主要是通过intent来携带数据进行跳转的。但是系统在内部对intent中数据的并没有进行一些处理,比如数据为空,数据有问题等等,一旦攻击者对intent中的数据进行改动,就导致程序崩溃。

解决办法

1、既然是intent数据有问题。那我们获取的时候,就钥先做一些判断处理,还有就是try…catch处理。

2、在AndroidMenifest.xml中加上android:exported这个属性,设置为false 。即将组件设置为不可导出。

3、将service设置为私有的

 

Content Provider

四大组件之一的ContentProvider,在应用中扮演是应用间数据共享桥梁的角色。如果ContentPrevider组件对外暴露,攻击者很容易通过该暴露的组件的openFile接口,对文件目录进行遍历,从而导致数据泄漏。那么该如何判断ContentPrevider是否暴露这个接口呢?通过对所有的openFile方法,如果未对传入的uri技能型安全判断,则就认为有漏洞风险

解决方法

1、将不必要暴露的ContentPrivider组件设置为私有的。

2、去除没必要的openFile接口

3、对目标的uri进行有效的判断。

 

WebView安全

webView是Android原生提供的一个实现H5页面的控件。除了具有一般view的属性和设置外,还可以URL请求,页面加载,渲染,页面交互等进行处理。

漏洞产生原因

1、js调用Android原生代码,可以通过WebView的addJavaScriptInterface()方法进行对象的映射。当拿到该对象的时候,就可以对该对象中的方法进行调用。攻击可以通过拿到该对象,然后调用对象中的任意方法。

2、在Android应用中,webview开启了file域的访问,且允许file域对http域进行访问,同时未对file域的路径做限制。攻击者通过URLScheme的方式,可远程打开并加载恶意的html文件,获取到app中的一些信息。这个漏洞触发的条件是1、webview中setAllowFileAccessFromFileURLs或者是setAllowUniversalAccessFromFileURLsAPI配置为true。2、webview可以直接被外部调用,并能够加载外部可控的HTML文件。

解决方案

1、针对第一个漏洞,Google也给出解决方案,在Android4.2之前规定,被调用的方法必须要加上@javascriptInterface这个注解。才能够调用。在4.2之前采用拦截prompt()方法来进行漏洞的修复。

2、针对第二个漏洞,前面说了漏洞触发条件有两个,所以主要办法就是对这两个条件进行修复。1、setAllowFileAccessFromFileURLs或setAllowUniversalAccessFromFileURLs两个API为false。(Android4.1版本之前这两个API默认是true,需要显式设置为false)2、如果需要开启file域的访问,则要对file域的访问范围要严格控制。

 

SharePreferences存储风险和SDCard存储风险

1、SharePreferences存储是一种轻量级的基于XML文件存储的键值对形式进行数据的存储的。存储的数据一般是比较小的。

存在风险:现在很多人将登录相关的信息明文存储到sp中,过度的依赖Android系统本身提供的安全存储机制。导致攻击者可以通过root手机来查看敏感的信息。

解决方案:一些敏感的信息不要明文进行存储,先使用加密算法进行加密,在存储。

2、SDCard

Android系统中存放的文件存储卡分为内置存储卡和外部存储卡

内置存储卡,是有权限控制的,现在Android系统如果要读区内置存储卡,必须要用户手动给予权限,否则的话不能够读取。相对来说比较安全。

外部存储卡,有点类似于U盘,这个是没有权限控制,所以说如果只要有SDCard的读写操作权限,就可以进行读写操作,电脑也可以读取。

 

存在风险:如果数据存在外部存储卡中,攻击者很容易就读取到里面的数据,造成数据泄漏。

解决方案:敏感的数据不要存储到SDCard中,防止数据被修改或者是数据泄漏。推荐存储在/data/data/packagename/目录下应用数据任意备份风险

当AndroidManifest.xml配置文件中没有设置allowBackup这个属性,或者是设置这个属性为true的时候(默认是true),应用程序的数据可以被任意的备份和恢复。攻击者就可以通过adb工具备份复制应用程序的数据。

解决方案:在AndroidManifest.xml文件中设置application的属性 android:allowBackup=”false”

 

密码软键盘安全问题

现在很多应用的键盘,特别是输入支付密码的键盘,都是自己写的一个键盘。虽然从性能上或者是用户体验上来说,系统键盘或者第三方的键盘都要由于我们自己写的。但是如果用系统键盘或者是第三方键盘,我们输入的数据很容易就被泄漏,比如输入数据监听攻击,键盘截屏攻击,输入数据篡改攻击等。

解决方案

1、自定义输入键盘。自定义键盘,网上有很多案例,这里就不具体了。

2、防截屏。在activity中的onCreate()方法中,在setContentView之前加上getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);就可以防止屏幕截屏了。设置这个flag后,系统会把当前窗口的内容视为安全隐私内容,系统会阻止这些内容被截屏或者在不安全可靠的场景显示出来。

 

其他

前面说了存在的安全问题及解决方案,在这里还提一下提高安全性的两个方案。

1、混淆。系统提供有proguard文件来将我们要定义的混淆规则定义在里面。被混淆过的项目通过反编译工具,如ApkTool ,dex2jar , jd-gui等编译出来后,一些代码是显示为a,b,c这样的形式,无法知道具体的类名或者其他。虽然混淆不能保证安全多少。但是,至少能够增强反编译的难度。再说了没有什么事百分之百的,我们所做的安全防护,都只是让攻击者不能这么轻易的就破解而已。

2、第三方加固工具

现在市场上用的比较多的第三方工具有阿里聚安全,腾讯云应用加固,360加固保,梆梆加固,爱加密第三方加固工具相当于在在我们自己的应用上加了一层壳,让攻击者没有这么简单的拿到我们的数据。

 第三方加固的原理

 

 

我们拿到需要加密的Apk和自己的壳程序Apk,然后用加密算法对源Apk进行加密在将壳Apk进行合并得到新的Dex文件,最后替换壳程序中的dex文件即可,得到新的Apk,那么这个新的Apk我们也叫作脱壳程序Apk.他已经不是一个完整意义上的Apk程序了,他的主要工作是:负责解密源Apk.然后加载Apk,让其正常运行起来。

主要步骤:我们拿到需要加密的apk和自己的壳apk,然后用加密算法对源apk进行加密在壳apk进行合并得到新的dex文件,最后替换壳程序中的dex文件就可以了。得到新的apk,这个新的apk主要工作是:负责解密源apk,然后加载apk,让其正常的运行起来。

 

加固工具的对比

体积(体积小的为优):360 > 腾讯 > 爱加密 > 阿里 > 梆梆

兼容性: 阿里 > 腾讯 > 360 = 梆梆 > 爱加密

启动速度(时间短为优): 阿里 > 爱加密 > 360 = 梆梆 > 腾讯

漏洞: 腾讯 > 爱加密 > 360 > 梆梆 > 阿里

 

更多相关文章

  1. android telephony 之 UICC 卡数据读写及 UICC 框架结构
  2. android Application Component研究之ContentProvider
  3. Android(安卓)Touch系统简介(二):实例详解onInterceptTouchEvent与
  4. 获取当前应用的版本号和当前android系统的版本号
  5. Android账户同步备份机制
  6. Android应用程序组件Content Provider简要介绍和学习计划
  7. 2013年01月06日
  8. Android(安卓)ART模式简介
  9. Android富文本编辑器附源码

随机推荐

  1. 【FF7】关于多成Layer嵌套的问题
  2. Android(安卓)Studio添加volley以及volle
  3. Android(安卓)context空指针异常
  4. android 底部tab
  5. 【高通SDM660平台 Android(安卓)10.0】(1
  6. Android(安卓)两种串口实现方法总结
  7. Android(安卓)8.0系统以后你该这样启动Se
  8. View点击涟漪效果
  9. Android(安卓)studio在线升级
  10. android studio 中实现android全屏 AppCo