破解校园网密码小记

动机

闲来无聊,想找点东西玩玩。正好校园网的帐号总是不够用,往届的帐号不注销,所以刷一刷帐号,顺便熟悉一下网络相关的编程。

找资料

刷帐号和刷课的逻辑是类似的,就在网上找刷课的博客,选了一篇作为参考。

动手

看网页源码

要想刷帐号,最重要的是先找到与网站进行交互的方法。包括url、method、表单信息。幸好之前有html的基础,不然看起来也是要爆炸。

从网页源码中定位找到了要传输的表单信息,用户名 <input class="input" name="username" id="username" style="border: none; font-size: 16px; display: none;" tabindex="0" type="text" tipinfo="Username" value="">,密码 <input name="pwd" class="input" id="pwd" type="password" style="border: none; display: none;" tabindex="0" tipinfo="Password" value="">,提交按钮 <a id="loginLink" tabindex="-1" onclick="this.className='loginButtonHKClicked_1';doauthen();"> <div id="loginLink_div"></div> </a>

提交按钮这个地方不是用的form表单,而是用javascript创建的XMLHttpRequest向如武器发送请求。所以再重点看一下这个doauthen()函数,里面的具体逻辑就是获取各种参数信息,将这些信息拼起来之后发送给服务器。发送给服务器的核心逻辑如下:

1
2
AuthInterFace.init("./");
AuthInterFace.login(userId,password,service,queryString,operatorPwd,operatorUserId,code,function(authResult){//回调函数});

AuthInterFace是javascript的一个函数对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
var AuthInterFace = (function() {
var ePortalUrl = "";
function post(url, data,callback) {
var thePost = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
thePost.open("POST", url, true);
thePost.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
thePost.onreadystatechange=function() {
if (thePost.readyState == 4 && thePost.status == 200) {
if(thePost.responseText&&thePost.responseText!=""){
if(callback){
callback(eval("("+thePost.responseText+")"));
}
}
}
}
thePost.send(data);
}
return {
init:function(url){
ePortalUrl=url + "InterFace.do?method=";
},
login : function(userId, password, service, queryString,operatorPwd,operatorUserId,validcode,callback) {
/* 1.登录 */
var content = "userId=" + userId + "&password=" + password + "&service=" + service + "&queryString=" + queryString+"&operatorPwd="+operatorPwd+"&operatorUserId="+operatorUserId+"&validcode="+validcode;
post(ePortalUrl + "login", content, callback);
},
keepalive : function(userIndex,callback) {
/* 2.保活 */
var content = "userIndex=" + userIndex;
post(ePortalUrl + "keepalive", content,callback);
},
getOnlineUserInfo : function(userIndex,callback) {
/* 3.获取在线用户信息 */
var content = "userIndex=" + userIndex;
post(ePortalUrl + "getOnlineUserInfo", content,callback);
},
freshOnlineUserInfo : function(userIndex,callback) {
var content = "userIndex=" + userIndex;
post(ePortalUrl + "freshOnlineUserInfo", content,callback);
},
logout : function(userIndex,callback) {
/* 4.下线 */
var content = "userIndex=" + userIndex;
post(ePortalUrl + "logout", content,callback);
},
loginWithQrCode : function(qrCode, queryString,callback) {
/* 5.二维码认证 */
var content = "qrCode=" + qrCode + "&queryString=" + queryString;
post(ePortalUrl + "loginWithQrCode", content,callback);
},
visitorReg : function(phoneNum, authCode,validcode,callback) {
/* 6.访客注册 */
var content = "phoneNum=" + phoneNum + "&authCode=" + authCode+"&validcode="+validcode;
post(ePortalUrl + "visitorReg", content,callback);
},
pageInfo : function(queryString,callback) {
/* 7.获取页面显示信息 */
var content = "queryString=" + queryString;
post(ePortalUrl + "pageInfo", content,callback);
},
registerMac : function(mac, userIndex,callback) {
/* 8.注册MAC快速认证 */
var content = "mac=" + mac + "&userIndex=" + userIndex;
post(ePortalUrl + "registerMac", content,callback);
},
cancelMac : function(mac, userIndex,callback) {
/* 9.取消MAC快速认证 */
var content = "mac=" + mac + "&userIndex=" + userIndex;
post(ePortalUrl + "cancelMac", content,callback);
},
cancelMacWithUserNameAndMac : function(userId, mac,callback) {
/* 9.取消MAC快速认证 */
var content = "userId=" + userId + "&usermac=" + mac;
post(ePortalUrl + "cancelMacWithUserNameAndMac", content,callback);
},
/*10.使用用户名密码下线所有用户*/
logoutByUserIdAndPass:function (userId,pass,callback){
var content = "userId=" + userId + "&pass=" + pass;
post(ePortalUrl + "logoutByUserIdAndPass", content,callback);
},
/*11.切换服务*/
switchService:function (userIndex,serviceName,callback){
var content = "userIndex=" + userIndex + "&serviceName=" + serviceName;
post(ePortalUrl + "switchService", content,callback);
},
//获取服务
getServices:function(queryString,callback){
post(ePortalUrl+"getServices" + "&queryString=" + queryString,'',callback);
},
registerNetWorkProtocol:function(userId,callback){
var content = "userId=" + userId;
post(ePortalUrl+"registerNetWorkProtocol",content,callback);
},
validateUserName:function(userId,userName,callback){
var content = "userId=" + userId+"&userName="+userName;
post(ePortalUrl+"validateUserName",content,callback);
},
modifyPass:function(userId,pass,callback){
var content = "userId=" + userId+"&pass="+pass;
post(ePortalUrl+"modifyPass",content,callback);
}
};
})();

波折

  • 一开始尝试直接将网页代码下载下来,然后将对应的表单信息写成固定的,结果发现服务器不给我响应。
  • 然后就想知道为啥不给我响应,就和正常的网页请求进行对比,使用chrome浏览器的审查元素功能,里面有个“network”标签,能在每次网络请求之后将所有的请求信息记录下来。
  • 比对正常的网页和我下载的本地网页,发现了一个问题,正常网页的表头信息有一个referer和origin,而下载的本地网页中没有referer,origin值为null。在网上查到说服务器发现origin不是服务器的地址时会拒绝跨网服务。
  • 然后,直接改用java发送http请求,用的httpclient。在使用HttpPost的时候,设置referer和origin httpPost.setHeader("referer","http://210.77.16.21/eportal/index.jsp?wlanuserip=0bc386d9e643d188b011a0d00c9b5c40&wlanacname=5fcbc245a7ffdfa4&ssid=&nasip=2c0716b583c8ac3cbd7567a84cfde5a8&mac=53ba540bde596b811a6d5617a86fa028&t=wireless-v2&url=2c0328164651e2b4f13b933ddf36628bea622dedcc302b30"); httpPost.setHeader("origin","http://210.77.16.21");

总结

犹豫了这么久,终于把这玩意做出来了。其实最麻烦的地方就在审查html源码,找到url和action,然后找到所有的参数信息。其次就是对网络编程不是很熟悉,这次也是直接在网上找的demo。最后就是在真正发送请求的时候,有一个跨网服务的问题,还好比对了请求信息,找到的问题所在,不然也能卡死。

这玩意还可以做的更加高端一些,现在只是有一些固定猜测的密码,对所有的帐号进行尝试。以后可以弄一个密码字典,对密码进行暴力破解,不过比较耗时,暂时没有需求。