12306本身有很多很明显的漏洞和缺陷。比如订票查询必须的5秒钟其实只是界面上的限制,服务器的查询没有任何限制。比如查询结果的mmstr是没有绑定用户的,一个账户查出所有用户可用。比如订单提交页的5秒时间没有任何提示。这些从12306存在的第一天开始就存在,在这些没有被微博大规模转发引人注目时,他们是懒得去修正的。
封堵……这种费力不讨好的事情,看起来很像小孩子才会做的事情。
好吧废话不多说了。说说12306的变更。
首先是验证码地址的变更。这个变更基本上没啥技术含量,但是神奇的是原地址居然还是有效的,便给了用户始终输不对的错觉。
地址从 passCodeAction.do 改为 passCodeNewAction.do。
然后,大招憋出来了。
在登录页面、查询页面、订单提交页面,分别会插入三个动态的脚本文件。基础地址都是这样的:
https://dynamic.12306.cn/otsweb/dynamicJsAction.do?jsversion=7576&method=loginJs
method=后面的内容根据页面不同会有差别,在登录、查询、订单提交页面,分别是 loginJS、queryJS、orderJS。
这个脚本的内容大致相同,有细微差别。典型内容如下:
(function($) {
function fw(kw) {
var hasKey = false;
var values = kw['values'];
var html = $(kw['key']).html();
if (html) {
for (var i = 0; i < values.length; i++) {
if (html.indexOf(values[i]) > -1) {
hasKey = true;
break;
}
}
}
return hasKey;
}
function bin216(s) {
var i, l, o = "",
n;
s += "";
b = "";
for (i = 0, l = s.length; i < l; i++) {
b = s.charCodeAt(i);
n = b.toString(16);
o += n.length < 2 ? "0" + n: n;
}
return o;
};
var Base32 = new
function() {
var delta = 0x9E3779B8;
function longArrayToString(data, includeLength) {
var length = data.length;
var n = (length – 1) << 2;
if (includeLength) {
var m = data[length – 1];
if ((m < n – 3) || (m > n)) return null;
n = m;
}
for (var i = 0; i < length; i++) {
data[i] = String.fromCharCode(data[i] & 0xff, data[i] >>> 8 & 0xff, data[i] >>> 16 & 0xff, data[i] >>> 24 & 0xff);
}
if (includeLength) {
return data.join(").substring(0, n);
} else {
return data.join(");
}
};
function stringToLongArray(string, includeLength) {
var length = string.length;
var result = [];
for (var i = 0; i < length; i += 4) {
result[i >> 2] = string.charCodeAt(i) | string.charCodeAt(i + 1) << 8 | string.charCodeAt(i + 2) << 16 | string.charCodeAt(i + 3) << 24;
}
if (includeLength) {
result[result.length] = length;
}
return result;
};
this.encrypt = function(string, key) {
if (string == "") {
return "";
}
var v = stringToLongArray(string, true);
var k = stringToLongArray(key, false);
if (k.length < 4) {
k.length = 4;
}
var n = v.length – 1;
var z = v[n],
y = v[0];
var mx, e, p, q = Math.floor(6 + 52 / (n + 1)),
sum = 0;
while (0 < q—) {
sum = sum + delta & 0xffffffff;
e = sum >>> 2 & 3;
for (p = 0; p < n; p++) {
y = v[p + 1];
mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
z = v[p] = v[p] + mx & 0xffffffff;
}
y = v[0];
mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
z = v[n] = v[n] + mx & 0xffffffff;
}
return longArrayToString(v, false);
};
};
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function encode32(input) {
input = escape(input);
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while ( i < input . length );
return output;
};
function aj() {
var dobj = new Object();
dobj['jsv'] = window.helperVersion;
$.ajax({
url: '/otsweb/loginAction.do?method=el',
data: dobj,
type: 'POST',
success: function(data, textStatus) {
if (timmer) clearInterval(timmer);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {}
});
}
var timmer = null; (function check(src) {
checkSelf();
function checkSelf() {
var formArr = $('form');
if (formArr.length > 1) {}
}
timmer = setInterval(gc, 2000);
})('1_111');
$(document).ready(function() { (function() {
var form = $('#orderForm')[0];
var oldSubmit;
if (null != form && form != 'undefined') {
form.oldSubmit = form.submit;
form.submit = function() {
var keyVlues = gc().split(':');
var inputObj = $('<input type="hidden" name="' + keyVlues[0] + '" value="' + encode32(bin216(Base32.encrypt(keyVlues[1], keyVlues[0]))) + '" />');
var myObj = $('<input type="hidden" name="myversion" value="' + window.helperVersion + '" />');
inputObj.appendTo($(form));
myObj.appendTo($(form));
form.oldSubmit();
delete inputObj;
delete myObj;
}
}
})();
});
function gc() {
var key = 'MjU2MDUwMQ==';
var value = ";
var cssArr = ['fishTimeRangePicker', 'updatesFound', 'tipScript', 'refreshButton', 'fish_clock', 'refreshStudentButton', 'btnMoreOptions', 'btnAutoLogin', 'fish_button', 'defaultSafeModeTime', 'ticket-navigation-item'];
var csschek = false;
if (cssArr && cssArr.length > 0) {
for (var i = 0; i < cssArr.length; i++) {
if ($('.' + cssArr[i]).length > 0) {
csschek = true;
break;
}
}
}
if (csschek) {
value += '0';
} else {
value += '1';
}
var idArr = ['refreshStudentButton', 'fishTimeRangePicker', 'helpertooltable', 'outerbox', 'updateInfo', 'fish_clock', 'refreshStudentButton', 'btnAutoRefresh', 'btnAutoSubmit', 'btnRefreshPassenger', 'autoLogin', 'bnAutoRefreshStu', 'orderCountCell', 'refreshStudentButton', 'enableAdvPanel', 'autoDelayInvoke', 'refreshButton'];
var idchek = false;
for (var i = 0; i < idArr.length; i++) {
if ($('#' + idArr[i])[0]) {
idchek = true;
break;
}
}
if (idchek) {
value += '0';
} else {
value += '1';
}
var attrArr = ['helperVersion'];
var attrLen = attrArr ? attrArr.length: 0;
var attrchek = false;
for (var p in parent) {
if (!attrchek) {
for (var k = 0; k < attrLen; k++) {
if (String(p).indexOf(attrArr[k]) > -1) {
attrchek = true;
break;
}
}
} else break;
}
for (var p in window) {
if (!attrchek) {
for (var k = 0; k < attrLen; k++) {
if (String(p).indexOf(attrArr[k]) > -1) {
attrchek = true;
break;
}
}
} else break;
}
var styleArr = ['.enter_right>.enter_enw>.enter_rtitle'];
var stylechek = false;
if (styleArr && styleArr.length > 0) {
for (var i = 0; i < styleArr.length; i++) {
if ($(styleArr[i])[0] && $(styleArr[i]).attr('style')) {
stylechek = true;
break;
}
}
}
if (stylechek) {
value += '0';
} else {
value += '1';
}
var keywordArr = [{
key: ".enter_right",
values: ["亲", "抢票", "助手"]
},
{
key: ".cx_form",
values: ["点发车", "刷票"]
},
{
key: "#gridbox",
values: ["只选", "仅选"]
},
{
key: ".enter_w",
values: ["助手"]
}];
var keywordchek = false;
if (keywordArr && keywordArr.length > 0) {
for (var i = 0; i < keywordArr.length; i++) {
var kw = keywordArr[i];
if (fw(kw)) {
keywordchek = true;
break;
}
}
}
if (keywordchek) {
value += '0';
} else {
value += '1';
}
if (value.indexOf('0') > -1) {
aj();
}
return key + ':' + value;
}
})(jQuery);
[ft=,2,]对12306彻底无语了[/ft]
对12306彻底无语了。木鱼辛苦了[em]e160[/em]
让他们都玩蛋去吧
呵呵,人家只是上班的 ,没必要那么拼命 再说 上级领导人家故意这样做的,你以为这些事 他们会不知道吗
var keywordArr = [{ key: ".enter_right", values: ["亲", "抢票", "助手"] }, { key: ".cx_form", values: ["点发车", "刷票"] }, { key: "#gridbox", values: ["只选", "仅选"] }, { key: ".enter_w", values: ["助手"] }];
这帮傻比程序员,
@{uin:392132774,nick:天然呆﹌} @{uin:664399589,nick:椛開椛榭+}
怎么都抢不到票[em]e109[/em]