[TOC]
## 1 WebView远程执行漏洞检测 # 06001
和WebView远程代码执行相关的漏洞主要有CVE-2012-6336,CVE-2014-1939,CVE-2014-7224, 这些漏洞中最核心的漏洞是CVE-2012-6336,另外两个CVE只是发现了几个默认存在的接口。
Android API < 17之前版本存在远程代码执行安全漏洞,该漏洞源于程序没有正确限制使用addJavaScriptInterface(CVE-2012-6636)方法,攻击者可以通过Java反射利用该漏洞执行任意Java对象的方法,导致远程代码执行安全漏洞。
风险等级:`提醒`
* CVE-2012-6636
Android API 16.0及之前的版本中存在安全漏洞,该漏洞源于程序没有正确限制使用WebView.addJavascriptInterface方法。远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法
Google `Android <= 4.1.2 (API level 16)` 受到此漏洞的影响。
* CVE-2014-1939
java/android/webkit/BrowserFrame.java 使用addJavascriptInterface API并创建了SearchBoxImpl类的对象。攻击者可通过访问`searchBoxJavaBridge_`接口利用该漏洞执行任意Java代码。
Google `Android <= 4.3.1` 受到此漏洞的影响
* CVE-2014-7224
香港理工大学的研究人员发现当系统辅助功能中的任意一项服务被开启后,所有由系统提供的WebView都会被加入两个JS objects,分别为是accessibility和accessibilityTraversal。恶意攻击者就可以使用accessibility和accessibilityTraversal这两个Java Bridge来执行远程攻击代码.
Google `Android < 4.4` 受到此漏洞的影响。
问题示例:
A. WebView远程代码执行漏洞位置
WebView.addJavascriptInterface(Object obj, String interfaceName)
B. WebView远程代码执行漏洞触发条件
使用addJavaScriptInterface方法注册可供JavaScript调用的Java对象;
使用WebView加载外部网页或者本地网页
Android系统版本低于4.2
建议:
* API等于高高于17的Android系统。出于安全考虑,为了防止Java层的函数被随意调用,Google在4.2版本之后,规定允许被调用的函数必须以@JavascriptInterface进行注解。
* API等于高高于17的Android系统。建议不要使用addJavascriptInterface接口,一面带来不必要的安全隐患,如果一定要使用该接口:
1. 如果使用https协议加载url,应用进行证书校验防止访问的页面被篡改挂马
2. 如果使用http协议加载url,应进行白名单过滤、完整性校验等防止访问的页面被篡改
3. 如果加载本地html,应将html文件内置在apk中,以及进行对html页面完整性的校验
* 使用removeJavascriptInterface移除Android系统内部的默认内置接口:`searchBoxJavaBridge_`、accessibility、accessibilityTraversal
## 2 WebView潜在XSS攻击检测 # 06002
Android api < 17, 允许WebView执行JavaScript(setJavaScriptEnabled),有可能导致XSS攻击。
风险等级:`提醒`
问题示例:
遍历查找调用setJavaScriptEnabled方法并设置为true的包路径。
建议:
应尽量避免使用。如果一定要使用:
* API >= 17 的Android系统。出于安全考虑,为了防止Java层的函数被随意调用,Google在4.2版本之后,规定允许被调用的函数必须以`@JavascriptInterface`进行注解。
* API >= 17 的Android系统。建议不要使用addJavascriptInterface接口,一面带来不必要的安全隐患,如果一定要使用该接口:
1. 如果使用https协议加载url,应用进行证书校验防止访问的页面被篡改挂马
2. 如果使用http协议加载url,应进行白名单过滤、完整性校验等防止访问的页面被篡改
3. 如果加载本地html,应将html文件内置在apk中,以及进行对html页面完整性的校验
* 使用removeJavascriptInterface移除Android系统内部的默认内置接口:`searchBoxJavaBridge_`、accessibility、accessibilityTraversal
## 3 WebView File域同源策略绕过漏洞检测 # 06003
应用程序一旦使用WebView并支持File域,就会受到该漏洞的攻击。该漏洞源于:JavaScript的延时执行能够绕过file协议的同源检查,并能够访问受害应用的所有私有文件,即通过WebView对Javascript的延时执行和将当前Html文件删除掉并软连接指向其他文件就可以读取到被符号链接所指的文件,然后通过JavaScript再次读取HTML文件,即可获取到被符号链接所指的文件。
大多数使用WebView的应用都会受到该漏洞的影响,恶意应用通过该漏洞,可在无特殊权限下盗取应用的任意私有文件,尤其是浏览器,可通过利用该漏洞,获取到浏览器所保存的密码、Cookie、收藏夹以及历史记录等敏感信息,从而造成敏感信息泄露。
风险等级:`高危`
问题示例:
遍历查找调用了setAllowFileAccess的类路径,然后再获取函数参数值,判断参数值是否为true;同时判断该类路径是否为导出的组件。若两个条件满足,则存在漏洞,否则安全。
建议:
* 将不必要导出的组件设置为不导出,阿里聚安全建议显式设置所注册组件的`android:exported`属性为false;
* 如果需要导出组件,禁止使用File域;如果应用的需要导出包含WebView的组件,阿里聚安全建议禁止使用File域协议:
myWebView.getSettings. setAllowFileAccess(false);
* 如果需要使用File协议,禁止File协议调用JavaScript;如果应用的WebView需要使用File域协议,阿里聚安全建议禁止File域协议调用JavaScript:
myWebView.getSettings. setJavaScriptEnabled(false);
## 4 Webview密码明文存储漏洞检测 # 06004
webview的保存密码功能默认设置为true。Webview会明文保存网站上的密码到本地私有文件”databases/webview.db”中。对于可以被root的系统环境或者配合其他漏洞(如webview的同源绕过漏洞),攻击者可以获取到用户密码。
![密码明文存储漏洞-说明](https://wiki-1252789527.cos.ap-shanghai.myqcloud.com/scan_model/image063.jpg)
风险等级:`提醒`
问题示例:
遍历查找调用了setSavePassword的函数路径,然后再获取函数参数值,判断参数值是否为true
建议:
显示地设置webView.getSetting().setSavePassword(false)
## 5 主机名弱校验漏洞检测 # 06005
自定义HostnameVerifier类,却不实现verify方法验证域名,导致中间人攻击漏洞。
风险等级:`中危`
问题示例:
遍历查找所有实现了HostnameVerifier接口的自定义类并获取其路径,然后检测器成员函数verify的返回值。
建议:
自定义HostnameVerifier类并实现verify方法验证域名。
## 6 证书弱校验漏洞检测 # 06006
App在实现X509TrustManager时,默认覆盖google默认的证书检查机制方法:`checkClientTrusted`、`checkServerTrusted`和`getAcceptedIssuers`,会导致中间人攻击漏洞。
风险等级:`中危`
问题示例:
检测X509TrustManager的错误使用,一般错误的使用如下:
```
class InnerUnSafeTrustManager implements X509TrustManager{
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {}
}
```
或者
```
class InnerUnSafeTrustManager implements X509TrustManager{
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
```
即实现了X509TrustManager接口,覆盖函数缺什么也不验证。则这3个函数对应的smali代码如下:
```
.method public checkClientTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V
.locals 0
.param p1, "chain" # [Ljava/security/cert/X509Certificate;
.param p2, "authType" # Ljava/lang/String;
.annotation system Ldalvik/annotation/Throws;
value = {
Ljava/security/cert/CertificateException;
}
.end annotation
.prologue
.line 14
return-void
.end method
.method public checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V
.locals 0
.param p1, "chain" # [Ljava/security/cert/X509Certificate;
.param p2, "authType" # Ljava/lang/String;
.annotation system Ldalvik/annotation/Throws;
value = {
Ljava/security/cert/CertificateException;
}
.end annotation
.prologue
.line 20
return-void
.end method
.method public getAcceptedIssuers()[Ljava/security/cert/X509Certificate;
.locals 1
.prologue
.line 24
const/4 v0, 0x0
new-array v0, v0, [Ljava/security/cert/X509Certificate;
#这里对应return new X509Certificate[0];
return-object v0
.end method
```
即以下指令:
![不安全的指令逆向后的Smali代码](https://wiki-1252789527.cos.ap-shanghai.myqcloud.com/scan_model/image068.jpg)
即不安全的自定义类(实现了X509TrustManager接口),它checkClientTrusted(X509Certificate[] chain, String authType)、checkServerTrusted(X509Certificate[] chain, String authType)和getAcceptedIssuers()三个函数的所有指令加起来至少是4或5个)。所以当检测到实现了X509TrustManager接口的自定义类以上3个成员函数的指令加起来**小于等于5**,则可以判定为不安全的类。
建议:
如果自己创建X509Certificate,则在覆盖`checkClientTrusted`、`checkServerTrusted`和`getAcceptedIssuers`后要进行校验。
## 7 中间人攻击漏洞检测 # 06007
App调用setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER),信任所有主机名,会导致中间人攻击。
风险等级:`中危`
问题示例:
用污点分析的方法,遍历查找所有设置了ALLOW\_ALL\_HOSTNAME\_VERIFIER字段属性的方法路径
问题示例:
~~~
private HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new SSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
~~~
建议:
对信任的主机严格认证
## 8 WebView不校验证书漏洞检测 # 06008
Android WebView组件加载网页发生证书认证错误时,会调用WebViewClient类的onReceivedSslError方法,如果该方法实现调用了handler.proceed()来忽略该证书错误,则会受到中间人攻击的威胁,可能导致隐私泄露。
风险等级:`中危`
问题示例:
~~~
WebView mWebView;
WebView yelbeeView;
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JsBridge(mContext), JS_OBJECT);
mWebView.loadUrl("http://www.baidu.com");
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler,
SslError error) {
// 06008
}
handler.proceed(); //忽略SSL证书的错误
}
}
// 06009
mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
mWebView.removeJavascriptInterface("accessibilityTraversal");
//mWebView.removeJavascriptInterface("accessibility");
~~~
## 9 WebView组件系统隐藏接口未移除漏洞 # 06009
android webview组件包含3个隐藏的系统接口:`searchBoxJavaBridge_`,`accessibilityTraversa`l以及`accessibility`,恶意程序可以利用它们实现远程代码执行。这在4.0 <= Android版本 < 4.4中会发生。
风险等级:`低危`
问题示例:
使用WebView,对应到smali语句中的特征是`Landroid/webkit/WebView;->getSettings()Landroid/webkit/WebSettings;`
而没有移除隐藏接口,对应到smali语句中的特征(关键字匹配)是会出现如下几个关键字:
* `removeJavascriptInterface`
* `searchBoxJavaBridge_`
* `accessibility`
* `accessibilityTraversal`
Smali代码如下:
```
const-string v3, "searchBoxJavaBridge_"
invoke-virtual {v1, v3}, Landroid/webkit/WebView;->removeJavascriptInterface(Ljava/lang/String;)V
const-string v3, "accessibility"
invoke-virtual {v1, v3}, Landroid/webkit/WebView;->removeJavascriptInterface(Ljava/lang/String;)V
const-string v3, "accessibilityTraversal"
invoke-virtual {v1, v3}, Landroid/webkit/WebView;->removeJavascriptInterface(Ljava/lang/String;)V
```
建议:
如果使用了WebView,那么使用WebView.removeJavascriptInterface(String name) API,显示的移除`searchBoxJavaBridge_`、`accessibility`、`accessibilityTraversal`这三个接口。