一、WebView相关

1、任意代码执行漏洞
已知的WebView任意代码执行漏洞有4个。较早被公布是CVE-2012-6636,揭露了WebView中addJavascriptInterface接口会引起远程代码执行漏洞。接着是CVE-2013-4710,针对某些特定机型会存在addJavascriptInterface API引起的远程代码执行漏洞。之后是CVE-2014-1939爆出WebView中内置导出的“searchBoxJavaBridge_”Java Object可能被利用,实现远程任意代码。再后来是CVE-2014-7224,类似于CVE-2014-1939,WebView内置导出“accessibility”和“accessibilityTraversal”两个Java Object接口,可被利用实现远程任意代码执行。

后文我们将围绕下面这段常见的示例代码展开:

WebView mWebView = (WebView)findViewById(R.id.webView);
WebSettings msetting = mWebView.getSettings();
msetting.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new TestAddJsInterface(), "myjs");
mWebView.loadUrl(getIntent().getStringExtra("url"));

CVE-2012-6636:

Android系统为了方便APP中Java代码和网页中的Javascript脚本交互,在WebView控件中实现了addJavascriptInterface接口,对应示例代码中的③,网页中的JS脚本可以利用接口“myjs”调用App中的Java代码,而Java对象继承关系会导致很多Public的函数及getClass函数都可以在JS中被访问,结合Java的反射机制,攻击者还可以获得系统类的函数,进而可以进行任意代码执行。漏洞在2013年8月被披露后,很多APP都中招,其中浏览器APP成为重灾区。但截至目前任有很多APP中依然存在此漏洞,与以往不同的只是攻击入口发生了一定的变化。另外我们也发现一些小厂商的APP开发团队因为缺乏安全意识,依然还在APP中随心所欲的使用addjs接口,明目张胆踩雷。

出于安全考虑,Google在API 17中规定允许被调用的函数必须以@JavascriptInterface进行注解,理论上如果APP依赖的API为17或者以上,就不会受该问题的影响。但部分机型上,API 17依然受影响,并且如果APP存在此漏洞,且targetsdk小于17,那漏洞的影响可以覆盖到android4.4的终端,如果大于等于17,只能在android4.2的机型上触发,所以前一种情况的危害目前来看依旧很大。

CVE-2014-1939:

在2014年发现在Android4.4以下的系统中,webkit中默认内置了“searchBoxJavaBridge_”, 代码位于“java/android/webkit/BrowserFrame.java”,该接口同样存在远程代码执行的威胁。

CVE-2014-7224:

在2014年,研究人员Daoyuan Wu和Rocky Chang发现,当系统辅助功能服务被开启时,在Android4.4以下的系统中,由系统提供的WebView组件都默认导出"accessibility" 和"accessibilityTraversal"这两个接口,代码位于“android/webkit/AccessibilityInjector.java”,这两个接口同样存在远程任意代码执行的威胁。

常见挂马页面:

function addJsHack(cmdArgs){for (var obj in window){ try {if ("getClass" in window[obj]) {try{window[obj].getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);;}catch(e){}  }} catch(e) {}}
}
addJsHack()

2、密码明文存储漏洞
WebView默认开启密码保存功能mWebView.setSavePassword(true),如果该功能未关闭,在用户输入密码时,会弹出提示框,询问用户是否保存密码,如果选择"是",密码会被明文保到/data/data/com.package.name/databases/webview.db

3、域控制不严格漏洞

setAllowFileAccess:

Android中默认mWebView.setAllowFileAccess(true),在File域下,能够执行任意的JavaScript代码,同源策略跨域访问能够对私有目录文件进行访问等。APP对嵌入的WebView未对file:/// 形式的URL做限制,会导致隐私信息泄露,针对IM类软件会导致聊天信息、联系人等等重要信息泄露,针对浏览器类软件,则更多的是cookie信息泄露。

setAllowFileAccessFromFileURLs:

在JELLY_BEAN以前的版本默认是setAllowFileAccessFromFileURLs(true),允许通过file域url中的Javascript读取其他本地文件,在JELLY_BEAN及以后的版本中默认已被是禁止。

setAllowUniversalAccessFromFileURLs:

在JELLY_BEAN以前的版本默认是setAllowUniversalAccessFromFileURLs(true),允许通过file域url中的Javascript访问其他的源,包括其他的本地文件和http,https源的数据。在JELLY_BEAN及以后的版本中默认已被禁止。

360手机浏览器缺陷可导致用户敏感数据泄漏:

以360手机浏览器4.8版本为例,由于未对file域做安全限制,恶意APP调用360浏览器加载本地的攻击页面(比如恶意APP释放到SDCARD上的一个HTML)后,就可以获取360手机浏览器下的所有私有数据,包括webviewCookiesChromium.db下的cookie内容,攻击页面关键代码:

function getDatabase() {  var request = false;if(window.XMLHttpRequest) {request = new XMLHttpRequest();if(request.overrideMimeType) {request.overrideMimeType('text/xml');}}xmlhttp = request;var prefix = "file:data/data/com.qihoo.browser/databases";var postfix = "/webviewCookiesChromium.db"; //取保存cookie的dbvar path = prefix.concat(postfix);// 获取本地文件代码xmlhttp.open("GET", path, false);xmlhttp.send(null);var ret = xmlhttp.responseText;return ret;
}

4、file跨域漏洞

Android 2.3 webkit或者浏览器APP自建内核中会存在此类跨域漏洞。在处理转跳时存在漏洞,导致允许从http域跨向file域,实现跨域漏洞。以某浏览器4.5.0.511版本为例,写一个html,命名为filereach.html,存放在服务器上。该浏览器4.5.0.511的X5内核存在http域跨file域的漏洞。POC代码如下所示:

<iframe name=f src="www.baidu.com" ></iframe>
<script>function init(){f.location = "file:///default.prop";}setTimeout(init,5000)
</script>

在浏览器中打开服务器上的filereach.html,将从http域跳转到file域

5、安全开发建议

(1)建议开发者通过以下方式移除该JavaScript接口:

  removeJavascriptInterface("searchBoxJavaBridge_")removeJavascriptInterface("accessibility")removeJavascriptInterface("accessibilityTraversal")

(2)出于安全考虑,为了防止Java层的函数被随便调用,Google在4.2版本之后,规定允许被调用的函数必须以@JavascriptInterface进行注解
(3)通过WebSettings.setSavePassword(false)关闭密码保存提醒功能
(4)通过以下设置,防止越权访问,跨域等安全问题:

setAllowFileAccess(false)
setAllowFileAccessFromFileURLs(false)
setAllowUniversalAccessFromFileURLs(false)

二、通信安全

1、使用HTTPS协议

HTTPS的主要思想是在不安全的网络上创建一安全信道,并可在使用适当的加密包和服务器证书可被验证且可被信任时,对窃听和中间人攻击提供合理的防护。可以说是非常基础的安全防护级别了。

2、验证证书

android中实现Https基本就这两种方式,一种是不验证证书,一种是有验证证书(预防钓鱼),但是如果把证书放在apk中也是一件很危险的事情,因为现在的反编译技术不得不服,所以目前觉得最好的方式,就是放在.so文件中可以进一步的降低风险 。

3、通信数据尽量不使用明文形式

前后端进行自定义算法进行加密,md5 base64 AES RSA 等等,算法推荐.so和java相互调用的形式。

4、防抓包

System.getProperty("http.proxyHost");
System.getProperty("http.proxyPort");

正常这两行代码获取的是null,如果返回不为空,就是挂代理了,那么就可以考虑是否不给数据了

5、token等等进一步的防护措施

道高一尺,魔高一丈,未来的路还会很长。

三、数据存储安全

有了数据就得存放,如果存放,就会被别人发现.所以得存好喽

1、隐藏数据存储位置
在Andoid设备中,以’.'开头文件或者文件夹是不可见的,并且也可以进行读写操作.如果隐藏了存储了文件位置,就可以避免用户误操作和被发现的机会。

2、存储内容不要使用明文
就算被找到,内容如果以密文的形式,也会降低被泄漏的风险

3、代码中禁止硬编码重要信息内容
硬编码很容易被反编译找到.建议存储到.so中(虽然.so也可以被破解,但是相较于java更安全点)

4、存储位置推荐
尽量存储到手机内部存储上,不要存储到外部存储卡上(因为手机内部存储只对相应的应用开放,外部存储对所有的应用都开放)

四、组件安全

规范安卓标准组件(Activity、Service、Receiver、Provider)的访问权限

1、设置权限开放属性:android:exported=[“true” | “false”]

exported属性为四大组件共有属性,其中含义大同小异。默认值由其包含 与否决定。若未包含,默认为“false”,若存在至少一个,则默认值为“true”。

  • 在Activity中:

表示是否允许外部应用组件启动。若为“false”,则 Activity 只能由同一应用或同一用户 ID 的不同应用启动。

  • 在Service中:

表示是否允许外部应用组件调用服务或与其进行交互。若为“false”,则 Activity 只能由同一应用或同一用户 ID 的不同应用启动。

  • 在Receiver中:

表示是否可以接收来自其应用程序之外的消息,如来自系统或或其他应用的广播。若为“ false”,则广播接收器只能接收具有相同用户ID的相同应用程序或应用程序的组件发送的消息。

  • 在Provider中:

表示是否允许其他应用程序访问内容提供器。若为“false”,则具有与Provider相同的用户ID(UID)的应用程序才能访问它。如果需要给其他应用程序提供内容,则应当限定读写权限。

2、配置自定义权限

自定义权限,限制自己的组件访问,详情看Android自定义权限与使用

3、使用更加安全高效的LocalBroadcastManager

区别基于Binder实现的BroadcastReceiver,LocalBroadcastManager 是基于Handler实现的,拥有更高的效率与安全性。安全性主要体现在数据仅限于应用内部传输,避免广播被拦截、伪造、篡改的风险。简单了解下用法:
(1)、自定义BroadcastReceiver

public class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {//Do SomeThing Here}
}

(2)、注册Receive

MyReceiver myReceiver = new MyReceiver();
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter filter = new IntentFilter();
filter.addAction("MY_ACTION");
localBroadcastManager.registerReceiver(myReceiver, filter);

(3)、发送本地广播

Bundle bundle = new Bundle();
bundle.putParcelable("DATA", content);
Intent intent = new Intent();
intent.setAction("MY_ACTION");
intent.putExtras(bundle);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

(4)、在Activity销毁时取消注册

@Override
protected void onDestroy() {super.onDestroy();localBroadcastManager.unregisterReceiver(myReceiver);
}

4、Application相关属性配置

(1)、debugable属性 android:debuggable=[“true” | “false”]
很多人说要在发布的时候手动设置该值为false,其实根据官方文档说明,默认值就是false。
(2)、allowBackup属性 android:allowBackup=[“true” | “false”]
设置是否支持备份,默认值为true,应当慎重支持该属性,避免应用内数据通过备份造成的泄漏问题。

5、自定义键盘
对于操作密码等危险输入的情况,可以考虑自定义键盘处理,防止通过键盘被盗用密码.

五、其他防护措施

多做一层安全措施,少一点风险.

1、代码安全
加固 360加固宝 等等
混淆

2、控制日志输出
自定义工具类,不要在线上出现敏感的信息

3、漏洞检测工具
各种云测平台进行测试
testin 云测
阿里云测 免费的
腾讯的 wetest

4、防止模拟器
判断手机是否包含蓝牙等模块,一些信息是否跟手机真机不一致等.防止通过模拟器篡改信息

5、二次打包
通过判断签名信息,防止,被二次打包,调试应用信息

6、账号与设备绑定
账号与相应设备进行绑定,如果发现与常用设备不符合,增加短信登录形式进行重新登录

7、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哈希值应该存放在服务器端。

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

9、是否root
检测是否包含su程序,和ro.secure是否为1,如果root了,可以禁止某些核心功能
检测是否root的代码

public boolean isRoot() {int secureProp = getroSecureProp();if (secureProp == 0)//eng/userdebug版本,自带root权限return true;else return isSUExist();//user版本,继续查su文件
}private int getroSecureProp() {int secureProp;String roSecureObj = CommandUtil.getSingleInstance().getProperty("ro.secure");if (roSecureObj == null) secureProp = 1;else {if ("0".equals(roSecureObj)) secureProp = 0;else secureProp = 1;}return secureProp;
}private boolean isSUExist() {File file = null;String[] paths = {"/sbin/su","/system/bin/su","/system/xbin/su","/data/local/xbin/su","/data/local/bin/su","/system/sd/xbin/su","/system/bin/failsafe/su","/data/local/su"};for (String path : paths) {file = new File(path);if (file.exists()) return true;//可以继续做可执行判断}return false;
}

10、是否装有xposd框架
检测是否安装有xposd框架,如果有提示并隐藏核心功能模块.接口禁用某些功能
所有的方案回归到一点:判断xposed的包是否存在。
(1)、是通过主动抛出异常查栈信息;
(2)、是主动反射调用。

private static final String XPOSED_HELPERS = "de.robv.android.xposed.XposedHelpers";
private static final String XPOSED_BRIDGE = "de.robv.android.xposed.XposedBridge";//手动抛出异常,检查堆栈信息是否有xp框架包
public boolean isEposedExistByThrow() {try {throw new Exception("gg");} catch (Exception e) {for (StackTraceElement stackTraceElement : e.getStackTrace()) {if (stackTraceElement.getClassName().contains(XPOSED_BRIDGE)) return true;}return false;}
}//检查xposed包是否存在
public boolean isXposedExists() {try {Object xpHelperObj = ClassLoader.getSystemClassLoader().loadClass(XPOSED_HELPERS).newInstance();} catch (InstantiationException e) {e.printStackTrace();return true;} catch (IllegalAccessException e) {//实测debug跑到这里报异常e.printStackTrace();return true;} catch (ClassNotFoundException e) {e.printStackTrace();return false;}try {Object xpBridgeObj = ClassLoader.getSystemClassLoader().loadClass(XPOSED_BRIDGE).newInstance();} catch (InstantiationException e) {e.printStackTrace();return true;} catch (IllegalAccessException e) {//实测debug跑到这里报异常e.printStackTrace();return true;} catch (ClassNotFoundException e) {e.printStackTrace();return false;}return true;
}//尝试关闭xp的全局开关,亲测可用
public boolean tryShutdownXposed() {if (isEposedExistByThrow()) {Field xpdisabledHooks = null;try {xpdisabledHooks = ClassLoader.getSystemClassLoader().loadClass(XPOSED_BRIDGE).getDeclaredField("disableHooks");xpdisabledHooks.setAccessible(true);xpdisabledHooks.set(null, Boolean.TRUE);return true;} catch (NoSuchFieldException e) {e.printStackTrace();return false;} catch (ClassNotFoundException e) {e.printStackTrace();return false;} catch (IllegalAccessException e) {e.printStackTrace();return false;}} else return true;
}

Android安全相关相关推荐

  1. 浅入浅出 Android 安全:第六章 Android 安全的其它话题

    第六章 Android 安全的其它话题 来源:Yury Zhauniarovich | Publications 译者:飞龙 协议:CC BY-NC-SA 4.0 在本章中,我们会涉及到与 Andro ...

  2. android 各类demo链接

    http://gundumw100.iteye.com/blog/940084 带磁性的悬浮窗体,类似于360绿色小人  主要实现的是:  1.悬浮所有窗体之上  2.有吸引力,吸附于屏幕边上  3. ...

  3. android代码精华 各路大神写的代码精华,大家一起分享

    http://blog.csdn.net/kan1kan5/article/details/41960259 http://gundumw100.iteye.com/blog/940084 带磁性的悬 ...

  4. [android开发必备]Android开发者社区汇总

    [android开发必备]Android开发者社区汇总 经常收到很多人问做android开发去哪个社区,每次都回答的零零碎碎的很比系统,今天统一整理下,把截至目前为止有价值的android开发社区汇总 ...

  5. 那些年收藏的技术文章(一) CSDN篇

    #Android ##Android基础及相关机制 Android Context 上下文 你必须知道的一切 Android中子线程真的不能更新UI吗? Android基础和运行机制 Android任 ...

  6. 十大干货安全议题,足以展望今年网络安全趋势

    夏天可以看雪吗? 答案是肯定的. 因为,看雪2019 安全开发者峰会即将于7月20日在北京国家会议中心开幕 2019 安全开发者峰会(SDC)是由拥有19年悠久历史的老牌安全技术社区--看雪学院主办, ...

  7. 10款移动app安全测试工具推荐

    移动互联网时代,我们的生活和工作深受 App 影响.伴随移动 App 的广泛应用,App 安全日益重要.本文介绍了 App 开发可能用到的安全测试工具. 当今,全球移动用户大约超过37亿.Google ...

  8. 那些年收藏的技术文章(一)-CSDN篇

    Android Android基础及相关机制 Android View体系 Android坐标相关 Android事件机制及相关问题 Android官方组件 Android Service Andro ...

  9. 网络安全咨询合规-APP合规检测

    一.APP安全检测主要内容: APP 安全检测主要面向主流手机操作系统上开发的移动应用.常见的检测方式包括** 漏洞扫描. 渗透测试. 代码审计. 安全加固. 安全配置检查 App 违法违规收集使用个 ...

最新文章

  1. 《Cisco/H3C交换机配置与管理完全手册(第2版)》终稿封面和目录
  2. clone是深拷贝还是浅拷贝_Cloneable接口的作用与探索理解浅拷贝与深拷贝
  3. Spring Quartz
  4. html中embed标签的用法
  5. WINCE 开机自动弹USB连接窗口问题(已解决)
  6. python3.6 安装Scrapy
  7. 赠票福利 | 2019,GMIS归来!杨强、吴恩达等全球重磅嘉宾共话数据智能
  8. Two Arrays and Sum of Functions
  9. 【Android】对话框 AlertDialog
  10. 来自看雪的手把手调试DebugPort清零
  11. idea黑色好还是白色好_白色牛仔裤,好看又好搭
  12. 分解质因数(优中再优化)
  13. Rocky4.2下安装达梦(DM)6数据库
  14. Mujoco-小球建模与控制
  15. 大数据智能算法及测评技术
  16. mpp格式文件怎么打开,mpp进度计划
  17. 计算机网络工程师 考试题,计算机四级网络工程师考试题及答案.docx
  18. 袁老走好,谢谢您!我辈也当自强。
  19. Android Studio不使用数据线调试adb
  20. JAVA并发编程的艺术-读书笔记

热门文章

  1. 电线对接和端接为什么要使用连接器?
  2. 八月暑期福利,10本Python热门书籍免费送!
  3. 学习网络安全应该具备哪些专业技能
  4. 自动生成文章摘要[JavaScript 版本]
  5. 第三篇:【重磅】呼叫中心运营指标KPI字典
  6. AD(九)原理图Value值核对、网路编号核对、元件名称核对
  7. ftp 发生意外错误 0x8ffe2740
  8. 电信客户流失数据分析(一)
  9. 【吐血整理】java程序员推荐轻薄笔记本
  10. Highcharts 写 venn图 (韦恩图),以及解决项目中venn的报错