[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的同源繞過漏洞),攻擊者可以獲取到用戶密碼。

風險等級:`提醒`
問題示例:
遍歷查找調用了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
```
即以下指令:

即不安全的自定義類(實現了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`這三個接口。