注意URL和gid等参数的变化!
注意提交刷票参数代码的变化(参数顺序、随机参数名长度):
data:{'b90fc601b40454242223eb3c9fff52a8':number,'c2afe6b237d39f704cc4a172d4c858ab':name,'047fedf333cad42c3b2bbd66a77c027e':department,gid:gid,'4be1a10913904f5006a7fb7f75232e11':$("#4be1a10913904f5006a7fb7f75232e11").val()},
表单页面原始URL:
http://voice.xxx.com/index.php?m=grabvotes&a=showform&gid=10
表单页面原始内容:
<!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>
<link charset="utf-8" rel="stylesheet" href="http://voice.xxx.com/statics/css//grabvotes.css" type="text/css"/>
<script type="text/javascript" src="http://voice.xxx.com/statics/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://voice.xxx.com/statics/js/jbox/jquery.jBox-2.3.min.js"></script>
<link type="text/css" rel="stylesheet" href="http://voice.xxx.com/statics/js/jbox/Skins/SFI/jbox.css"/>
<div align="center" >
<div class="login_lay_01">
<table border="0" cellspacing="0" cellpadding="0" class="table_lay" style="background:url(http://voice.xxx.com/index.php?m=grabvotes&c=index&a=get_bg_img&2111419857) no-repeat left center;" >
<script>
document.write('<tr><th></th><td width=\"80\"><span><input name=\"5759b3532219844e5afb893f451c5af0\" id=\"5759b3532219844e5afb893f451c5af0\" type=\"text\" style=\"width:80px; background-image:url(http://voice.xxx.com/statics/images/grabvotes/lg_input_bg_code.png)\"/></span></td><td width=\"89\"><img id=\'code_img\' οnclick=\'this.src=this.src+\"&\"+Math.random()\' src=\'http://voice.xxx.com/api.php?op=checkcode_ticket&code_len=4&font_size=14&width=70&height=30&font_color=&background=&gid=14\'></td></tr><tr><th></th><td colspan=\"2\"><span><input name=\"c87222f198fb3312206b9c8cb6316d95\" id=\"c87222f198fb3312206b9c8cb6316d95\" type=\"text\" /></span></td></tr><tr><th></th><td colspan=\"2\"><span><input name=\"c5be4964b5da41c597ec0fb3bec28a24\" id=\"c5be4964b5da41c597ec0fb3bec28a24\" type=\"text\" /></span></td></tr><tr><th width=\"68\"></th><td colspan=\"2\"><span><input name=\"2026432a0967b8d28e68615e64316d9f\" id=\"2026432a0967b8d28e68615e64316d9f\" type=\"text\" /></span></td></tr>');
</script>
</table>
</div>
<div class="login_lay_02"><input type="hidden" name="gid" id="gid" value="14"/><input class="lay_btn1" type="button"/> <input class="lay_btn2" type="button"/></div>
<div class="clear"></div>
</div>
<script>
$('.lay_btn1').click(function(){
var number=$("#2026432a0967b8d28e68615e64316d9f").val();
var name=$("#c5be4964b5da41c597ec0fb3bec28a24").val();
var department=$("#c87222f198fb3312206b9c8cb6316d95").val();
var gid=$("#gid").val();
var reg=/^\d{6}$/;
if(reg.test(number))
if(number!='请输入正确工号'&&name!='请输入真实姓名'&&department!='请输入所属部门'){
$.ajax({
type:'post',
dataType:'json',
url:'http://voice.xxx.com/index.php?m=grabvotes&c=index&a=register',
data:{'2026432a0967b8d28e68615e64316d9f':number,'c5be4964b5da41c597ec0fb3bec28a24':name,'c87222f198fb3312206b9c8cb6316d95':department,gid:gid,'5759b3532219844e5afb893f451c5af0':$("#5759b3532219844e5afb893f451c5af0").val()},
success:function(data){
switch(data.status){
case 1: $.jBox.info('成功提交!等待审核。','提示',{ closed: function () { top.$.jBox.close(); } });$('.login_lay').slideUp(200); setTimeout("reload()",1000); break;
case 2: $.jBox.info('你已经抢过票啦!','提示',{ closed: function () { top.$.jBox.close(); } });break;
case 3: $.jBox.info('~~~~(>_<)~~~~ 慢了一步,已经没票了!','提示',{ closed: function () { top.$.jBox.close(); } });break;
case 5: $.jBox.info('~~~~(>_<)~~~~ 慢了一步,活动已经结束了!','提示',{ closed: function () { top.$.jBox.close(); } });break;
case 6: $.jBox.info('亲!同一部电影一台电脑只能抢一次哦!','提示',{ closed: function () { top.$.jBox.close(); } });break;
case 7: $.jBox.info('验证码错误,点击刷新!','提示');break;
case 11: $.jBox.info('填写时间小于5秒!','提示');break;
default : $.jBox.info('非法操作!','提示',{ closed: function () { top.$.jBox.close(); } });break;
}
},
error:function(data){
$.jBox.info('抢票失败!','提示');
}
});
}else{$.jBox.info('亲,请把信息填完整哦!','提示');}
});
$('#2026432a0967b8d28e68615e64316d9f').blur(function(){
var num=$('#2026432a0967b8d28e68615e64316d9f').val();
var reg=/^\d{6,8}$/;
if(!reg.test(num)){
$.jBox.info('亲,请输入6位或8位数字的工号!','提示');
}
});
$('.login_lay_02 .lay_btn2').click(function(){
top.$.jBox.close();
})
//$(function(){
// $(".table_lay").css("background","url(http://voice.xxx.com/index.php?m=grabvotes&c=index&a=get_bg_img&"+Math.random()+") no-repeat left center");
// });
</script>
</body>
</html>
验证码原始URL:
http://voice.xxx.com/api.php?op=checkcode_ticket&code_len=4&font_size=14&width=70&height=30&font_color=&background=&gid=10
抢票提交原始URL:
http://voice.xxx.com/index.php?m=grabvotes&c=index&a=register
1,web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>TestWeb</display-name>
<servlet>
<display-name>loadFormPage</display-name>
<servlet-name>loadFormPage</servlet-name>
<servlet-class>crack.LoadFormPageServlet</servlet-class>
</servlet>
<servlet>
<display-name>loadCheckCode</display-name>
<servlet-name>loadCheckCode</servlet-name>
<servlet-class>crack.LoadCheckCode</servlet-class>
</servlet>
<servlet>
<display-name>crackTickets</display-name>
<servlet-name>crackTickets</servlet-name>
<servlet-class>crack.CrackTickets</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loadFormPage</servlet-name>
<url-pattern>/loadFormPage.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>loadCheckCode</servlet-name>
<url-pattern>/loadCheckCode.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>crackTickets</servlet-name>
<url-pattern>/crackTickets.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2,加载表单页面的servlet
LoadFormPageServlet.java
package crack;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoadFormPageServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
public static final String VOICE_URL = "http://voice.xxx.com/index.php";
public LoadFormPageServlet(){
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
//使用URLEncoder.encode对特殊字符和不可见字符进行编码
String loadFormPageURL = VOICE_URL + "?m=grabvotes&a=showform&gid=10";
URL formUrl = new URL(loadFormPageURL);
HttpURLConnection formConnection = (HttpURLConnection)(formUrl.openConnection());
formConnection.setUseCaches(false);
formConnection.setRequestProperty("Connection", "keep-alive");
formConnection.connect();
response.setCharacterEncoding("UTF-8");
Map<String, List<String>> headerFields = formConnection.getHeaderFields();
List<String> setCookies = headerFields.get("Set-Cookie");
String[] aCookie = new String[2];
for(String cook : setCookies)
{
System.out.println("加载表单页面接收到Set-Cookie:" + cook);
aCookie = ((cook.split(";"))[0]).split("=");
response.addCookie(new Cookie(aCookie[0], aCookie[1]));
}
BufferedReader reader = new BufferedReader(new InputStreamReader(formConnection.getInputStream()));
String lines = null;
while((lines = reader.readLine()) != null)
{
lines = lines.replaceAll("voice\\.xxx\\.com", "localhost:8080/Crack")
.replaceAll("api\\.php", "loadCheckCode.do");
response.getWriter().print(lines);
}
reader.close();
response.getWriter().print("<script type=\"text/javascript\" src=\"./crack.js\"></script>");
formConnection.disconnect();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doPost(request, response);
}
}
3,加载验证码的servlet
LoadCheckCode.java
package crack;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoadCheckCode extends HttpServlet
{
private static final long serialVersionUID = 1L;
public static final String CHECK_CODE_URL = "http://voice.xxx.com/api.php?op=checkcode_ticket&code_len=4&font_size=20&width=150&height=60&font_color=blue&background=&gid=10";
public LoadCheckCode(){
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
URL imgUrl = new URL(CHECK_CODE_URL);
HttpURLConnection formConnection = (HttpURLConnection)(imgUrl.openConnection());
formConnection.setUseCaches(false);
formConnection.setRequestProperty("Connection", "keep-alive");
for(Cookie cookie : request.getCookies())
{
formConnection.setRequestProperty("Cookie", cookie.getName() + "=" + cookie.getValue());
System.out.println("读取验证码图片,携带Cookie:" + cookie.getName() + "===" + cookie.getValue());
}
formConnection.connect();
try
{
byte[] imgBytes = readInputStream(formConnection.getInputStream());
response.getOutputStream().write(imgBytes);
response.getOutputStream().flush();
}
catch(Exception e)
{
e.printStackTrace();
}
formConnection.disconnect();
}
public byte[] readInputStream(InputStream inStream) throws Exception
{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = inStream.read(buffer)) != -1)
{
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doPost(request, response);
}
}
4,提交刷票请求Servlet
CrackTickets.java
package crack;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CrackTickets extends HttpServlet
{
private static final long serialVersionUID = 1L;
public static final String CRACK_URL = "http://voice.xxx.com/index.php";
public CrackTickets(){
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
Thread.sleep(4000);//控制提交时间,防止提交太快被阻止
}
catch(InterruptedException e)
{
e.printStackTrace();
}
response.setCharacterEncoding("UTF-8");
URL crackUrl = new URL(CRACK_URL);
HttpURLConnection crackConnection = (HttpURLConnection)(crackUrl.openConnection());
crackConnection.setRequestProperty("accept", "*/*");
crackConnection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
crackConnection.setUseCaches(false);
crackConnection.setRequestProperty("Connection", "keep-alive");
crackConnection.setDoOutput(true);
crackConnection.setDoInput(true);
crackConnection.setRequestMethod("POST");
crackConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
for(Cookie cookie : request.getCookies())
{
crackConnection.setRequestProperty("Cookie", cookie.getName() + "=" + cookie.getValue());
System.out.println("提交刷票请求,携带Cookie:" + cookie.getName() + "===" + cookie.getValue());
}
StringBuffer params = new StringBuffer("m=grabvotes&c=index&a=register&gid=14");
params.append("&" + request.getParameter("empCodeName") + "=" + request.getParameter("empCodeValue"));
params.append("&" + request.getParameter("empName") + "=" + request.getParameter("empValue"));
params.append("&" + request.getParameter("departmentName") + "=" + request.getParameter("departmentValue"));
params.append("&" + request.getParameter("checkCodeName") + "=" + request.getParameter("checkCodeValue"));
System.out.println("刷票参数:" + params);
crackConnection.connect();
DataOutputStream dos = new DataOutputStream(crackConnection.getOutputStream());
dos.writeBytes(params.toString());
dos.flush();
dos.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(crackConnection.getInputStream()));
System.out.println("刷票返回结果:");
String lines = null;
while((lines = reader.readLine()) != null)
{
System.out.println(lines);
response.getWriter().print(lines);
}
reader.close();
crackConnection.disconnect();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doPost(request, response);
}
}
5,页面注入JavaScript
Crack.js
dataReg正则表达式用来抓取提交刷票请求时Ajax参数的javascript代码:
data:{'b90fc601b40454242223eb3c9fff52a8':number,'c2afe6b237d39f704cc4a172d4c858ab':name,'047fedf333cad42c3b2bbd66a77c027e':department,gid:gid,'4be1a10913904f5006a7fb7f75232e11':$("#4be1a10913904f5006a7fb7f75232e11").val()}
从抓取的js参数中,提取出随机生成的参数名称
var dataReg = /\bdata\s*:\s*\{((\s*\'\w+\'\s*:\s*((\w+)|(\$\(\"#\w+\"\)\.val\(\)))\s*\,?\s*)|(\b\w+\s*:\s*\w+\s*\,?\s*))+\}/;
var idReg = /\'\w+\'\s*:/;
var empCodeID = "";
var empNameID = "";
var deptID = "";
var checkCodeID = "";
$(document).ready(
function(){
$("script").each(
function(){
var scriptText = $(this).text();
var dataString = null;
var params = null;
if((dataString=dataReg.exec(scriptText))!=null)
{
//console.info(dataString[0]);
params = dataString[0].split(",");
empCodeID = (idReg.exec(params[0]))[0].substring(1, 33);
empNameID = (idReg.exec(params[1]))[0].substring(1, 33);
deptID = (idReg.exec(params[2]))[0].substring(1, 33);
checkCodeID = (idReg.exec(params[4]))[0].substring(1, 33);
return false;
}
}
);
$("#"+empCodeID).val("001");
$("#"+empNameID).val("老王");
$("#"+deptID).val("总裁办");
$("#"+checkCodeID).keyup(
function(){
if($("#"+checkCodeID).val().length==4)
{
$.ajax({
type: 'post',
dataType: 'json',
url: 'crackTickets.do',
data: {
empCodeName: empCodeID,
empName: empNameID,
departmentName: deptID,
checkCodeName: checkCodeID,
empCodeValue: $("#"+empCodeID).val(),
empValue: $("#"+empNameID).val(),
departmentValue: $("#"+deptID).val(),
checkCodeValue: $("#"+checkCodeID).val(),
gid: "14"
},
success: function(data){
switch(data.status)
{
case 1: alert('成功提交!等待审核。'); break;
case 2: alert('你已经抢过票啦!');break;
case 3: alert('慢了一步,已经没票了!');break;
case 5: alert('慢了一步,活动已经结束了!');break;
case 6: alert('亲!同一部电影一台电脑只能抢一次哦!');break;
case 7: alert('验证码错误,点击刷新!');break;
case 11: alert('填写时间小于5秒!');break;
default : alert('非法操作!');break;
}
},
error:function(data){
alert('抢票失败!','提示');
}
});
}
}
);
$("#"+checkCodeID).focus();
}
);