大學校園網的那點事

             關於數字XX高校,我的幾點看法

正如孔子所說,“逝者如斯夫,不捨晝夜!”時間如流水落花般逝去,二十二的年齡,畢業的季節。大四下,我會好好欣賞XX高校的各式風景。

*************************************************************

好了,感慨不多發了,我們進入正題。寫這篇文章的主要目的是分析一下數字XX高校的不足之處,好讓這個系統能夠更加完美。當然,有則改之,無則加勉。

其實,在剛發這個校園卡上網的時候,見着6位數字的默認密碼,我就曾大膽的猜測過,用窮舉法不就能登錄別人的帳號嗎?對,就是一個一個試,當然不是靠我們人來手工操作,

6位數字的密碼,共100萬個,人工輸入嘗試當然是不可取的。但是寫程序呢?那又會怎麼樣呢?

************************************************************

一、暴力密碼拆解程序的實現。

 

這是登錄界面,校內網的同學就能看到,地址:http://61.137.86.87:8080/portalNat444/index.jsp

 

我們平常登錄是輸入帳號密碼,點擊登陸按鈕進行登錄,這就是說明我們給服務端發送了一個數據,服務端接收到我們的數據然後判斷帳號密碼的正確性,最後給我們正確的響應。

我們要用的是:

網頁封包抓取---->即我們要知道計算機向服務端到底發送了什麼樣的數據包,便能依瓢畫葫蘆,直接實現數據包嘗試登錄。

抓包的工具很多,如果你還在用Httpwatch的話,我可以告訴你,你沒有跟上潮流。Httpwatch固然老牌,但是貌似在64位系統下不兼容。這裏我用的是Wireshark,一款相當nice的抓包工具,當然如果你是Firefox瀏覽器的話,可以直接用自帶的debug


 

具體操作可以百度Wiresharkuser manual,我這裏不多加闡述。

 

根據Wireshark抓包,可以知道抓到的包是POST 類型的,當然在網頁的源碼裏也能找到:


 

當然,後面的便是date.resultCode0時,就登錄成功,如果你能成功控制服務器,把resultCode設置成0,則會永遠登錄成功,顯然這是不明智的。

 

迴歸正題,我們需要發送的post數據包爲:

網址:http://61.137.86.87:8080/portalNat444/AccessServices/login

方式:POST

數據內容:

accountID=010103100527%40zndx.inter   //這裏的%40 代表的是@

&password=56aad664fa33bffb42b2c0be23ebc5efce17d7f82c0d75ade387941c690063382fef34369b1d7c929945fdbd4ba28bc77db7b028d022464646165acedf2b5deb2ce1fb3d4dc074c55888e299d384af306572a368f468d88fdafdaefebfa39bf84fad0530775d37f35dc79594ba62be4fc5189544397ed97054f4fc375903b6

&brasAddress=59df7586

&userIntranetAddress=10.96.85.80

我們可以看到,一共發送給了服務器4個參數:

第一個參數accountID:(學號加上@zndx.inter

第二個參數password:顧名思義,這是密碼。不過並不是我們所期待的6位數字,這是因爲他經過了處理,加密了,加密算法爲RSA1024bit,這個算法後面會講到。

第三個參數brasAddress:我這裏是59df7586,應該是本機的物理特徵,多抓取了幾個封包,發現這個不變,就不必管它了,不影響我們工作。

第四個參數userIntranetAddress:這是本機內網IP,我們可以在cmd中輸入ipconfig/all或者ipconfig進行查看:

 

 

也可以寫一個小程序遍歷本機的ip地址。

 

這是我寫的一個小程序:

 

也可以用C++

 

程序C++源碼如下:

#include <stdio.h> 
#include <winsock2.h> 
#pragma comment(lib,"ws2_32.lib") 
 
int doit(int, char **) 
{ 
char host_name[255]; 
//獲取本地主機名稱 
if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR) { 
printf("Error %d when getting local host name.\n", WSAGetLastError()); 
return 1; 
} 
printf("Host name is: %s\n", host_name); 
 
//從主機名數據庫中得到對應的“主機” 
struct hostent *phe = gethostbyname(host_name); 
if (phe == 0) { 
printf("Yow! Bad host lookup."); 
return 1; 
} 
 
//循環得出本地機器所有IP地址 
for (int i = 0; phe->h_addr_list[i] != 0; ++i) { 
struct in_addr addr; 
memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); 
printf("IPAddress %d : %s\n" , i, inet_ntoa(addr)); 
} 
printf("如果有10.96的IP address,則說明此Ip爲本機Ipv4地址******************  \n" );
printf("如果無10.96的IP address,則說明計算機未連通校園網******************  \n" );
return 0; 
} 
 
int main(int argc, char *argv[]) 
{ 
WSAData wsaData; 
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) { 
return 255; 
} 
 
int retval = doit(argc, argv); 
 
WSACleanup(); 
 
return retval; 
}


好了,一共4個參數,我們解決了3個,頭痛的是第二個被加密的密碼是如何由6位數字轉換成256位的加密後的字符串的。

 

256位的加密字符串很容易讓人聯想到RSA1024加密,這是一種單向加密,多用於商業用途,強度取決於對大數的因式分解。具體可以到維基百科看。

這種過高的加密強度使得我望而卻步。

正要放棄,卻發現了一個致命的弱點,有一個security.js的文件又再給人一線希望。將源文件下載到本地,分析後就知道了由6位數字如何魔術般成爲了256位字符。

一共有這麼幾個文件:

 

 

 

 

我們打開security.js,可以發現,我們的猜測並沒有錯:

 

一共700行代碼,不一一貼出

***************************************************************************

無論是註解還是函數名稱,都證明了是RSA1024無疑。可笑的是,這個代碼是05年寫的,10年經過修改。並且在調試過程中,我發現了供應商是華爲,無疑。

 

既然有了源碼,我們也能發現這和我們抓包所得到的數據一致,只是密碼用了一個函數encodeURIComponent()函數進行編碼後再用security.js裏寫好的RSA加密算法進行加密。

 

搞定了POST的四個參數,用一個循環和100萬個密碼進行暴力破解,也就能實現用別人的一個已知的學號(默認密碼)進行登錄。

 

二、暴力破解的效率

百度網盤曾經有段時間是4位數字密碼,即1萬個數字,即使算最後一次才嘗試成功,也在10分鐘以內。我們就按這個概率算,當然,你可以計算時間的期望值如果你的概率論學得不錯。就算10分鐘,1000分鐘也能嘗試出一個密碼,約16個小時。是不是很nice,按期望的話,平均9小時就差不多能得到一個帳號的密碼。

當然官方不是吃素的,他當然會考慮到這個可能性。

 

三、官方限制

可能考慮到有人會嘗試窮舉所有密碼,或是因爲代碼的嚴謹性,這個文件裏的內容就是來限制大家的次數,我大概嘗試了下,1個帳號連續輸錯10次密碼後會提示錯誤信息“無法獲取”,大約停止3分鐘。如果按照這個官方設計好的方式來算,10次密碼耗時3分鐘,100萬次耗時30萬分鍾,約208天的時間,當然,就不存在窮舉來竊取他人帳號,因爲沒有人願意發大半年時間就破解一個密碼,可能還不夠交電費。那我們就放棄嗎?

Of course not!儘管它是限制了次數,我們可以用一種巧妙的方法躲過,方法很簡單:我們可以嘗試010103100101的密碼10次,一直到無法獲取,開始嘗試2號學號的10次,這樣我們電腦的效率能實現最大化,概率當然不變,還是9小時左右能拿到一個號。

我還發現,代碼裏存在一個登錄標誌,這使得多線程無法得以實現。不過不怕,每個寢室不是你一個人在戰鬥,跟他們說清情況,結果可想而知,你懂的。


四、優化

100萬次的次數太多,爲了使得嘗試次數減少,我向同學要了大概10個左右的密碼,基本可以剔除6位數字裏全相同的,5個數字相同的以及4個數字相同的密碼。

這樣的密碼可以不用嘗試:

111112222211115344445863888

用排列組合,我們可以算出,剔除了以上幾種可能後,密碼的嘗試次數將減少到746640次,這樣的話,時間又能縮短了。當然,你還可以去除一些123456765432;這樣的密碼,具體可以參考雙色球的一些軟件的算法。這裏不做贅述。

 

五、其他

除了溫柔的暴力拆解密碼以外,當然可以採取直接的入侵手段,那樣便會方便很多,當然完成後記得刪除telnet http等日誌。

 

總的來說,數字XX高校還是設計得不夠完善。

提出幾點建議如下:

1.大家不要嫌麻煩,建議改下密碼,6位數字並不安全。

2.數字XX高校應把源碼藏好,不能讓外面輕易得到,這點是很值得改善的。

3.源代碼裏的驗證碼都被註釋了起來:

 

 

圖一:jsp中的

Js中的validateCode 也全部不再使用,儘管提高了學生上網的方便,同時也使得帳號的安全性下降了。

4.其他的就是網絡攻防了,這就看管理員的水平了。

--------------------------------------------------------------------------------

聲明:本人水平有限,若有不正確之處,還望各位大俠指正。

-----------------------------------------------------------------------------------

                                                                  Ericky

                                                             20140322

附錄一:公鑰定義處

 

 

發佈了31 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章