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.mzph.cn/news/446788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio 查看页面布局层次结构

Android Studio有个可以查看手机上app页面布局层次结构的工具。可以协助我们对布局进行优化&#xff0c;去掉没有必要的节点等&#xff0c;通过这个工具可以清晰的看见页面整个结构&#xff1b;废话少说直接上图&#xff0c;再说过程。 这就是我们想要看到的&#xff0c;每个节…

Java web后端 第一章框架搭建

Redis 通用Mapper 通用Mapper->MyBatis动态SQL封装包,增删改查 0 SQL语句 PageHelper PageHelper–>实现分页操作,不需要limit,直接使用静态方法 电商系统技术特点 分布式(数据很多,一台电脑存储一部分数据) 高并发,集群(并发量很高,后台不只一个电脑) ,海量数据 主…

android--地图定位打卡

获取位置信息 1)位置信息 GPS卫星定位,在室外适用 基站(3个基站交叉,锁定手机位置)–基站定位不平均,有些地方实现不了3点定位 网络定位–通过手机IP地址,去锁定位置(消耗流量,对网络有要求) 谷歌地图的大致实现思路(通用) 2)实现定位功能的重要类 在百度地图和高德地图中不…

android--在命令行中生成Android的数字证书keystore文件

标题 生成 密钥口令为 13458977480 密钥库口令为 13458977480 存放位置 查看证书的相关资料

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 -> …

如何查看软连接,以及相关注意事项

使用命令 ls -il 图片显示 参考链接 Linux 命令之软连接详解Linux软连接 查看/创建/删除

Git SSH key配置

一、检查本地Git配置 用如下命令&#xff08;如未特别说明&#xff0c;所有命令均默认在Git Bash工具下执行&#xff09;检查一下用户名和邮箱是否配置&#xff08;github支持我们用用户名或邮箱登录&#xff09;&#xff1a; git config --global --list 显示信息如下&#…

HTTPS 工作原理

一、简介 HTTPS对于客户端开发人员来说并没有什么需要特别注意的地方&#xff0c;因为代码和写HTTP请求时并没有什么两样。但也正是因为这个原因&#xff0c;导致许多客户端开发人员对HTTPS并不了解&#xff0c;只知道它是安全的加密网络传输&#xff0c;对其具体的工作原理却一…

解决VM虚拟机中ubuntu系统上不了网的问题

最简单的方式 关闭虚拟机在对应的虚拟机上右键&#xff0c;点击设置&#xff0c;找到网络适配器&#xff0c;点击移除&#xff0c;再次点击添加&#xff0c;将网络适配器再次添加回来&#xff0c;点击确定重启虚拟机如果第一种方式解决不了问题&#xff0c;请使用第二种方式 …

Android Glide图片加载框架(一)基本用法

文章目录一、前言二、简介三、基本用法第一步&#xff1a;调用 Glide.with() 方法创建加载图片的实例第二步&#xff1a;调用 load() 方法指定待加载的图片资源第三步&#xff1a;调用 into() 方法绑定显示控件总结四、扩展用法1、占位图2、指定图片格式3、指定图片大小Android…

操作系统 进程 学习以及思考

进程管理逻辑图 将多个程序拷贝到进程中&#xff0c;占用内存&#xff0c;如图扇形区域&#xff0c;当酷狗进程需要资源的时候&#xff0c;会通过I/O子系统取用资源的过程中&#xff0c;会放弃对cpu的占用&#xff0c;cpu就会处理别的进程&#xff0c;因此提高了cpu的利用率&am…

Android Glide图片加载框架(二)源码解析之with()

文章目录一、前言二、如何阅读源码三、源码解析1、with()Android Glide图片加载框架系列文章 Android Glide图片加载框架&#xff08;一&#xff09;基本用法 Android Glide图片加载框架&#xff08;二&#xff09;源码解析之with() Android Glide图片加载框架&#xff08;二…

计算机操作系统生产者和消费者模型的简单介绍

同步互斥小口诀 画图理解题目判断题目类型分析进程数目 填写进程模板补充基本代码(伪代码)补充PV代码检查调整代码 注意事项 代码是一步一步写出来的&#xff0c;代码是反复调整写出来的60%是生产者和消费者模型30%是读者和写者的模型 生产者和消费者 例子1 妈妈每次放放一…

Android Glide图片加载框架(二)源码解析之load()

文章目录一、前言二、源码分析1、load()Android Glide图片加载框架系列文章 Android Glide图片加载框架&#xff08;一&#xff09;基本用法 Android Glide图片加载框架&#xff08;二&#xff09;源码解析之with() Android Glide图片加载框架&#xff08;二&#xff09;源码…

计算机操作系统读者和写者模型的简单介绍以及思考

读者和写者 读写两组进程&#xff0c;共享一个文件&#xff0c;多个读者可以同时访问文件&#xff0c;多个写者不可以同时访问文件&#xff0c;写者和读者也不可以同时访问文件共享读&#xff1b;独占写特征:1,资源被谁占有&#xff1b;2&#xff0c;写者改变资源&#xff0c;…

Android Glide图片加载框架(二)源码解析之into()

文章目录一、前言二、源码解析1、into(ImageView)2、GlideContext.buildImageViewTarget()3、RequestBuilder.into(Target,RequestListener,RequestOptions);4、RequestBuilder.buildRequest()5、SingleRequest.obtain()6、isEquivalentTo()、isSkipMemoryCacheWithCompletePre…

2014年考研英语一翻译知识点

题目讲解网址 总结 1.做翻译题,不用看句子前后的地方,直接看要翻译的部分 2.多根据语境去翻译 3.如果是不认识的单词,一般都是我们平常经常使用/说的词的代替高级词 题目句子 It is also the reason why when we try to describe music with words, all wecan do is articul…

计算机操作系统 死锁问题

概念 条件是基础&#xff0c;在一定的原因下&#xff0c;产生结果死锁三胞胎 死锁 僵持&#xff0c;消耗时间&#xff0c;双方都占用了部分资源&#xff0c;不释放活锁 双方互相谦让&#xff0c;都不占用资源饥饿 谦让的一方一直等待&#xff0c;无法占有资源&#xff0c;导致…