12306 logic analysis of new version ticketing and 12306 New Version Ticketing
Preface
The new version of 12306 was probably launched the day before yesterday, because I found that the program I wrote was no longer working the day before.
When I log on, an error will be reported-"illegal request". I am wondering, is it because 12306 has changed the logic?
However, after two days of research, we have developed a new version of the ticket grabbing software ~ Okay, no worries.
Next we will start with logging in to analyze the newly added dynamicJs (this name is quite appropriate, so it is called)
A glimpse of the new version
The following are the parameters for the new 12306 login.
Based on my previous version of the ticketing software, the last three parameters are newly added, and the key and value of the parameter in the red box are not fixed ~ The other two are simple and do not affect the login success or failure.
So how does this dynamically changed parameter come from? This is probably the "Pride" of version 12306-dynamicJs. Find dynamicJs from the 12306 Official Website:
In this js file, the key snippets (and subsequent gc () Functions) for generating dynamic key-value are as follows:
function() {(function() {var form = document.forms[0];var oldSubmit;if (null != form && form != 'undefined'&& form.id == 'loginForm') {form.oldSubmit = form.submit;submitForm = 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));delete inputObj;delete myObj;}} else {submitForm = function() {var keyVlues = gc().split(':');return keyVlues[0]+ ",-,"+ encode32(bin216(Base32.encrypt(keyVlues[1], keyVlues[0])))+ ":::" + 'myversion' + ",-,"+ window.helperVersion;};}})();});
The core is the submitForm function, which will be triggered when the login button is clicked (in fact, it will be triggered when the form is submitted, but only the login is concerned here)
We can see that in the above if-else judgment, the form is differentiated: divided into two categories, one is the Form with the id of loginForm (that is, the login form ), the rest are classified as another type.
The two types of processing logic are different. For loginForm, it inserts two hidden fields on the page to submit the form. For the other type, two groups of key-values are generated and joined.
However, we need a little bit of discussion here, that is, no matter whether the login is successful or not, these two hidden domains will be inserted. Let's test it, this is what happened when I failed to log on N times:
Haha ~ This is not our focus. Or how to analyze the dynamic key and value. Since we only focus on login, we can streamline the previous js Code:
if (null != form && form != 'undefined'&& form.id == 'loginForm') {form.oldSubmit = form.submit;submitForm = 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));delete inputObj;delete myObj;}}
The key of a parameter is keyValues [0], and value is the value obtained through some encryption operations using keyValue [0] And keyValue [1, this is the target parameter we are looking.
Now, we can see that the array keyValues is split through the return value of the gc () function, so let's see what gc () is:
Function gc () {var key = 'mtk0mtew'; var value = ''; var cssArr = ['selectseattype', 'ev _ light', 'ev _ light ', 'signature', 'updatesfound ', 'tidscript', 'refreshwith', 'fish _ clock', 'refreshstudentclick', 'btnmoreoptions', 'btnautologin', 'fish _ call ', '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 = ['btnmoreoptions', 'refreshstudentclick', 'hangzhou', 'helpertooltable', 'outerbox', 'updateinfo', 'fish _ clock ', 'refreshstudentclick ', 'btnautorefresh', 'btnautosubmit ', 'btnrefreshpassenger', 'autologin', 'bnautorefreshstu ', 'ordercountcell', 'refreshstudentbutto N ', 'enableadvpanel', 'autodelayinvoke', 'refreshwith', 'refreshtimesbar', 'challsecret']; 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 ;}} elsebreak ;}for (var p in window) {if (! Attrchek) {for (var k = 0; k <attrLen; k ++) {if (String (p ). indexOf (attrArr [k])>-1) {attrchek = true; break ;}} elsebreak;} var styleArr = ['. enter_right>. enter_enw>. enter_rtitle ','. objbox td ']; var stylechek = false; if (styleArr & styleArr. length> 0) {for (var I = 0; I <styleArr. length; I ++) {var tempStyle = $ (styleArr [I]); if (tempStyle [0]) {for (var k = 0; k <tempStyle. length> 0; k ++) {if (tempStyle. eq (k ). 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: [" only "," only ", "checkBox", "checkbox"]}, {key :". enter_w ", values: [" assistant "]}]; 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 ;}
You can see that the key does not need to be calculated, while the value is calculated: specifically, you can find whether there are elements of the specified class on the page, whether the specified id element exists ........ I don't know what 12306 is for. I didn't understand the true meaning of this piece anyway? However, it can be analyzed that the final result of value must be "xxxx". x indicates 0 or 1, but obviously 12306 does not want value to include '0 '. Maybe we can directly use '123' to replace value ~
Here, the login logic is analyzed. If you want to simulate the login, you can try it by yourself. Here we provide a train of thought. You can take functions such as encode32 to the local device, use the js engine provided by Java for execution ~ Then this value will come out.
More in-depth
In fact, it is not just login. Such a dynamic key-value is added to all forms submitted. The specific process is as follows:
1. First, a dynamic js file will be introduced when loading the page, through which the dynamic key value is obtained, and the logic for calculating the value is the same
2. When submitting a form, the dynamic key and value are also submitted. If this parameter is incorrect, an "invalid request" error is returned.
Having mastered this, it is not difficult to upgrade from the old version of the ticketing software to the new version ~