WebSockets是一個能夠提供單TCP連線全雙工頻道的HTML5特性。它的持續性連接功能,使得建構B/S模式的即時應用成為可能。 Websockets常常用在那些有聊天功能的WEB應用程式上。
下面的圖片就非常貼切地闡釋了一個APT攻擊用到的websockets:
這裡必須提到的是,burpsuite可以捕捉並記錄WebSockets的訊息。而ZAP和IronWASP是我所知道的,可以重播websocket請求的軟體。
在burpsuite裡,我們無法重播websockets訊息,但我們還是可以在有限條件下,偵測WebSocket握手包是否成功。為了進行測試,我們需要分析websocket的升級請求套件:它們會透過http或https發送,因此可以重播。
以下截圖為burpsuite重播器(Repeat選項卡)的記錄,其顯示了websocket連接的有效請求和應答情況:
為了測試這個漏洞,我們需要發送另一個帶有重製後的Origin頭的請求包。如果我們回應包裡有「101 Web Socket Protocol Handshake」的標誌,這就表示WebSocket已經建立成功了。
如果連線沒有建立成功,那就意味著該應用程式不存在這個漏洞,因為它會拒絕外部的WebSocket連線。建立成功後,我們就可以開始下一步測試,看看該應用程式是否有WebSocket跨站劫持漏洞。這裡要說明一下:即使已經建立連接,也需要其如Origin的正常連接一般,確認得到服務端對WebSocket訊息的應答之後,才能證明該應用程式存在漏洞。這是因為開發者可能會同時啟用Origin偵測與連線權限認證。因此我們的實驗中也許會出下面這種情況:建立的連接可以一直保持,但擁有外部來源的Origins不會通過認證。
ZAP可以重播WebSocket訊息,但據我了解,它並不能更改Origin頭。下面介紹的方法可以給你科普下,如何透過CSWSH(WebSocket跨站劫持)來獲得更多的東西。
打開需要測試的WEB應用程式登錄其中,然後在同一瀏覽器中開一個新選項卡,訪問http://www.php .cn/(模擬的駭客網站),輸入該WebSocket的URL位址,然後點選網頁上的Connect按鈕。一旦建立連接,你就可以透過這個頁面向WebSocket的伺服器發送訊息。我們需要透過重播有效session發送過的訊息,然後查看伺服器的回應包。
如果服務端的回應與前面有效session發送的正常套件相同,那就表示該應用程式可能存在WebSocket跨站劫持漏洞。
IronWASP可以做到更多,即使是最基礎的偵測也能提供自動化腳本檢查。
以上測試Origin的方法的使用的服務端是http://www.php.cn/,如果你想要更靈活地設定Origin值,你可以使用IronWASP的客戶端功能。它允許你自訂Origin值來測試WebSocket連線。
在以下環境下可能會使用到客戶端功能:
1.應用程式允許來自開放的Origin的WebSocket連線
2.應用允許來自localhost和內網IP的Origin欄位值
這種做法是為了方便開發者和應用程式的內部測試。透過使用IronWASP的客戶端,你可以嘗試內網IP或localhost作為Origin是否能夠生效。如果可以的話,那沒準兒你可以耍一點小手段,在真實環境下利用這個漏洞。例如,如果某個應用程式允許http:/127.0.0.1:8080作為Origin字段,那我們就可以這樣做:若受害者正好有個在本地8080埠運行的WEB應用,而且其存在跨站腳本漏洞。如果滿足這些條件,駭客可以先在該WEB應用上進行跨站攻擊,然後再向目標應用服務端建立WebSocket連線:
如果你需要利用localhost或內網IP進行測試Origin頭,使用客戶端腳本進行自動化偵測會讓你的行動更加輕鬆。 IronWASP允許你使用Python或Ruby進行實作自訂腳本編寫。
下面這個腳本可以單獨偵測Origin頭裡填滿的內網IP位址,測試服務端對此是否認可:
import clr clr.AddReference("WebsocketClient.exe") from WebsocketClient import * def check_conn(origin): print "Testing origin - " + origin ws = SyncWebsockClient() ws.Connect("ws://tatgetapp.com/ws", origin, "SessionID=KSDI2923EWE9DJSDS01212") ws.Send("first message to send") msg = ws.Read() ws.Close() if msg == "message that is part of valid session": print "Connection successful!!" return True else: return False def check_nw(): for nws in ["192.168.0.0/16", "172.16.0.0/12", "10.0.0.0/8"]: for ip in Tools.NwToIp(nws): if check_conn("http://" + ip): break check_nw()
以上是詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!