Android WebView 使用漏洞

目錄

  • 一、類型
  • 二、具體分析
    • 2.1、WebView任意代碼執行漏洞
      • 2.1.1、addJavascriptInterface 接口引起遠程代碼執行漏洞
        • 漏洞產生原因
        • 解決方案
        • 關于該方法的其他細節
      • 總結
      • 2.1.2、searchBoxJavaBridge_接口引起遠程代碼執行漏洞
        • 漏洞產生原因
        • 解決方案
      • 2.1.3、accessibility和 accessibilityTraversal接口引起遠程代碼執行漏洞
    • 2.2、密碼明文存儲漏洞
      • 2.2.1 問題分析
      • 2.2.2、解決方案
    • 2.3、域控制不嚴格漏洞
      • 2.3.1、問題分析
        • 1、setAllowFileAccess()
        • 2、setAllowFileAccessFromFileURLs()
        • 3、setAllowUniversalAccessFromFileURLs()
        • 4、setJavaScriptEnabled()
      • 最終解決方案



一、類型

WebView中,主要漏洞有三類:

  • 任意代碼執行漏洞;

  • 密碼明文存儲漏洞;

  • 域控制不嚴格漏洞;


二、具體分析

2.1、WebView任意代碼執行漏洞

出現該漏洞的原因有三個:

  • WebView 中 addJavascriptInterface() 接口

  • WebView 內置導出的 searchBoxJavaBridge_ 對象

  • WebView 內置導出的 accessibilityaccessibilityTraversalObject 對象

2.1.1、addJavascriptInterface 接口引起遠程代碼執行漏洞

漏洞產生原因

JS調用Android的其中一個方式是通過 addJavascriptInterface 接口進行對象映射:

webView.addJavascriptInterface(new JSObject(), "myObj");
// 參數1:Android的本地對象
// 參數2:JS的對象
// 通過對象映射將Android中的本地對象和JS中的對象進行關聯,從而實現JS調用Android的對象和方法

所以,漏洞產生原因是:當JS拿到Android這個對象后,就可以調用這個Android對象中所有的方法,包括系統類(java.lang.Runtime 類),從而進行任意代碼執行。

如可以執行命令獲取本地設備的SD卡中的文件等信息從而造成信息泄露

具體獲取系統類的描述:(結合 Java 反射機制)

  • Android中的對象有一公共的方法:getClass() ;

  • 該方法可以獲取到當前類 類型Class

  • 該類有一關鍵的方法: Class.forName;

  • 該方法可以加載一個類(可加載 java.lang.Runtime 類)

  • 而該類是可以執行本地命令的

以下是攻擊的Js核心代碼:

function execute(cmdArgs)  
{  // 步驟1:遍歷 window 對象// 目的是為了找到包含 getClass ()的對象// 因為Android映射的JS對象也在window中,所以肯定會遍歷到for (var obj in window) {  if ("getClass" in window[obj]) {  //步驟2:利用反射調用forName()得到Runtime類對象alert(obj);          return  window[obj].getClass().forName("java.lang.Runtime")  // 步驟3:以后,就可以調用靜態方法來執行一些命令,比如訪問文件的命令getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);  // 從執行命令后返回的輸入流中得到字符串,有很嚴重暴露隱私的危險。// 如執行完訪問文件的命令之后,就可以得到文件名的信息了。}  }  
}   
  • 當一些 APP 通過掃描二維碼打開一個外部網頁時,攻擊者就可以執行這段 js 代碼進行漏洞攻擊。

  • 在微信盛行、掃一掃行為普及的情況下,該漏洞的危險性非常大

解決方案

Android 4.2版本之后

Google 在Android 4.2 版本中規定對被調用的函數以 @JavascriptInterface 進行注解從而避免漏洞攻擊

Android 4.2版本之前

在Android 4.2版本之前采用攔截prompt()進行漏洞修復。

具體步驟如下:

  • 繼承 WebView ,重寫 addJavascriptInterface 方法,然后在內部自己維護一個對象映射關系的 Map;

將需要添加的 JS 接口放入該Map中

  • 每次當 WebView 加載頁面前加載一段本地的 JS 代碼,原理是:
    • 讓JS調用一Javascript方法:該方法是通過調用 prompt() 把JS中的信息(含特定標識,方法名稱等)傳遞到Android端;
    • 在Android的 onJsPrompt() 中 ,解析傳遞過來的信息,再通過反射機制調用Java對象的方法,這樣實現安全的JS調用Android代碼。

關于Android返回給JS的值:可通過prompt()把Java中方法的處理結果返回到Js中

具體需要加載的JS代碼如下:

javascript:(function JsAddJavascriptInterface_(){  // window.jsInterface 表示在window上聲明了一個Js對象// jsInterface = 注冊的對象名// 它注冊了兩個方法,onButtonClick(arg0)和onImageClick(arg0, arg1, arg2)// 如果有返回值,就添加上returnif (typeof(window.jsInterface)!='undefined') {      console.log('window.jsInterface_js_interface_name is exist!!');}   else {  window.jsInterface = {     // 聲明方法形式:方法名: function(參數)onButtonClick:function(arg0) {   // prompt()返回約定的字符串// 該字符串可自己定義// 包含特定的標識符MyApp和 JSON 字符串(方法名,參數,對象名等)    return prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onButtonClick',args:[arg0]}));  }, onImageClick:function(arg0,arg1,arg2) {   return
prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onImageClick',args:[arg0,arg1,arg2]}));  },  };  }  
})
// 當JS調用 onButtonClick() 或 onImageClick() 時,就會回調到Android中的 onJsPrompt ()
// 我們解析出方法名,參數,對象名
// 再通過反射機制調用Java對象的方法

關于該方法的其他細節

細節1:加載上述JS代碼的時機

  • 由于當 WebView 跳轉到下一個頁面時,之前加載的 JS 可能已經失效

  • 所以,通常需要在以下方法中加載 JS:

onLoadResource();
doUpdateVisitedHistory();
onPageStarted();
onPageFinished();
onReceivedTitle();
onProgressChanged();

細節2:需要過濾掉 Object 類的方法

  • 由于最終是通過反射得到Android指定對象的方法,所以同時也會得到基類的其他方法(最頂層的基類是 Object類)

  • 為了不把 getClass() 等方法注入到 JS 中,我們需要把 Object 的共有方法過濾掉,需要過濾的方法列表如下:

getClass()
hashCode()
notify()
notifyAl()
equals()
toString()
wait()

總結

  • 對于Android 4.2以前,需要采用攔截 prompt() 的方式進行漏洞修復

  • 對于Android 4.2以后,則只需要對被調用的函數以 @JavascriptInterface 進行注解

  • 關于 Android 系統占比,Google公布的數據:截止 2017 .1 .8 ,Android4.4 之下占有約15%,所以需要重視。


2.1.2、searchBoxJavaBridge_接口引起遠程代碼執行漏洞

漏洞產生原因

  • 在Android 3.0以下,Android系統會默認通過 searchBoxJavaBridge_ 的Js接口給 WebView 添加一個JS映射對象: searchBoxJavaBridge_對象

  • 該接口可能被利用,實現遠程任意代碼。


解決方案

刪除 searchBoxJavaBridge_ 接口

// 通過調用該方法刪除接口
removeJavascriptInterface();

2.1.3、accessibility和 accessibilityTraversal接口引起遠程代碼執行漏洞

問題分析與解決方案同上,這里不作過多闡述。


2.2、密碼明文存儲漏洞

2.2.1 問題分析

WebView默認開啟密碼保存功能 :

mWebView.setSavePassword(true)
  • 開啟后,在用戶輸入密碼時,會彈出提示框:詢問用戶是否保存密碼;

  • 如果選擇”是”,密碼會被明文保到 /data/data/com.package.name/databases/webview.db 中,這樣就有被盜取密碼的危險


2.2.2、解決方案

關閉密碼保存提醒

WebSettings.setSavePassword(false) 

2.3、域控制不嚴格漏洞

2.3.1、問題分析

先看Android里的 WebViewActivity.java

public class WebViewActivity extends Activity {private WebView webView;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_webview);webView = (WebView) findViewById(R.id.webView);//webView.getSettings().setAllowFileAccess(false);                    (1)//webView.getSettings().setAllowFileAccessFromFileURLs(true);         (2)//webView.getSettings().setAllowUniversalAccessFromFileURLs(true);    (3)Intent i = getIntent();String url = i.getData().toString(); //url = file:///data/local/tmp/attack.html webView.loadUrl(url);}}/**Mainifest.xml**/
// 將該 WebViewActivity 在Mainifest.xml設置exported屬性
// 表示:當前Activity是否可以被另一個Application的組件啟動
android:exported="true"

即 A 應用可以通過 B 應用導出的 Activity 讓 B 應用加載一個惡意的 file 協議的 url,從而可以獲取 B 應用的內部私有文件,從而帶來數據泄露威脅

具體:當其他應用啟動此 Activity 時, intent 中的 data 直接被當作 url 來加載(假定傳進來的 url 為 file:///data/local/tmp/attack.html ),其他 APP 通過使用顯式 ComponentName 或者其他類似方式就可以很輕松的啟動該 WebViewActivity 并加載惡意url。

下面我們著重分析WebView中getSettings類的方法對 WebView 安全性的影響:

  • setAllowFileAccess()

  • setAllowFileAccessFromFileURLs()

  • setAllowUniversalAccessFromFileURLs()

1、setAllowFileAccess()

// 設置是否允許 WebView 使用 File 協議
webView.getSettings().setAllowFileAccess(true);     
// 默認設置為true,即允許在 File 域下執行任意 JavaScript 代碼

使用 file 域加載的 js代碼能夠使用進行同源策略跨域訪問,從而導致隱私信息泄露

  • 同源策略跨域訪問:對私有目錄文件進行訪問

  • 針對 IM 類產品,泄露的是聊天信息、聯系人等等

  • 針對瀏覽器類軟件,泄露的是cookie 信息泄露。

如果不允許使用 file 協議,則不會存在上述的威脅;

webView.getSettings().setAllowFileAccess(true);  

但同時也限制了 WebView 的功能,使其不能加載本地的 html 文件,如下圖:

移動版的 Chrome 默認禁止加載 file 協議的文件

在這里插入圖片描述
解決方案:

  • 對于不需要使用 file 協議的應用,禁用 file 協議;
setAllowFileAccess(false); 
  • 對于需要使用 file 協議的應用,禁止 file 協議加載 JavaScript。
setAllowFileAccess(true); // 禁止 file 協議加載 JavaScript
if (url.startsWith("file://") {setJavaScriptEnabled(false);
} else {setJavaScriptEnabled(true);
}

2、setAllowFileAccessFromFileURLs()

// 設置是否允許通過 file url 加載的 Js代碼讀取其他的本地文件
webView.getSettings().setAllowFileAccessFromFileURLs(true);
// 在Android 4.1前默認允許
// 在Android 4.1后默認禁止

AllowFileAccessFromFileURLs() 設置為 true 時,攻擊者的JS代碼為:

<script>
function loadXMLDoc()
{var arm = "file:///etc/hosts";var xmlhttp;if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}xmlhttp.onreadystatechange=function(){//alert("status is"+xmlhttp.status);if (xmlhttp.readyState==4){console.log(xmlhttp.responseText);}}xmlhttp.open("GET",arm);xmlhttp.send(null);
}
loadXMLDoc();
</script>// 通過該代碼可成功讀取 /etc/hosts 的內容數據

解決方案:

設置 setAllowFileAccessFromFileURLs(false);

當設置成為 false 時,上述JS的攻擊代碼執行會導致錯誤,表示瀏覽器禁止從 file url 中的 javascript 讀取其它本地文件。

3、setAllowUniversalAccessFromFileURLs()

// 設置是否允許通過 file url 加載的 Javascript 可以訪問其他的源(包括http、https等源)
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);// 在Android 4.1前默認允許(setAllowFileAccessFromFileURLs()不起作用)
// 在Android 4.1后默認禁止

AllowFileAccessFromFileURLs() 被設置成true時,攻擊者的JS代碼是:

// 通過該代碼可成功讀取 http://www.so.com 的內容
<script>
function loadXMLDoc()
{var arm = "http://www.so.com";var xmlhttp;if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}xmlhttp.onreadystatechange=function(){//alert("status is"+xmlhttp.status);if (xmlhttp.readyState==4){console.log(xmlhttp.responseText);}}xmlhttp.open("GET",arm);xmlhttp.send(null);
}
loadXMLDoc();
</script>

解決方案:

設置 setAllowUniversalAccessFromFileURLs(false);

4、setJavaScriptEnabled()

// 設置是否允許 WebView 使用 JavaScript(默認是不允許)
webView.getSettings().setJavaScriptEnabled(true);  // 但很多應用(包括移動瀏覽器)為了讓 WebView 執行 http 協議中的 JavaScript,都會主動設置為true,不區別對待是非常危險的。

即使把 setAllowFileAccessFromFileURLs()setAllowUniversalAccessFromFileURLs() 都設置為 false,通過 file URL 加載的 javascript 仍然有方法訪問其他的本地文件:符號鏈接跨源攻擊

前提是允許 file URL 執行 javascript,即 webView.getSettings().setJavaScriptEnabled(true);

這一攻擊能奏效的原因是:通過 javascript 的延時執行和將當前文件替換成指向其它文件的軟鏈接就可以讀取到被符號鏈接所指的文件。

具體攻擊步驟:

  • 把惡意的 js 代碼輸出到攻擊應用的目錄下,隨機命名為 xx.html,修改該目錄的權限;

  • 修改后休眠 1s,讓文件操作完成;

  • 完成后通過系統的 Chrome 應用去打開該 xx.html 文件

  • 等待 4s 讓 Chrome 加載完成該 html,最后將該 html 刪除,并且使用 ln -s 命令為 Chrome 的 Cookie 文件創建軟連接

注:在該命令執行前 xx.html 是不存在的;執行完這條命令之后,就生成了這個文件,并且將 Cookie 文件鏈接到了 xx.html 上。

于是就可通過鏈接來訪問 Chrome 的 Cookie

1、Google 沒有進行修復,只是讓Chrome 最新版本默認禁用 file 協議,所以這一漏洞在最新版的 Chrome 中并不存在
2、但是,在日常大量使用 WebView 的App和瀏覽器,都有可能受到此漏洞的影響。通過利用此漏洞,容易出現數據泄露的危險

如果是 file 協議,禁用 javascript 可以很大程度上減小跨源漏洞對 WebView 的威脅。

1、但并不能完全杜絕跨源文件泄露。
2、例:應用實現了下載功能,對于無法加載的頁面,會自動下載到 sd 卡中;由于 sd 卡中的文件所有應用都可以訪問,于是可以通過構造一個 file URL 指向被攻擊應用的私有文件,然后用此 URL 啟動被攻擊應用的 WebActivity,這樣由于該 WebActivity 無法加載該文件,就會將該文件下載到 sd 卡下面,然后就可以從 sd 卡上讀取這個文件了

最終解決方案

對于不需要使用 file 協議的應用,禁用 file 協議;

// 禁用 file 協議;
setAllowFileAccess(false); 
setAllowFileAccessFromFileURLs(false);
setAllowUniversalAccessFromFileURLs(false);

對于需要使用 file 協議的應用,禁止 file 協議加載 JavaScript。

// 需要使用 file 協議
setAllowFileAccess(true); 
setAllowFileAccessFromFileURLs(false);
setAllowUniversalAccessFromFileURLs(false);// 禁止 file 協議加載 JavaScript
if (url.startsWith("file://") {setJavaScriptEnabled(false);
} else {setJavaScriptEnabled(true);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446788.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446788.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446788.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

將讀寫鎖放到共享內存,實現進程之間對于同一文件的讀寫操作

思路 將讀寫鎖和讀寫鎖的屬性以及一個用于存儲共享內存的地址的int型變量三者封裝成一個struct結構將這個結構體放到共享內存中&#xff0c;以及將讀寫鎖的屬性設置成全局性質&#xff0c;然后使用這個屬性初始化鎖&#xff0c;以及將鎖的地址關聯到結構體的內存地址這個變量定…

Android Studio 查看頁面布局層次結構

Android Studio有個可以查看手機上app頁面布局層次結構的工具。可以協助我們對布局進行優化&#xff0c;去掉沒有必要的節點等&#xff0c;通過這個工具可以清晰的看見頁面整個結構&#xff1b;廢話少說直接上圖&#xff0c;再說過程。 這就是我們想要看到的&#xff0c;每個節…

Java web后端 第一章框架搭建

Redis 通用Mapper 通用Mapper->MyBatis動態SQL封裝包,增刪改查 0 SQL語句 PageHelper PageHelper–>實現分頁操作,不需要limit,直接使用靜態方法 電商系統技術特點 分布式(數據很多,一臺電腦存儲一部分數據) 高并發,集群(并發量很高,后臺不只一個電腦) ,海量數據 主…

進程鎖 讀寫文件的小例子 C++代碼

代碼 #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <cassert> #include <pthread.h> #include <cstdio> #include <cstdlib> #include <fstream> #include <io…

Java 中sleep()與wait()的區別

目錄一、原理不同二、鎖的處理機制不同三、使用的區域不同四、異常捕獲不同五、總結一、原理不同 sleep()是Thread類的靜態方法&#xff0c;是線程用來控制自身流程的&#xff0c;它會使此線程暫停執行指定的時間&#xff0c;而把執行機會讓給其他的線程&#xff0c;等到計時時…

android--地圖定位打卡

獲取位置信息 1)位置信息 GPS衛星定位,在室外適用 基站(3個基站交叉,鎖定手機位置)–基站定位不平均,有些地方實現不了3點定位 網絡定位–通過手機IP地址,去鎖定位置(消耗流量,對網絡有要求) 谷歌地圖的大致實現思路(通用) 2)實現定位功能的重要類 在百度地圖和高德地圖中不…

Android 將整形顏色值轉換成String類型

轉換方法&#xff1a; val hexColor String.format("#%06X", [0xFFFFFF or intColor]);轉換結果&#xff1a; #F2EADA

MacOS 的 zsh 和 bash 切換

目錄一、從 bash 切換到 zsh1、使用系統自帶的 zsh2、使用第三方的 zsh2.1、Clone代碼到本地2.2、備份你已存在的 ~/.zshrc 文件2.3、新建一份新的 zsh 配置文件2.4、改變默認的shell腳本二、從 zsh 切換回 bash三、zsh 和 bash 的環境變量zsh、bash 都是shell&#xff0c;zsh …

android--在命令行中生成Android的數字證書keystore文件

標題 生成 密鑰口令為 13458977480 密鑰庫口令為 13458977480 存放位置 查看證書的相關資料

linux查看系統日志

cd /var/log/gscubuntu:/var/log$ tail -f syslog

IDEA 創建 SpringBoot 項目

目錄一、新建Springboot項目第一步&#xff1a;新建一個Springboot項目第二步&#xff1a;選擇項目模板第三步&#xff1a;設置項目配置第四步&#xff1a;設置項目依賴第五步&#xff1a;設置項目名稱及路徑第六步&#xff1a;創建完成二、測試及運行1、測試代碼2、設置默認端…

VC++軟件

一個main fatal error LNK1169: 找到一個或多個多重定義的符號–報錯 一個項目即一個程序&#xff0c;多個文件只能有一個main函數 刪除掉多余的main 控制臺按enter鍵閃退 在代碼中加上 #include<stdlib.h> getchar();//讓控制臺停留 system("pause");//讓…

IDEA 將 SpringBoot 項目打包成jar

目錄一、打包配置1、File -> Project Structure2、Project Structure3、設置啟動類及META-INF4、設置打包輸出目錄二、打包1、Build -> Artifacts2、Build三、查看打包文件四、運行新建SpringBoot項目&#xff1a;IDEA 創建 SpringBoot 項目 一、打包配置 1、File -> …

2014年考研英語一完型填空知識點

單詞 單詞釋意commitv犯罪sufficientlyadv足夠gainfuladj有收益的socioeconomicadj社會經濟的discontentn/v不滿意householdn家庭supervisionn監督offensiveadj冒犯的conditionn狀態casualadj隨意的causaladj因果關系的establishedadj已確立,公認的interactionn相互作用或影響…

如何查看軟連接,以及相關注意事項

使用命令 ls -il 圖片顯示 參考鏈接 Linux 命令之軟連接詳解Linux軟連接 查看/創建/刪除

Git SSH key配置

一、檢查本地Git配置 用如下命令&#xff08;如未特別說明&#xff0c;所有命令均默認在Git Bash工具下執行&#xff09;檢查一下用戶名和郵箱是否配置&#xff08;github支持我們用用戶名或郵箱登錄&#xff09;&#xff1a; git config --global --list 顯示信息如下&#…

2014年英語一閱讀理解Text1

單詞解釋chancellorn總理upfrontadj坦率的eligibleadj有資格的,合格的fortnightlyadv兩星期一次的sign on辦理reformn改革subsidisev補助zealn熱情taxpayern納稅人claimantn(因失業)領取救濟金者skip down邊跳邊走prospectn前景psychologicallyadv心理上地excludev不包括crucia…

HTTPS 工作原理

一、簡介 HTTPS對于客戶端開發人員來說并沒有什么需要特別注意的地方&#xff0c;因為代碼和寫HTTP請求時并沒有什么兩樣。但也正是因為這個原因&#xff0c;導致許多客戶端開發人員對HTTPS并不了解&#xff0c;只知道它是安全的加密網絡傳輸&#xff0c;對其具體的工作原理卻一…

解決VM虛擬機中ubuntu系統上不了網的問題

最簡單的方式 關閉虛擬機在對應的虛擬機上右鍵&#xff0c;點擊設置&#xff0c;找到網絡適配器&#xff0c;點擊移除&#xff0c;再次點擊添加&#xff0c;將網絡適配器再次添加回來&#xff0c;點擊確定重啟虛擬機如果第一種方式解決不了問題&#xff0c;請使用第二種方式 …