首頁 > web前端 > H5教程 > 詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

黄舟
發布: 2017-03-08 15:49:44
原創
1916 人瀏覽過

WebSockets是一個能夠提供單TCP連線全雙工頻道的HTML5特性。它的持續性連接功能,使得建構B/S模式的即時應用成為可能。 Websockets常常用在那些有聊天功能的WEB應用程式上。

下面的圖片就非常貼切地闡釋了一個APT攻擊用到的websockets:

詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

科普:

##同源策略( Same origin policy):同源是指,域名,協議,連接埠相同,即瀏覽器會檢查同一瀏覽器的不同選項卡中,來源相同的腳本才能跨選項卡執行。

Origin字段:瀏覽器在發送POST請求的時候可能會加上一個Origin字段,這個Origin字段主要是用來標識最初請求是從哪裡發起的。如果瀏覽器無法確定來源在哪裡,那麼在傳送的請求裡面Origin欄位的值就為空。

IronWASP:某開源WEB測試平台,使用者可以自訂安全掃描,並且可以自己用python/ruby來定義外掛系統。相關介紹請見:http://www.php.cn/

ZAP(Zed Attack Proxy):是一款整合各種工具的滲透測試框架,可以發現在WEB應用程式中的漏洞,相關介紹見:http://www.php.cn/

WebSocket的安全評估

#最近,我們對一個擁有複雜選單選項和功能的WEB應用做了安全評估。該應用程式中大部分操作都用到了web-sockets,這意味著其大多數行為都不會記錄到http代理日誌上。

首先,我們打開主頁後,網站會載入一個有JS腳本和CSS檔案的靜態網頁。此後,整個通訊互動會轉為Websockets模式,瀏覽器和服務端之間會建立websocket連接,從而載入網站裡所有可見的HTML資源。點擊連結或提交Form表單時,瀏覽器會向服務端發送一些WebSocket訊息。伺服器處理了這些訊息後,會透過WebSocket進行回饋,而後客戶端瀏覽器會展示新的HTML內容。

這時當websocket訊息在進行互動時,通訊數量是非常巨大的。每隔一秒它們之間會有心跳探測包的交互作用。然而現有的工具達不到我的要求,我不得不為IronWASP添加了一個Websocket訊息分析裝置和一個WebSocket客戶端,這樣它才能識別Websocket從而嘗試fuzz其漏洞。你可以在這裡了解下相關知識。

在測試這個應用程式時,我發現它存在WebSocket跨站劫持(Cross-Site WebSocket Hijacking)漏洞(由christian schneider首創)。當然,我會在跟大家介紹測試方法之前,先解釋下這個漏洞的影響。在測試相關Websockets應用程式之前,我們需要先做下準備。

WebSocket跨站劫持漏洞實驗準備

大家應該明白,同源策略(SOP)不會透過瀏覽器在websockets上強制執行(同一瀏覽器下,受SSL保護的頁面,不會讓非SSL的WebSocket通過),我們測試的應用採用了http cookie作為session認證,WebSocket透過瀏覽器發送的訊息不會有Session ID或是隨機參數。

這樣一來,如果某用戶登入了帶有漏洞的WEB應用,然後在同一瀏覽器還打開了http://www.php.cn/(攻擊者的網站),http:/ /www.php.cn/可以嘗試透過該漏洞應用與應用程式的服務端建立一個WebSocket連接,然後透過瀏覽器發送一個帶有有效的認證Session ID的請求包。於是,這個由攻擊者網站建立的WebSocket連線會和應用程式本身有相同的權限。

由於整個應用程式都是以websockets為基礎運作的,劫持了WebSocket就等於劫持了使用者的session。所以這個漏洞在本質上和儲存型跨站腳本漏洞是一樣的。

如果你認為這就很糟了,那麼當你聽到某些情況下WebSocket跨站腳本,甚至可以在用戶系統上實現遠端程式碼執行的時候,會不會更驚訝呢?事請參閱IPython Notebook的案例。

在測試之前,你首先要做的就是確認該應用程式是否存在WebSockets。幸運的是,做這個非常簡單,你只需要知道以下三點:

1.WebSocket的URL連線一般是以ws://或wss://開頭的。

2.需要偵測建立連線的Origin頭,網頁可能是透過Origin欄位建立的WebSocket連結。

3.瀏覽器和服務端之間發送的訊息中,我們可以從中檢查出普通WebSocket連線的特性。

下面這張圖會為你展示:如何透過IronWASP日誌得到Origin欄位的值和WebSocket的URL值。

詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

一旦你得到這些資訊,你可以使用一些特殊方法,對跨站WebSocket劫持漏洞進行偵測。我在這裡例舉三個簡單的例子:

使用代理軟體(如Burpsuite):

這裡必須提到的是,burpsuite可以捕捉並記錄WebSockets的訊息。而ZAP和IronWASP是我所知道的,可以重播websocket請求的軟體。

在burpsuite裡,我們無法重播websockets訊息,但我們還是可以在有限條件下,偵測WebSocket握手包是否成功。為了進行測試,我們需要分析websocket的升級請求套件:它們會透過http或https發送,因此可以重播。

以下截圖為burpsuite重播器(Repeat選項卡)的記錄,其顯示了websocket連接的有效請求和應答情況:

詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

為了測試這個漏洞,我們需要發送另一個帶有重製後的Origin頭的請求包。如果我們回應包裡有「101 Web Socket Protocol Handshake」的標誌,這就表示WebSocket已經建立成功了。

如果連線沒有建立成功,那就意味著該應用程式不存在這個漏洞,因為它會拒絕外部的WebSocket連線。建立成功後,我們就可以開始下一步測試,看看該​​應用程式是否有WebSocket跨站劫持漏洞。這裡要說明一下:即使已經建立連接,也需要其如Origin的正常連接一般,確認得到服務端對WebSocket訊息的應答之後,才能證明該應用程式存在漏洞。這是因為開發者可能會同時啟用Origin偵測與連線權限認證。因此我們的實驗中也許會出下面這種情況:建立的連接可以一直保持,但擁有外部來源的Origins不會通過認證。

ZAP可以重播WebSocket訊息,但據我了解,它並不能更改Origin頭。下面介紹的方法可以給你科普下,如何透過CSWSH(WebSocket跨站劫持)來獲得更多的東西。

使用WebSocket跨站劫持的線上測試工具

打開需要測試的WEB應用程式登錄其中,然後在同一瀏覽器中開一個新選項卡,訪問http://www.php .cn/(模擬的駭客網站),輸入該WebSocket的URL位址,然後點選網頁上的Connect按鈕。一旦建立連接,你就可以透過這個頁面向WebSocket的伺服器發送訊息。我們需要透過重播有效session發送過的訊息,然後查看伺服器的回應包。

如果服務端的回應與前面有效session發送的正常套件相同,那就表示該應用程式可能存在WebSocket跨站劫持漏洞。

詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

使用IronWASP

IronWASP可以做到更多,即使是最基礎的偵測也能提供自動化腳本檢查。

使用IronWASP的WebSocket客戶端

以上測試Origin的方法的使用的服務端是http://www.php.cn/,如果你想要更靈活地設定Origin值,你可以使用IronWASP的客戶端功能。它允許你自訂Origin值來測試WebSocket連線。

詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

在以下環境下可能會使用到客戶端功能:

1.應用程式允許來自開放的Origin的WebSocket連線

2.應用允許來自localhost和內網IP的Origin欄位值

這種做法是為了方便開發者和應用程式的內部測試。透過使用IronWASP的客戶端,你可以嘗試內網IP或localhost作為Origin是否能夠生效。如果可以的話,那沒準兒你可以耍一點小手段,在真實環境下利用這個漏洞。例如,如果某個應用程式允許http:/127.0.0.1:8080作為Origin字段,那我們就可以這樣做:若受害者正好有個在本地8080埠運行的WEB應用,而且其存在跨站腳本漏洞。如果滿足這些條件,駭客可以先在該WEB應用上進行跨站攻擊,然後再向目標應用服務端建立WebSocket連線:

詳細介紹如何全面掌控Session?且看WebSocket跨站劫持的圖文程式碼詳解

使用IronWASP的WebSocket API進行自動化偵測

如果你需要利用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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板