基于锐捷网络的校园网自动化登录脚本

每次手动联网太麻烦了,这次闲得无聊写了个简单的校园网自动化登录脚本

地址:https://github.com/FourzzZ233/AutoLogin

Login

代码审计

登录所使用js代码

function onclick(event) {
  this.className = 'loginButtonHKClicked_1';
  doauthen();
}

我们在debugger里搜寻下doauthen()代码,在http://10.255.253.2:8080/eportal/interface/index_files/pc/login_bch.js?version=20210512下找到

function doauthen() {
        $("#serviceShowHide").hide();
        $("#isUsernameErrorImg").hide();
        $("#isPwdErrorImg").hide();
        $("#isServiceErrorImg").hide();
        $("#isValidCodeErrorImg").hide();
        $("#serviceShowHideTop").css("background-position", "-373px 0px");
        $("#username_hk_posi").css("background-position", "-373px 0px");
        $("#pwd_hk_posi").css("background-position", "-373px 0px");
        $("#left_hk_regist_validcode").css("background-position", "-373px 0px");
    disableLoginButton();
    if (checkForm() == true) {
        // 改为使用接口认证
        var queryString = encodeURIComponent(encodeURIComponent(getQueryString()));
	 //勾选系统配置--服务配置--域名就将用户名拼接成用户名@服务名
        var username=document.getElementById("username").value;
        var domainName="";
      /*  if(document.getElementById("isNoDomainName")){
        	domainName=document.getElementById("isNoDomainName").value;
        	if(domainName=='true'){
          		var temp=document.getElementById("net_access_type");
          		if(temp){
          			username=username+"@"+temp.value;
          		}
          }
        }*/
        
        
        var tj=document.getElementById("Tj_yes");
        if (tj.style.display == "block" || tj.style.display == "") {
        	username=prefixValue+username;
        }
        var userId = encodeURIComponent(encodeURIComponent(username));
      //针对记住密码加密修改
    		var password = document.getElementById("pwd").value;
    		//alert("1 = "+password);
    		//对是否开启密码加密进行判断
        var  encrypt =  document.getElementById("passwordEncrypt").value;
        var macString = getQueryStringByName("mac");
        if(isNull(macString)){
        	macString="111111111";
        }
        if("true"==encrypt){
		    			if(password.length<150){
		    				var passwordMac = password+">"+macString;
		    				password = encryptedPassword(passwordMac);
		    			}
          }else{
	          	if(password.length>150){
	          		 encrypt = "true";//看看以后这个地方有没有什么利用点
	          	}
          }
        encrypt = encodeURIComponent(encodeURIComponent(encrypt));
        var password = encodeURIComponent(encodeURIComponent(password));
       // alert("2 = "+password);
        var service = "";
        if(document.getElementById("net_access_type")){
        		service = encodeURIComponent(encodeURIComponent(document.getElementById("net_access_type").value));
        }
        var operatorPwd="";
        var operatorUserId="";
        if(document.getElementById('isNoOperatorPasswordFrameId')){
          //运营商密码框是否显示
          var isOperatorhide=document.getElementById('isNoOperatorPasswordFrameId').style.display;
          //显示运营商密码框则提交数据---校验
          if(isOperatorhide!="none"){
          	operatorPwd = document.getElementById("operatorPwd").value;
          	if("true"==encrypt && !isNull(operatorPwd)){
          		operatorPwd =  encryptedPassword(operatorPwd);
          		operatorPwd=encodeURIComponent(encodeURIComponent(operatorPwd));
          	}else{
          		operatorPwd=encodeURIComponent(encodeURIComponent(document.getElementById("operatorPwd").value));
          	}
          }
        }
        
        if(document.getElementById('isNoOperatorUserIdFrameId')){
          //运营商用户名框是否显示
          var isOperatorUserIdhide=document.getElementById('isNoOperatorUserIdFrameId').style.display;
          //显示运营商用户名框框则提交数据---校验
          if(isOperatorUserIdhide!="none"){
          	operatorUserId=encodeURIComponent(encodeURIComponent(document.getElementById("operatorUserId").value));
          }
        }
        
        var code="";
        var isDisplayValidCode=document.getElementById('isDisplayValidCode').style.display;
        if(isDisplayValidCode!="none"){
        	code=document.getElementById("validCode").value;
        	if(code==""){
        		showerror("验证码不能为空.",5); 
        		return false;
        	}
        }
        AuthInterFace.init("./");
AuthInterFace.login(userId,password,service,queryString,operatorPwd,operatorUserId,code,encrypt,function(authResult){	//发现登录代码
        	 if(authResult.result=="success"){
           	if(authResult.message&&authResult.message!=""){
           		alert(authResult.message);
           	}
                   var c = document.getElementById("disPlayIs_check_no");
                   var a = document.getElementById("disPlayClearSave_yes");
                   var d = document.getElementById("disPlayClearTj_yes");
                   var b = document.getElementById("disPlayIs_tj_no");
                   var macStringTemp = getQueryStringByName("mac");
                   if(isNull(macStringTemp)){
                  	 macStringTemp="111111111";
                   }
                   if (a.style.display == "block" || a.style.display == "") {
                       if (document.getElementById("username")) {
                        setCookies("EPORTAL_COOKIE_USERNAME",document.getElementById("username").value)
                       }
                       setCookies("EPORTAL_COOKIE_NEWV","true");
                       if (document.getElementById("pwd")){
			                         //对密码进行rsa加密保存
			                      	var password = document.getElementById("pwd").value;
									if(password.length<150){
										var passwordMacTemp = password+">"+macStringTemp;
										var passwordEncrypt = encryptedPassword(passwordMacTemp);
									    setCookies("EPORTAL_COOKIE_PASSWORD", passwordEncrypt)
									}
                           			else{setCookies("EPORTAL_COOKIE_PASSWORD", password);}
                       }
                       if (document.getElementById("net_access_type")) {
				setCookies("EPORTAL_COOKIE_SERVER",document.getElementById("net_access_type").value);
         setCookies("EPORTAL_COOKIE_SERVER_NAME",document.getElementById("selectDisname").innerHTML);
                       }
                       if(document.getElementById("operatorPwd")){
    setCookies("EPORTAL_COOKIE_OPERATORPWD", document.getElementById("operatorPwd").value);
                     	}
                   } else {
                       if (c.style.display == "block" || c.style.display == "") {
                           setCookies("EPORTAL_COOKIE_USERNAME", "");
                           setCookies("EPORTAL_COOKIE_PASSWORD", "");
                           setCookies("EPORTAL_COOKIE_SERVER", "");
                           setCookies("EPORTAL_COOKIE_SERVER_NAME", "")
                           setCookies("EPORTAL_COOKIE_OPERATORPWD","");
                           setCookies("EPORTAL_COOKIE_NEWV","");
                       }
                   }
                   if (d.style.display == "block" || d.style.display == "") {
                       setCookies("EPORTAL_AUTO_LAND", "true")
                   } else {
                       setCookies("EPORTAL_AUTO_LAND", "")
                   }
                  
               if(successPage&&successPage!=''&&successPage=="true"){
              	 
                 var newWin;
                 var _width=document.body.clientWidth-300;
                 var _height=document.body.clientHeight-150;
                 newWin =  window.open ('success.jsp?page=min', '认证成功页面', 'height=100,width=250,top="'+_height+'",left="'+_width+'",toolbar=no,menubar=no, scrollbars=no, resizable=no,location=no, status=no'); //这句要写
              	 newWin.location.href = "success.jsp?userIndex="+authResult.userIndex+"&keepaliveInterval="+authResult.keepaliveInterval+"&page=min";
                  AuthInterFace.getOnlineUserInfo(authResult.userIndex,function(onlineUserInfo){
                  		 var userUrl = onlineUserInfo.userUrl;
                       if (userUrl && userUrl != "") {
                      	    window.location.href=userUrl;
                       }
                  });
               }else{
              	  window.location="success.jsp?userIndex="+authResult.userIndex+"&keepaliveInterval="+authResult.keepaliveInterval;
               }
        	 }else{
        		   //认证失败,清除cookie中的服务选项
        			setCookies("EPORTAL_COOKIE_SERVER", "");
            	setCookies("EPORTAL_COOKIE_SERVER_NAME", "");
        		 		var url=authResult.validCodeUrl;
	         			if(url!=null&&url!=""){
	         				$("#validImage").attr("src",url);
	         				$("#isDisplayValidCode").show();
	        				$("#isDisplayValidCodeTip").show();
	         			}
		        		var message=authResult.message;
		        		//认证失败的地方
		        		if(message.indexOf("ERR_USER_FIRSTLOGIN_NEED_CHANGE_PASSWORD")>-1){
		        			if(userId!=null&&password!=null){
		        				document.getElementById("userIdHj").value =userId;
		        				document.getElementById("passHj").value =password;
			        			document.getElementById("haiJunForm").submit();
			        			return;
		        			}
		        		}
		           	if(message.indexOf("网络协议书")>-1){
		           		errorTip=true;
		           		opensetting(); 
		           	}else if(shouldDisplayOperatorInfo(message)){
document.getElementById("isNoOperatorPasswordFrameId").style.display="block";	  		   		 document.getElementById("isNoOperatorPasswordFrameId_space").style.display="block";		  		   	document.getElementById("isNoOperatorUserIdFrameId").style.display="block";	  		   		 document.getElementById("isNoOperatorUserIdFrameId_space").style.display="block";
if(document.getElementById("selectDisname").innerHTML &&document.getElementById("selectDisname").innerHTML!="" &&document.getElementById("selectDisname").innerHTML!="请选择服务")
{
$("#operatorUserId_tip").attr("value","请输入"+document.getElementById("selectDisname").innerHTML+"对应的账号");
$("#operatorPwd_tip").attr("value","请输入"+document.getElementById("selectDisname").innerHTML+"对应的密码");
}
					 if(message.indexOf("<OperatorId>")){
					 	operatorInfo = message.split("<OperatorId>");
					    message=operatorInfo[0];
					  	if(operatorInfo.length>1){
					  		document.getElementById("operatorUserId").value =operatorInfo[1] ;
					  		$("#operatorUserId_tip").focus();
					  		   		 }
					  		   	 }
					  		   	 
			  		  showerror(message);
		           	}else{
		           	 if(message.indexOf("<OperatorId>")){
			  		   		 operatorInfo = message.split("<OperatorId>");
			  		   		 message=operatorInfo[0];
		           	 }
		           		showerror(message);
		           		if(errorTip){
		           			errorTip=false;
		           			closeSubPage();
		           		}
		           		 // 显示错误信息
		           	}
           }
        });
    }
}

发现登录提交函数AuthInterFace.login()

然后在http://10.255.253.2:8080/eportal/interface/index_files/js/AuthInterFace.js?version=20210520下找到AuthInterFace.login()

login : function(userId, password, service, queryString,operatorPwd,operatorUserId,validcode,passwordEncrypt,callback)
//这里就是登录所用函数 
{   /* 1.登录 */
    var content = "userId=" + userId + "&password=" + password + "&service=" + service + "&queryString=" + queryString + "&operatorPwd=" + operatorPwd + "&operatorUserId=" + operatorUserId + "&validcode=" + validcode + "&passwordEncrypt=" + passwordEncrypt;
	post(ePortalUrl + "login", content, callback);
}

用Burpsuite查看发包

这里贴上用Burpsuite截断的包,后续写的脚本也是未加密

Not Encrypted

import requests

burp0_url = "http://10.255.253.2:80/eportal/InterFace.do?method=login"
burp0_cookies = {"EPORTAL_COOKIE_OPERATORPWD": "", "EPORTAL_COOKIE_SERVER": "", "EPORTAL_COOKIE_SERVER_NAME": "", "EPORTAL_COOKIE_USERNAME": "20201323", "EPORTAL_COOKIE_PASSWORD": "", "EPORTAL_COOKIE_DOMAIN": "", "EPORTAL_COOKIE_SAVEPASSWORD": "true", "EPORTAL_AUTO_LAND": "", "EPORTAL_USER_GROUP": "LT", "EPORTAL_COOKIE_NEWV": "true", "JSESSIONID": "CF756A51BAE0A2DB3D1506A6CB2B1BC7"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Origin": "http://10.255.253.2", "Connection": "close", "Referer": "http://10.255.253.2/eportal/index.jsp?wlanuserip=21f4d4f05e2baafd31edcf4f96a2021b&wlanacname=88c45520b79b5aca03cb213250e1ec77&ssid=ac3d8df0f36c3e4832d8215b9f0120fd&nasip=b59320a19a1a9b2dab3c5b4be01a3c5f&snmpagentip=&mac=912fc0ccf9aad8b3421167f0693f003f&t=wireless-v2&url=02a556e49324ea0e00e1922e2ab72da9eb7a08a172b46a4d228424fe91b7ae390776287c67f279399ae7e74673f4575e&apmac=&nasid=88c45520b79b5aca03cb213250e1ec77&vid=63f084044dc3786b&port=65184f32a03e53f9&nasportid=5b9da5b08a53a54082fb64db1e0b4f769e1d92d0b83e0972278b98341ec00270"}
burp0_data = {"userId": "", "password": "", "service": '', "queryString": "wlanuserip%3D21f4d4f05e2baafd31edcf4f96a2021b%26wlanacname%3D88c45520b79b5aca03cb213250e1ec77%26ssid%3Dac3d8df0f36c3e4832d8215b9f0120fd%26nasip%3Db59320a19a1a9b2dab3c5b4be01a3c5f%26snmpagentip%3D%26mac%3D912fc0ccf9aad8b3421167f0693f003f%26t%3Dwireless-v2%26url%3D02a556e49324ea0e00e1922e2ab72da9eb7a08a172b46a4d228424fe91b7ae390776287c67f279399ae7e74673f4575e%26apmac%3D%26nasid%3D88c45520b79b5aca03cb213250e1ec77%26vid%3D63f084044dc3786b%26port%3D65184f32a03e53f9%26nasportid%3D5b9da5b08a53a54082fb64db1e0b4f769e1d92d0b83e0972278b98341ec00270", "operatorPwd": '', "operatorUserId": '', "validcode": '', "passwordEncrypt": "false"}
requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)

编写脚本

根据源码和截包分析,确认为POST方式发包

因为不同地方的服务器ip可能设置得不一样,所以设置的根据当前上网环境决定认证服务器ip

import os
import sys
import requests

def response_status(obj:object):	#提高代码可读性
    print(obj.status_code)
    print(obj.headers)
    print(obj.text)
    
current_dir = os.getcwd()
sys.path.append(current_dir)
import YourAccount
#print(YourAccount.uid) 测试导入是否成功


dcr = requests.get("http://192.168.10.1")
detect_response = dcr.text
if(detect_response[:31] != "<script>top.self.location.href="):
    print("Warning!You should check your network or you've already pass the check!")
else:
    print("Entering login_page......")
    relocation = detect_response.split('\'')[1] #获取重定向后的地址
    print(relocation)
    server_address = relocation.split('index.jsp?')[0]  #截断获取host验证地址根目录,以此作为登录页面的前半部分
    server_ip = server_address.replace('/eportal/','')  #获取hostip
    queryStrings = relocation.split('index.jsp?')[1]    #截断获取login所需参数queryString
    username = str(YourAccount.uid)   #用户名
    password = str(YourAccount.pwd)     #密码
    login_url = server_address + "InterFace.do?method=login"
    login_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Origin": server_ip, "Connection": "close", "Referer": relocation}
    login_data = {"userId" : username,"password" : password,"service" : '',"queryString" : queryStrings,"operatorPwd" : '',"operatorUserId" : '',"validcode": '', "passwordEncrypt": "false"}
    autologin_response = requests.post(url=login_url,headers = login_headers,data = login_data)
    if "userIndex" in autologin_response.text and "success" in autologin_response.text:
        response_status(autologin_response)
         #修改了判断条件
        print("Login Successfully!!!")
        success_text = autologin_response.text
        userindex = success_text.replace(':',',').replace('\"','').split(',')[1]
        with open("./file.txt",'r+') as f:  #这里用的./是因为需要在当前工作目录下
            f.truncate()
            f.write(str(server_ip) + '\n')
            f.write(str(userindex) + '\n')
        with open("./file.txt",'r+') as f:
            for i in  f.readlines():
                print(i)
            print("Welcome!Your userIndex is " + userindex)
    else:
        print("Error!!!!")
        response_status(autologin_response)

Logout

代码审计

分析退出登录

logout : function(userIndex,callback) 
{
	/* 4.下线 */
	var content = "userIndex=" + userIndex;
	post(ePortalUrl + "logout", content,callback);
}

查看退出后的返回内容

{"userIndex":"...","result":"success","message":"","forwordurl":null,"keepaliveInterval":0,"validCodeUrl":""}

用Burpsuite查看发包

POST /eportal/InterFace.do?method=logout HTTP/1.1
Host: 10.255.253.2
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 116
Origin: http://10.255.253.2
Connection: close
Referer: http://10.255.253.2/eportal/success.jsp?userIndex=
Cookie: EPORTAL_COOKIE_OPERATORPWD=; EPORTAL_COOKIE_SERVER=; EPORTAL_COOKIE_SERVER_NAME=; EPORTAL_COOKIE_USERNAME=; EPORTAL_COOKIE_PASSWORD=; EPORTAL_COOKIE_DOMAIN=; EPORTAL_COOKIE_SAVEPASSWORD=true; EPORTAL_AUTO_LAND=; EPORTAL_USER_GROUP=LT; EPORTAL_COOKIE_NEWV=true; JSESSIONID=BBEE55554E9FB8507CD533282B2898D8

userIndex=

编写脚本

import requests

with open("./file.txt",'r+') as f:
    strs = []   #   0位是ip地址,1位是userindex
    for i in f.readlines():
        strs.append(str(i).replace("\n",""))    
    server_ip = strs[0] #存储一下ip地址
    #print(strs)
    # redirect_location = requests.get(url=strs[0],allow_redirects=False)
    # print(redirect_location.status_code)
    # print(redirect_location.headers)
    # lc = requests.get(url=redirect_location.headers.get('Location'),allow_redirects=False)
    # print(lc.status_code)
    # print(lc.headers)
    while(requests.get(url=strs[0],allow_redirects=False).status_code == 302):
        strs[0] = requests.get(url=strs[0],allow_redirects=False).headers.get('Location')
        print("Redirecting to "+strs[0])
    final_url = requests.get(strs[0]).url
    print("Now we enter " + final_url)

    logout_url = server_ip + '/eportal/InterFace.do?method=logout'
    logout_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Origin": server_ip, "Connection": "close", "Referer": final_url}
    logout_data = {"userIndex":strs[1]}
    logout_response = requests.post(url=logout_url,headers=logout_headers,data=logout_data)
    if "success" in logout_response.text:
        logout_response.encoding = 'utf-8'  #解决中文乱码问题
        print(logout_response.status_code)
        print(logout_response.text)
    else:
        print("Error!!!")
        print(logout_response.content)

Attention

我在之前反复测试时出现“您当前使用的源IP与设备重定向地址中用户IP不一致,请重新认证!”,初步估计是其他用户使用DHCP的锅,然后服务器太垃圾无法及时分配,这种也没啥办法,理论解决办法是使用手动分配ip地址,但俺太菜了不会用:)

Q.E.D.


怀着一颗虔诚谦虚的心学习