Log on to the client on the H3C campus network by yourself (for Linux)
By Ma Dongliang (cream Loki)
One man's war (http://blog.csdn.net/MDL13412)
On Monday evening, I talked to ZL students in the lab about the disconnection of wireless networks connecting to the school using WiFi on Android phones. Because our school's online logon client only supports Windows platforms and cannot be used on other platforms, we have always been using a browser to log on. Web login on a Linux PC is still stable, but once I log on using my small tablet (Android system), it will be dropped within 10 minutes. In fact, I wanted to write a login client for my Linux PC a year ago, but I was too reluctant to analyze the Protocol. This time, I was told by ZL that I decided to analyze the login protocol, write a client for everyone.
First, let me explain my development environment:
Operating System: fedora 16 (Verne)
Kernel version: 3.3.1-3
Browser: Google Chrome 17.0.963.79
Development language: Python (3.2)
Development tools: Eclipse 3.7.1 (pydev 2.2.4.2011110216)
Network Analysis Tool: Wireshark 1.6.5
Next, analyze the logon protocol and run Wireshark with the root permission on the gnome-terminal (Note: On fedora, you must run Wireshark with the root permission to set the NIC to the hybrid mode ), as shown in:
Next, set the filter, and click "capture"-> "options" on the menu bar. The "capture options" dialog box is displayed, as shown in:
Click "capture filter" to bring up the filter selection dialog box, as shown in:
Because I want to analyze the network client login data packets, IP filtering is the best choice. The server address verified on our campus network is 192.168.252.small, the "filter string" option can be used for filtering. Click "OK" and click "start" to capture packets.
Open the browser and enter http: // 192.168.252.20.: 8080/portal/index_default.jsp. This address is the homepage for webpage logon. The captured data is not the data we want. Fill in the account and password, as shown in:
Click "publish" to view the data packet. After analysis, the key data packet I found is shown in:
We can see the following fields in line-based text data: Application/X-WWW-form-urlencoded, username = MDL _ & userpwd = v1hywvleskowmda % 3d & isquickauth = false & language = Chinese & browserfinalurl = & userip = NULL. Obviously, username is not encrypted, while userpwd is encrypted, to learn about the encryption algorithm, I modified the password several times and analyzed the ing relationship. The ing relationship is as follows:
Aaa000 qufbmdaw
000aaa mdawqufb
201700a mdawmdawqq % 3d % 3d
1000000aa mdawmdawque % 3d
1000000aaa mdawmdawqufb
000bbb mdawqkjc
1000000b mdawmdawqg % 3d % 3d
000000bb mdawmdawqki % 3d
201700bbb mdawmdawqkjc
After analysis, this encryption algorithm is encrypted every three bytes and mapped to four ASCII characters. for less than three characters, it is obvious that % 3d is used, this is base64 encryption. With the encryption algorithm, you must analyze the Cookie field COOKIE: JSESSIONID = 3d4b4fba9e201dfef973138df52b5161; hello1 = MDL _; hello2 = false; hello3 =; hello4 = \ r \ n, the content of this field is different for remembering the password and not remembering the password. After analyzing the HTTP Process, I found that the JSESSIONID of the cookie is sent from the client notify to the server, therefore, Cookie forgery is possible.
After analysis, the hello1 field is the user name, And the hello2 field is whether to remember the password. The hello3 field is an encrypted string when remembering the password, but it is blank when not remembering the password, the hello4 field is the login fee type. This field is not used by our school, so it is always blank.
After analyzing this data packet, I found that the client sent the following data packet to the server after the account and password verification are successful:
The Cookie field is consistent with the previous packet, line-based text data: language = Chinese & heartbeatcyc = 240000 & heartbeattimeoutmaxtime = 3 & userdevport = IAG_5000-vlan-02-0000 % 40 VLAN & userstatus = 99 & userip = NULL & serialno =- 19730 & basip = after analysis, is post to the local and server at the same time, the client's online page also needs to receive a parameter in this field.
Next, I found the heartbeat packet. This is the verification packet sent by the client to the server, for example:
At the beginning, I thought that as long as I get the content of this packet to the server at regular intervals and keep the TCP persistent connection, it will not be dropped, but it is not feasible after verification. Later, I tried to simulate all the behaviors of the browser, but it was not successful. Finally, the server will return the user's online information and reset the disconnection time if the account is already online and the login request is sent again, I send a login request to the server every one minute. At last, the request can be stable online.
Next, I will post the client code I wrote in Python for your reference. In order to port the code to other platforms with minimal workload, I removed the interface I made in pyqt4, or a pure terminal program is used:
This project is divided into three files in total. config. ini stores the user's account and password. nsinodelogin. py is responsible for logging on and maintaining online, and nsinodelogout. py is responsible for deprecation.
Config. ini
[Account]username:mdl_password:MYPASSWORD
Nsinodelogout. py
#-*-Coding: UTF-8-*-welcomeinfo = ''' Author: Ma Dongliang unit: ACM Program Design Association, School of Information Engineering, Inner Mongolia University of Science and Technology blog: baiq: 401074567 copyright (c) 2012 cream. all rights reserved. usage: Modify the config in the current path. INI file, enter the user name and password in the corresponding field to log on to use nsinodelogin. use nsinodelogout to log out using Py. do not close this program '''import HTTP. clientimport base64import osfrom configparser import configparserrequesteaders = {'connection': 'Keep-alive', 'cache-control': 'max-age = 0', 'user-agent ': 'mozilla/5.0 (X11; Linux i686) applewebkit/535.11 (khtml, like gecko) Chrome/17.0.963.79 Safari/80', 'content-type ': 'application/X-WWW-form-urlencoded', 'accept': 'text/html, application/XHTML + XML, application/XML; q = 0.9 ,*/*; Q = 0.8 ', 'Accept-encoding': 'gzip, deflate, sdch', 'Accept-color': 'zh-CN, ZH; q = 0.8 ', 'Accept-charset': 'gbk, UTF-8; q = 0.7, *; q = 100', 'cookier ': ''} If _ name _ = '_ main _': Try: Print (welcomeinfo) Try: configfile = configparser () configfile. read (filenames = OS. getcwd () + '/config. INI ', encoding = 'utf-8') username = configfile. get ('account', 'username') Pwd = configfile. get ('account', 'Password') failed T: Print ('user information loading error ') logoutbody = 'username = {0} & userpwd = {1} & isquickauth = false & language = Chinese & browserfinalurl = & userip = NULL 'requesteaders ['cooker'] = 'jsessionid = f447cb1c348b7d7aa6c02cba3ecbf7af; hello1 = {0}; hello2 = flase; hello3 =; hello4 = '. format (username) Pwd = base64.encodebytes (PWD. encode (encoding = 'utf _ 8', errors = 'strict ') Pwd = PWD. replace ('= '. encode (encoding = 'utf _ 8', errors = 'strict '),' % 3d '. encode (encoding = 'utf _ 8', errors = 'strict ') logoutbody = logoutbody. format (username, PWD) logoutbody = logoutbody. replace ("B '", "") logoutbody = logoutbody. replace ("\ N'", "") While true: conn = http. client. httpconnection ('2017. 168.252.20.: 8080 ') Conn. request ('post', '/portal/logout. JSP ', logoutbody, headers = requesteaders) RES = Conn. getresponse () If res. status = 200: Print ('deprecation succeeded ') else: Print ('deprecation failed') Break failed t exception as E: Print ('error... check the network connection... ')
Nsinodelogin. py
#-*-Coding: UTF-8-*-import HTTP. clientimport timeimport base64import osfrom configparser import configparserrequesteaders = {'connection': 'Keep-alive', 'cache-control': 'max-age = 0', 'user-agent ': 'mozilla/5.0 (X11; Linux i686) applewebkit/535.11 (khtml, like gecko) Chrome/17.0.963.79 Safari/80', 'content-type ': 'application/X-WWW-form-urlencoded', 'accept': 'text/html, application/XHTML + XML, application/XML; q = 0.9 ,*/*; Q = 0.8 ', 'Accept-encoding': 'gzip, deflate, sdch', 'Accept-color': 'zh-CN, ZH; q = 0.8 ', 'Accept-charset': 'gbk, UTF-8; q = 0.7, *; q = 100', 'cookier ': ''} If _ name _ = '_ main _': Try: OS. system ('python3. /nsinodelogout. PY ') Try: configfile = configparser () configfile. read (filenames = OS. getcwd () + '/config. INI ', encoding = 'utf-8') username = configfile. get ('account', 'username') Pwd = configfile. get ('account', 'Password') failed T: Print ('user information loading error ') loginbody = 'username = {0} & userpwd = {1} & isquickauth = false & language = Chinese & browserfinalurl = & userip = NULL 'onlinebody = 'language = Chinese & heartbeatcyc = 240000 & heartbeattimeoutmaxtime = 3 & userdevport = IAG_5000-vlan-02-0000 % 40 VLAN & userstatus = 99 & userip = NULL & serialno = 15500 & basip = 'requesteaders ['cooker'] = 'jsessionid = require; hello1 = {0}; hello2 = flase; hello3 =; hello4 = '. format (username) Pwd = base64.encodebytes (PWD. encode (encoding = 'utf _ 8', errors = 'strict ') Pwd = PWD. replace ('= '. encode (encoding = 'utf _ 8', errors = 'strict '),' % 3d '. encode (encoding = 'utf _ 8', errors = 'strict ') loginbody = loginbody. format (username, PWD) loginbody = loginbody. replace ("B '", "") loginbody = loginbody. replace ("\ N'", "") While true: conn = http. client. httpconnection ('2017. 168.252.20.: 8080 ') Conn. request ('post', '/portal/login. JSP ', loginbody, headers = requesteaders) RES = Conn. getresponse () If res. status = 200: Print ('verification message sent successfully') Data = res. read () If-1 = data. find (B '000000'): Print ('logon information is correct ') else: Print ('check logon information') Break else: Print ('failed to send verification information ') continue conn = http. client. httpconnection ('2017. 168.252.20.: 8080 ') Conn. request ('post', '/portal/online. JSPs ', onlinebody, headers = requesteaders) RES = Conn. getresponse () If res. status = 200: Print ('sent online message successfully') else: Print ('sent online message failed') continue time. sleep (60) failed t exception as E: Print ('error... check the network connection... ')
This program is an experimental code and does not carry out detailed error verification. However, it is enough for campus network login.