Android 客户端常见漏洞

一、危险权限

二、组件漏洞

1.拒绝服务

涉及的API:android.content.Intent.get[a-zA-Z]*Extra

原理:本地组件启动时没有对Intent.getXXXExtra()获取或处理的数据进行异常捕获,从而导致攻击者可通过向受害者应用发送空数据、异常或者畸形数据来使该应用crash的目的。

防护:对接收到的任何数据做try catch处理,对于不符合预期的数据做异常处理,异常包括但不限于:空指针异常、类型转换异常、数组越界访问异常、类未定义异常、序列化反序列化异常(getSerializableExtra、getParcelableExtra)。

2.Activity

(1)越权绕过漏洞

涉及manifest节点:activity组件导出

没有对调用activity的组件进行权限验证,就会造成验证的安全问题。

防范:私有activity是相对安全的,所以尽量使得activity组件不要导出;公开activity必须谨慎处理接收的intent,返回数据不应包含敏感信息,不应发送敏感信息,收到返回数据时谨慎处理。

(2)钓鱼欺诈劫持

涉及API:android.content.Intent.setFlags

启动一个activity时,加入标志位FLAG_ACTIVITY_NEW_TASK,能够使被启动的activity立马呈现给用户,可用于钓鱼欺诈。

钓鱼欺诈劫持的原理:应用可以通过 Activity 管理器获取当前的任务栈信息,取出栈顶元素就可获知当前运行的 Activity 信 息。钓鱼应用可以利用这一点,监控当前栈顶的 Activity 信息,从而判断哪个 Activity 将被展示。 若登录界面是一个独立的 Activity,恶意应用通过判断栈顶元素的方式获知应用的登录界面将何时被展示,从而及时弹出伪造的登录界面,替换掉原有的 Activity。且由于手机屏幕的展示空间有限,系统不 会主动显示当前实际运行的是那个应用,用户无法察觉当前展示的登录界面是伪造的界面。

防范: 在敏感信息录入页面,并且如果是由单独的 activity 组成,当界面异常切换时要及时给用户以提示。一般是当前程序进入后台就对用户进行提示该程序已经进入后台运行。

3.Service

(1)权限提升

涉及manifest节点:Service组件导出

当一个具有高权限的service是被导出的时,如果没对调用这个Service进行权限限制和调用者的身份验证时,那么恶意的app将具有调用高权限的service的能力来执行高权限行为等。

(2)劫持

涉及API:

对于隐式启动的service,当存在同action名触发条件的service时,先安装应用的service优先级高,即使本应用使用startservice想要启动本应用的未导出的隐式service时也会被先安装的其他app的service劫持,因此想要劫持某个隐式启动的service时,只需要更早的在android系统中安装同action名的隐式启动的servic。(经测试,android4.4版本也有此问题;android5.0之后启动隐式的service时需要指明包名,因此理论上可以避免劫持的问题)

防范:私有的service尽量不定义intent-filter并且设置exported为false;尽量用显示的方式启动service; 合作service需对合作方的app签名做校验; Service接收到的数据需要谨慎处理; 内部service需使用签名级别的protectionLevel来判断是否为内部应用调用;  Service不应在onCreate时决定是否提供服务,应在onStartCommand/onBind/onHandleIntent等方法被调用时做判断;当service有返回数据时,应判断接收数据的组件是否有信息泄露的风险; 尽量不发送敏感信息。

4.Broadcast Receiver

涉及manifest节点:Broadcast Receiver组件导出

(1)敏感信息泄露

发送intent的时候没有明确指定接收者,而是简单的通过action进行匹配,而如果这个intent里包含敏感数据,那么恶意应用就可以注册一个广播接收者,嗅探并且拦截这个广播并且窃取敏感数据。

防护:使用LocalBroadcastManager来注册和发送广播只能被app自身广播接收器接收。

(2)权限绕过漏洞

使用Context.registerReceiver()动态注册的广播默认是导出的,如果导出的BroadcastReceiver没有做权限控制,导致其可以接收一个外部可控的url、命令等信息来执行特定的功能,那么攻击者可以利用应用的这些功能来执行越权操作。

防护: 使用LocalBroadCastManager来动态注册广播,其有以下三点优势:不必担心敏感数据泄露,通过这种方式发送的广播只能应用内接收;不必担心安全漏洞被利用,因为其他应用无法发送广播给该应用;它比系统的全局广播更高效。

(3)消息伪造

对于必须暴露的Receiver来说,如果其对外接收Intent而没有进行权限控制和身份验证,那么攻击者则能够伪造Intent中的消息。

防护:自定义声明权限,其protectionLevel为signature,在该暴露的Receiver中使用android:permission对其进行自定义权限限定,那么当其他应用如果和该应用的签名不一致时将无法申请该自定义权限,那么其他应用发出的不具有该自定义权限的同action广播是不会被该暴露的Receiver接收到的。

5.Content Provider

(1)信息泄露

涉及manifest节点:Broadcast Receiver组件导出

如果没有对Content Provider的权限做好控制,那么恶意程序有可能利用这种方式读取APP的敏感数据。

防护: minSdkVersion不低于9;不向外部app提供数据的私有content provide,应设置exported为false;使用protectionLevel为signature来进行权限控制;公开的content provider确保不存储敏感数据。

(2)SQL注入漏洞

涉及API:android.content.ContentResolver.delete(删除操作等)

 对Content Provider进行增删改查操作时,程序没有对用户的输入进行过滤,未采用参数化查询的方式,可能导致sql注入攻击。这样攻击者可以精心构造selection、projection参数等sql语句组成部分,实现在未授权的情况下从content provider获取更多的信息。

 防护:实现健壮的服务端校验 ;使用参数化查询语句,比如SQLiteStatement;避免使用rawQuery(); 过滤用户的输入。

(3)目录遍历漏洞

涉及API:android.content.ContentProvider.openFile

ContentProvider.openFile()方法使用不当将导致该漏洞,Uri.getPathSegments()这个API设计的时候未考虑输入数据会包含编码后的url的问题。

防护:首先对paramUri解码,文件创建后再通过调用File.getCanonicalPath()来获取文件或文件夹的绝对路径,最后校验生成的文件是否数据某个文件夹下面。

三、隐式启动intent:包含敏感数据

涉及API:android.content.Intent.Intent

     当存在两个应用具有相同的隐式启动activity需要的action时,一个应用的activity是导出的,一个应用的activity是不被导出的,那么当触发该action时,将会弹出选择哪一个activity的界面,进而能够启动那个不被导出的activity。(老版本才有,新版本已修复此漏洞,经测4.4版本无此漏洞)。

四、信息泄露漏洞

敏感信息:密码、手机号、快捷支付手机号、Email、身份证、银行卡、CVV码、有效期。

1.LogCat输出敏感信息

涉及API:android.util.Log.d(v/e/i)

原理: 应用层Log敏感信息输出。应用层System.out.println敏感信息输出。 系统某些异常的Log输出。 Native层敏感Log输出。

防护:  Eclipse中配置ProGuard实现release版apk实现自动删除Lod.d/v等。使用自定义LogCat类,上线前关闭Logcat开关。

2.敏感数据明文存储于Sdcard

Android系统的文件一半存储在sdCard和应用的私有目录下面,有些应用把敏感数据保存在了sdcard中,存在其数据被污染和替换的风险。

防护:应用的敏感数据严禁存储在sdcard中。

3.数据库敏感数据明文存储

涉及API:android.content.Context.openOrCreateDatabase

Database配置模式安全风险主要在于开发者在创建数据库(Database)时没有正确的选取合适的创建模式(MODE_PRIVATE, MODE_WORLE_READABLE, MODE_WORLD_WRITEABLE)进行权限控制,从而导致敏感信息泄露或者数据被篡改。

防护:敏感信息在数据库中需要加密存储,避免弱加密或者不加密的方式。对于敏感的数据库文件,不能使用MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE的模式进行创建。

4.Shared Preference全局可读写

涉及API:android.content.Context.getSharedPreferences

开发者在创建文件时没有正确的选取合适的创建模式(MODE_PRIVATE, MODE_WORLE_READABLE, MODE_WORLD_WRITEABLE)进行权限控制,明文存储敏感信息。

防护:避免使用MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE的模式创建进程间通信的shared preferences文件;重要敏感信息应该加密存储,因为如果android系统被root之后,app的私有目录也将能够被外部程序访问;避免滥用android:sharedUserId属性,在使用该属性的时候,不要对应用使用测试签名,否则其他具有相同签名的同sharedUserId的应用将能访问到该应用的内部存储;使用Secure Preferences等第三方加固库进行存储。

5.敏感信息硬编码

开发者在开发过程中把重要信息硬编码到apk文件中,导致攻击者可以通过逆向apk的方式得到重要敏感信息。

防护:避免硬编码敏感信息。

6.HTTP明文传输敏感信息

Http协议是明文传输数据的,当其传输敏感数据时将有可能被攻击者窃取到。

防护:敏感信息如果使用http协议传输,那么要对其进行加密,尽量使用非对称加密算法;使用https协议传输数据。

五、AndroidManifest.xml配置文件中的风险设置

1.allowBackup默认设置风险

涉及manifest节点:android:allowBackup=true

AndroidManifest文件中的allowBackup属性默认值为true,其为应用程序提供了数据备份和恢复的功能,但是这样攻击者就可以利用这种功能获取敏感信息、伪造身份、直接对服务器攻击等。

防护:显示设置android:allowBackup=false,使用android:restoreAnyVersion的默认值。

2.Debuggable默认设置风险

涉及manifest节点:android:debuggable=true

android:debuggable属性用于指定应用程序是否能够被调试,如果设置其为true,那么其将能够被java调试工具(jdb)调试,信息和代码都将可能会被获取和修改。

防护:系统默认其为false,使用系统默认设置。

六、WebView

1.webview密码明文存储漏洞

涉及API:android.webkit.WebSettings.setSavePassword

 setSavePassword(boolean):webview默认开启密码保存功能mWebView.setSavePassword(true),如果该功能未关闭,在用户输入密码时会提示用户是否保存密码,如果是,那么密码将会被明文保存到应用的私有目录的databases目录下的webview.db文件中。如果手机被root,那么将有信息泄露的风险。

2.webview file域同源策略绕过漏洞

涉及API:android.webkit.WebSettings.setAllowFileAccess

setAllowFileAccess(boolean):webview默认mWebView.setAllowFileAccess(true),在File域下能够执行任意的js代码,能够对私有目录文件进行访问,未对file:///形式的URL做限制,导致隐私信息泄露、cookie信息泄露等。

3.远程代码执行漏洞

涉及API:android.webkit.WebSettings.removeJavascriptInterface("searchBoxJavaBridge_"/"accessibility"/"accessibilityTraversal")

在android4.4版本以下:API16及以下,直接调用add方法将会引入searchBoxJavaBridge_接口而引发该漏洞,主要原因是系统没有对允许反射调用的公有函数做限制,导致攻击者可以利用暴露在js中的接口,通过反射的方式无限制的调用其他java类提供的公有方法,导致权限泄露。类似的危险函数还有accessibility,accessibilityTraversal。

在android4.4版本及以上,该漏洞发生的原因都是发生在chromium v8内核中。

防护:除了把自己应用里暴露的js接口做安全处理,还要移除系统添加的三个接口:searchBoxJavaBridge_、accessibility、accessibilityTraversal。

4.WebView忽略证书错误漏洞

涉及API:android.webkit.SslErrorHandler.proceed 

WebView组件加载网页发生证书认证错误时,会调用WebViewClient类的onReceivedSslError方法,如果该方法实现调用了handler.proceed()来忽略该证书错误,则会受到中间人攻击的威胁,可能导致隐私泄露。

防护:不调用android.webkit.SslErrorHandler的proceed方法,采用默认的处理方法SslErrorHandler.cancel(),停止加载问题页面。

5.同源策略绕过

涉及API:android.webkit.WebSettings.setAllowFileAccess

当应用程序使用WebView并支持File域时,JavaScript的延时执行能够绕过file策略的同源检查,并能够访问受害应用的所有私有文件。具体来说即通过WebView对Javascript的延时执行和将当前html文件删除并软连接指向其他文件就可以读取到被符号链接所指的文件,然后通过js再次读取html文件即可获取到被符号链接所指的文件。

防护:  将不必要导出的组件设置为不导出的; 如果应用需要导出的组件包含WebView,要禁止使用File域协议:myWebView.getSettings.setAllowFileAccess(false);如果必须使用File域协议,要禁止File协议调用;如果必须调用JavaScript,那么需要谨慎判断加载的file是否为敏感的file。

七、Https通信漏洞

1.忽略SSL证书校验

在自定义实现X509TrustManager时,checkServerTrusted中没有检查证书是否可信,导致通信过程中可能存在中间人攻击,造成敏感数据劫持。

防护:在自定义实现X509TrustManager时,在checkServerTrusted中对服务器信息进行严格校验。

2.忽略域名校验

涉及API:org.apache.http.conn.ssl.SSLSocketFactory.setHostnameVerifier

在自定义实现HostnameVerifier时,没有在verify中进行严格证书校验,导致通信过程中可能存在中间人攻击,造成敏感数据劫持。

在setHostnameVerifier方法中使用ALLOW_ALL_HOSTNAME_VERIFIER,信任了所有Hostname,也有中间人攻击风险。

防护:自定义实现HostnameVerifier时,在verify中对Hostname进行严格校验;在setHostnameVerifier方法中使用STRICT_HOSTNAME_VERIFIER进行严格域名校验。

 

猜你喜欢

转载自blog.csdn.net/qq_32133965/article/details/88027986