-
-
[原创]CVE-2012-6636复现---Webview远程代码执行漏洞
-
发表于: 2021-11-28 16:16 12146
-
参考几位大佬:
https://www.cnblogs.com/YenKoc/p/13589979.html
https://blog.csdn.net/u012195899/article/details/68942725
https://cloud.tencent.com/developer/article/1743487
WebView.addJavascriptInterface(Object obj, String interfaceName)
使用addJavascriptInterface方法注册可供JavaScript调用的Java对象;
使用WebView加载外部网页或者本地网页,且该网页中有恶意的js代码;
Android系统版本低于4.2;
Android系统通过WebView.addJavascriptInterface方法注册可供JavaScript调用的Java对象,以用于增强JavaScript的功能。但是系统并没有对注册Java类的方法调用的限制。导致攻击者可以利用反射机制调用未注册的其它任何Java类,最终导致JavaScript能力的无限增强。攻击者利用该漏洞可以根据客户端能力为所欲为。
API Level 依赖的API Level为17或者以上,就不会受到该问题的影响
对于API Level 等于或低于17的Android系统:
建议不要使用addJavascriptInterface接口;
如果一定要用addJavascriptInterface:
如果使用HTTPS协议加载URL,应进行证书校验防止访问的页面被篡改挂马;
如果使用HTTP协议加载URL,应进行白名单过滤、完整性校验等防止访问的页面被篡改;
如果加载本地Html,应将html文件内置在APK中,以及进行对html页面完整性校验。
参考:https://blog.csdn.net/tongdanping/article/details/103252352
为什么需要反射?(反射的作用/应用场景)
反射的作用可以用一句话概括:反射赋予了jvm动态编译的能力。动态编译可以最大限度的体现Java的灵活性(多态)。
否则类的元信息只能通过静态编译的形式实现(在编译期确定类型,绑定对象),而不能实现动态编译(在运行期确定类型,绑定对象)。也就是说在编译以后,程序在运行时的行为就是固定的了,如果要在运行时改变程序的行为,就需要动态编译,在Java中就需要反射机制。
有的类是我们在编写程序的时候无法使用new一个对象来实例化对象的。例如:调用的是来自网络的二进制.class文件,而没有其.java代码;
有的类可以在用到时再动态加载到jvm中,这样可以减少jvm的启动时间,同时更重要的是可以动态的加载需要的对象(多态)。
因为java代码是先通过编译器将.java文件编译成.class的二进制字节码文件,因此如果我们使用new Person()来实例化对象person会出现的问题就是如果我们希望更换person的实例对象,就要在源代码种更改然后重新编译再运行,但是如果我们将person的实例对象类名等信息编写在配置文件中,利用反射的Class.forName(className)方法来实例化java对象(因为实例化java对象都是根据全限定名查找到jvm内存中的class对象,并根据class对象中的累信息实例化得到java对象,因此xml文件中只要包含了权限定类名就可以通过反射实例化java对象),那么我们就可以更改配置文件,无需重新编译。例如:
这个函数作用是:将java的一个对象映射成javascript的一个对象。这样js代码就可以直接调用java对象。
在main_activity.java同目录下定义一个AndroidtoJS.java如下:
如图:创建一个assets文件夹
需要加载JS代码:javascript.html
通过addJavascriptInterface,把Android的对象映射成js的对象,这样js代码可以直接调用该android对象中的函数。
mainactivity.java
activity_main.xml代码如下
执行如下:
类似上面的过程。
在main_activity.java同目录下定义一个AndroidtoJS.java如下:
如图:javascript.html
通过addJavascriptInterface,把Android的对象映射成js的对象,这样js代码可以直接调用该android对象中的函数。
mainactivity.java
activity_main.xml代码如下
复现截图
如图所示,我们的html里面有恶意的js代码,执行了ls -al /sdcard命令,该命令的结果显示在APP了页面上(与在命令行中实际的执行结果相同)。
综上,如果我们使用了addJavascriptInterface这个危险接口,则当我们引入的webview网页中有恶意的js代码时,则可以实现任意命令执行。
package com.example.testaddjs;
import
android.webkit.JavascriptInterface;
public
class
AndroidtoJs extends
Object
{
/
/
定义JS需要调用的方法
/
/
被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public void hello(String msg) {
System.out.println(msg);
}
}
package com.example.testaddjs;
import
android.webkit.JavascriptInterface;
public
class
AndroidtoJs extends
Object
{
/
/
定义JS需要调用的方法
/
/
被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public void hello(String msg) {
System.out.println(msg);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset
=
"utf-8"
>
<title>Carson<
/
title>
<script>
function callAndroid(){
/
/
由于对象映射,所以调用test对象等于调用Android映射的对象
test.hello(
"js调用了android中的hello方法"
);
}
<
/
script>
<
/
head>
<body>
/
/
点击按钮则调用callAndroid函数
<button
type
=
"button"
id
=
"button1"
onclick
=
"callAndroid()"
><
/
button>
<
/
body>
<
/
html>
<!DOCTYPE html>
<html>
<head>
<meta charset
=
"utf-8"
>
<title>Carson<
/
title>
<script>
function callAndroid(){
/
/
由于对象映射,所以调用test对象等于调用Android映射的对象
test.hello(
"js调用了android中的hello方法"
);
}
<
/
script>
<
/
head>
<body>
/
/
点击按钮则调用callAndroid函数
<button
type
=
"button"
id
=
"button1"
onclick
=
"callAndroid()"
><
/
button>
<
/
body>
<
/
html>
package com.example.testaddjs;
import
androidx.appcompat.app.AlertDialog;
import
androidx.appcompat.app.AppCompatActivity;
import
android.content.DialogInterface;
import
android.os.Bundle;
import
android.view.View;
import
android.webkit.JsResult;
import
android.webkit.WebChromeClient;
import
android.webkit.WebSettings;
import
android.webkit.WebView;
import
android.widget.Button;
public
class
MainActivity extends AppCompatActivity {
WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView
=
(WebView) findViewById(R.
id
.webview);
WebSettings webSettings
=
mWebView.getSettings();
/
/
设置与Js交互的权限
webSettings.setJavaScriptEnabled(true);
/
/
通过addJavascriptInterface()将Java对象映射到JS对象
/
/
参数
1
:Javascript对象名
/
/
参数
2
:Java对象名
mWebView.addJavascriptInterface(new AndroidtoJs(),
"test"
);
/
/
AndroidtoJS类对象映射到js的test对象
/
/
加载JS代码
/
/
格式规定为:
file
:
/
/
/
android_asset
/
文件名.html
mWebView.loadUrl(
"file:///android_asset/javascript.html"
);
}
}
package com.example.testaddjs;
import
androidx.appcompat.app.AlertDialog;
import
androidx.appcompat.app.AppCompatActivity;
import
android.content.DialogInterface;
import
android.os.Bundle;
import
android.view.View;
import
android.webkit.JsResult;
import
android.webkit.WebChromeClient;
import
android.webkit.WebSettings;
import
android.webkit.WebView;
import
android.widget.Button;
public
class
MainActivity extends AppCompatActivity {
WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView
=
(WebView) findViewById(R.
id
.webview);
WebSettings webSettings
=
mWebView.getSettings();
/
/
设置与Js交互的权限
webSettings.setJavaScriptEnabled(true);
/
/
通过addJavascriptInterface()将Java对象映射到JS对象
/
/
参数
1
:Javascript对象名
/
/
参数
2
:Java对象名
mWebView.addJavascriptInterface(new AndroidtoJs(),
"test"
);
/
/
AndroidtoJS类对象映射到js的test对象
/
/
加载JS代码
/
/
格式规定为:
file
:
/
/
/
android_asset
/
文件名.html
mWebView.loadUrl(
"file:///android_asset/javascript.html"
);
}
}
<?xml version
=
"1.0"
encoding
=
"utf-8"
?>
<LinearLayout xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:orientation
=
"vertical"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
>
<WebView
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:
id
=
"@+id/webview"
>
<
/
WebView>
<
/
LinearLayout>
<?xml version
=
"1.0"
encoding
=
"utf-8"
?>
<LinearLayout xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:orientation
=
"vertical"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
>
<WebView
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:
id
=
"@+id/webview"
>
<
/
WebView>