自己動手寫H3C校園網登入用戶端(Linux平台版)

來源:互聯網
上載者:User

自己動手寫H3C校園網登入用戶端(Linux平台版)

By 馬冬亮(凝霜  Loki)

一個人的戰爭(http://blog.csdn.net/MDL13412)

        周一晚上的時候,和實驗室的ZL同學提聊到了Android手機使用Wifi串連學校的無線網掉線的問題。由於我們學校的上網登入用戶端僅支援Windows平台,在其他平台無法使用,所以,一直以來大家的解決方案就是使用瀏覽器進行登入。在Linux PC上使用網頁登入還是很穩定的,但是一旦使用我的小平板(Android系統)登入的時候,就會在10分鐘以內掉線。其實,早在一年前就想給我的Linux PC寫一個登入的用戶端,但是一直懶得去分析協議,這次經ZL同學一說,決定動手分析一下登入協議,寫一個用戶端給大家用。

        首先交代一下我的開發環境:

                作業系統:Fedora 16(Verne)

                核心版本:3.3.1-3

                瀏覽器:Google Chrome 17.0.963.79

                開發語言:Python(3.2)

                開發工具:Eclipse 3.7.1 (PyDev 2.2.4.2011110216)

                網路分析工具:WireShark 1.6.5

        下面開始分析登入協議,在gnome-terminal終端下使用root許可權運行wireshark(注意:在Fedora上,必須要用root許可權去運行wireshark才能設定網卡到混雜模式),如所示:

        接下來設定過濾器,點擊功能表列上的“Capture”->“Options”,彈出如所示的"Capture Options"對話方塊:

        單擊“Capture Filter”按鈕,彈出過濾器選擇對話方塊,如所示:

        由於我是要分析網路用戶端登入的資料包,所以用IP進行過濾是最佳選擇,我們校園網驗證的伺服器位址為192.168.252.251,將其填入的"Filter string"選項中就可以進行過濾了。然後點擊“確定”,在單擊“Start”開始抓包。

        開啟瀏覽器,輸入http://192.168.252.251:8080/portal/index_default.jsp,這個地址是我們進行網頁登入的首頁。此時抓到的資料並不是我們想要的資料,填入帳號和密碼,如所示:

        點擊“上線”,開始查看資料包,經過分析,我找到的關鍵資料包如所示:

        我們在Line-based text data: application/x-www-form-urlencoded這項中看到了如下欄位,userName=mdl_&userPwd=V1hYWVlESkowMDA%3D&isQuickAuth=false&language=Chinese&browserFinalUrl=&userip=null,很明顯userName沒有進行加密,而userPwd被加密了,為了得知密碼編譯演算法,我修改了幾次密碼,並對其映射關係進行了分析,映射關係如下:

        AAA000                  QUFBMDAw
        000AAA                  MDAwQUFB
        000000A                MDAwMDAwQQ%3D%3D
        000000AA              MDAwMDAwQUE%3D
        000000AAA            MDAwMDAwQUFB
        000BBB                  MDAwQkJC
        000000B                MDAwMDAwQg%3D%3D
        000000BB              MDAwMDAwQkI%3D
        000000BBB           MDAwMDAwQkJC

        經過分析,這個密碼編譯演算法是每3個位元組加密一次,並且將其映射為4位ASCII字元,對於不足三位的用%3D填充,很明顯了,這個是Base64加密。有了密碼編譯演算法,還要分析Cookie欄位Cookie: JSESSIONID=3D4B4FBA9E201DFEF973138DF52B5161; hello1=mdl_; hello2=false; hello3=; hello4=\r\n,對於記住密碼和不記住密碼,這個欄位的內容是不同的,經過分析HTTP的流程,我發現Cookie的JSESSIONID是用戶端Notify給伺服器的,那麼就給我們偽造Cookie提供了可能。

        經過分析,hello1欄位是使用者名稱,hello2欄位是是否記住密碼,hello3欄位在記住密碼的時候是一段經過加密的字串,不記住密碼的時候為空白,hello4欄位是登入的資費類型,我們學校沒有使用到這個欄位,所以始終為空白。

        分析完這個資料包,我發現,帳號和密碼驗證成功後用戶端又向伺服器發送了如下的資料包:

        其中Cookie欄位和上一個資料包一致,Line-based text data: application/x-www-form-urlencoded中language=Chinese&heartbeatCyc=240000&heartBeatTimeoutMaxTime=3&userDevPort=IAG_5000-vlan-02-0000%40vlan&userStatus=99&userip=null&serialNo=-19730&basip=這段後來經過分析,是同時post給本地和伺服器的,用戶端的線上頁面也要接收一份此欄位中的參數。

        接下來,我找到了心跳檢測的資料包,這個是用戶端主動發送給伺服器的驗證封裝,如:

           開始的時候我認為只要每隔一段時間向伺服器GET這個資料包的內容,並且保持TCP長串連就可以不掉線了,但是經過驗證,這是不可行的。後來又嘗試類比瀏覽器的所有行為,但是也沒有成功。最後,想到在一台機器上如果帳號已經線上,再次發送的登入請求,伺服器會返回使用者已經線上資訊,並重新設定掉線時間,於是突破點找到了,我每隔1分鐘,向伺服器發送一次登入請求,終於,可以保證穩定線上了。

        下面將我用Python寫的用戶端代碼貼出來,給大家做一個參考,為了能最小負擔的移植到其他平台,我將最初的PyQt4做的介面去掉了,還是使用了純終端的程式:

        這個項目總共分為3個檔案,config.ini儲存使用者的賬戶和密碼,NsINodeLogin.py負責登入並維持線上,NsINodeLogout.py負責下線。

config.ini

[Account]username:mdl_password:MYPASSWORD

NsINodeLogout.py

# -*- coding: utf-8 -*-welcomeInfo = '''作者:馬冬亮單位:內蒙古科技大學資訊工程學院ACM程式設計協會部落格:http://blog.csdn.net/MDL13412郵箱:mdl2009@vip.qq.comQ Q:401074567著作權 (C) 2012 凝霜.保留所有權利.使用方法:修改當前路徑下的config.ini檔案,將使用者名稱和密碼填寫至相應欄位登入使用NsINodeLogin.py登出使用NsINodeLogout.py線上時請不要關閉本程式'''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/535.11',    '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-Language':'zh-CN,zh;q=0.8',    'Accept-Charset':'GBK,utf-8;q=0.7,*;q=0.3',    'Cookie':''}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')        except:            print('載入使用者資訊錯誤')        logoutBody = 'userName={0}&userPwd={1}&isQuickAuth=false&language=Chinese&browserFinalUrl=&userip=null'        requesteaders['Cookie'] = '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('192.168.252.251:8080')            conn.request('POST', '/portal/logout.jsp', logoutBody, headers=requesteaders)            res = conn.getresponse()            if res.status == 200:                print('下線成功')            else:                print('下線失敗')                break    except Exception as e:        print('出錯啦...請檢查網路連接...')

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/535.11',    '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-Language':'zh-CN,zh;q=0.8',    'Accept-Charset':'GBK,utf-8;q=0.7,*;q=0.3',    'Cookie':''}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')        except:            print('載入使用者資訊錯誤')        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%40vlan&userStatus=99&userip=null&serialNo=15500&basip='        requesteaders['Cookie'] = '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'))        loginBody = loginBody.format(username, pwd)        loginBody = loginBody.replace("b'", "")        loginBody = loginBody.replace("\\n'", "")                while True:            conn = http.client.HTTPConnection('192.168.252.251:8080')            conn.request('POST', '/portal/login.jsp', loginBody, headers=requesteaders)            res = conn.getresponse()            if res.status == 200:                print('發送驗證資訊成功')                data = res.read()                if -1 == data.find(b'3032'):                    print('登入資訊正確')                else:                    print('請檢查登入資訊')                    break            else:                print('發送驗證資訊失敗')                continue                        conn = http.client.HTTPConnection('192.168.252.251:8080')            conn.request('POST', '/portal/online.jsp', onlineBody, headers=requesteaders)            res = conn.getresponse()                        if res.status == 200:                print('發送線上資訊成功')            else:                print('發送線上資訊失敗')                continue            time.sleep(60)    except Exception as e:        print('出錯啦...請檢查網路連接...')

        這個程式因為屬於實驗性的代碼,沒有進行詳細的錯誤校正,不過對於校園網的登入來說,已經足夠用了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.