<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    學習Sping-messaging遠程代碼執行(CVE-2018-1270)

    VSole2021-12-23 16:04:24

    01 漏洞描述

    Spring Framework、5.0.5 之前的 5.0.x 版本和 4.3.16 之前的 4.3.x 版本以及不支持的舊版本允許應用程序通過spring-messaging模塊通過簡單的內存 STOMP 代理通過 WebSocket 端點公開 STOMP 。惡意用戶(或攻擊者)可以向代理發送可能導致遠程代碼執行攻擊的消息。

    關于SockJS和STOMP

    在Spring-messaging中是通過SockJS傳輸的STOPM內容,這個遠程代碼執行漏洞也是在對STOPM解析中出現的,本質上是一個Spring表達式注入。

    SockJS

    一些瀏覽器中缺少對WebSocket的支持,因此,回退選項是必要的,而Spring框架提供了基于SockJS協議的透明的回退選項。也可以理解為一個類似于http協議,更多的是定義在傳輸層的一個協議。

    STOPM

    STOMP(Simple (or Streaming) Text Orientated Messaging Protocol)一個簡單的面向文本/流的消息協議。STOMP提供了能夠協作的報文格式,以至于STOMP客戶端可以與任何STOMP消息代理(Brokers)進行通信,從而為多語言,多平臺和Brokers集群提供簡單且普遍的消息協作。

    STOMP可用于任何可靠的雙向流網絡協議之上,如TCP和WebSocket。雖然STOMP是面向文本的協議,但消息有效負載可以是文本或二進制。

    一個STOMP客戶端是一個可以以兩種模式運行的用戶代理,可能是同時運行兩種模式。

    作為生產者,通過SEND框架將消息發送給服務器的某個服務

    作為消費者,通過SUBSCRIBE制定一個目標服務,通過MESSAGE框架,從服務器接收消息。

    COMMANDheader1:value1header2:value2
    Body^@
    

    常用的command

    CONNECT STOMP客戶端通過初始化一個數據流或者TCP鏈接發送CONNECT幀到服務端CONNECTED 如果服務端接收了鏈接意圖,它回回復一個CONNECTED幀SEND 客戶端主動發送消息到服務器SUBSRIBE 客戶端注冊給定的目的地,被訂閱的目的地收到的任何消息將通過MESSAGE Frame發送給client。ACK 控制著確認模式。UNSUBSRIBE UNSUBSCRIBE用來移除一個已經存在訂閱,一旦一個訂閱被從連接中取消,那么客戶端就再也不會收到來自這個訂閱的消息
    

    02 漏洞復現

    CVE-2018-1270漏洞成功復現需要發送三個包才能成功。

    1、CONNECT建立一個連接

    2、SUBSRIBE添加一個訂閱,將payload放入服務端緩存存儲

    3、SEND觸發payload

    環境搭建

    可以直接vulhub拉docker搭建也可以用idea拉寫好的代碼搭建gs-messaging-stomp-websocket用github搭建的時候需要注意下要把pom.xml中的spring版本改下不然拉的spring-messaging版本超過5.0.4了就修復了。

        org.springframework.boot    spring-boot-starter-parent    2.0.0.RELEASE       
    

    如果復現不成功一定看下spring-messaging版本是多少可以在idea里的lib里看看。

    03 復現方法

    1.修改頁面js文件

    在發送訂閱的時候插入payload,在頁面上點connect,然后發兩個字符send就觸發了。

    function connect() {    var header  = {"selector":"T(java.lang.Runtime).getRuntime().exec('touch /tmp/mi1k7ea')"};    var socket = new SockJS('/gs-guide-websocket');    stompClient = Stomp.over(socket);    stompClient.connect({}, function (frame) {        setConnected(true);        console.log('Connected: ' + frame);        stompClient.subscribe('/topic/greetings', function (greeting) {            showGreeting(JSON.parse(greeting.body).content);        },header);    });}
    

    2.burp抓包修改

    可以在攔截器修改也可以全部放到重放里然后需要注意websocket ID訂閱和發送是否一樣,確保是在一個session中否則可能失敗。

    ["SUBSCRIBEid:sub-0destination:/topic/greetingsselector:T(java.lang.Runtime).getRuntime().exec('open /System/Applications/Calculator.app')\u0000"]
    


    STOMP報文格式是和http很像的所以直接修改增加鍵值對就可以了,主要是selector這個字段,其他字段在這里修改后是沒影響的,只是在后臺會留下報錯的日志,正常情況下是不會留error日志的。


    3.直接用exp打就可以了

    直接看vulhub那個就能用了CVE-2018-1270_exploit.py,用的時候腳本里改下地址和需要執行的命令。

    04 漏洞分析

    首先看下補丁,主要修改了DefaultSubscriptionRegistry類中的一些描述,引入的包,EvaluationContext初始化方式和read方法的內容的改變,結合漏洞描述看最有可能的就是EvaluationContext初始化方式的變更最可能存在問題。

    EvaluationContext從最開始通過StandardEvaluationContext初始化到通過SimpleEvaluationContext初始化,然后熟悉spring表達式注入的話那么能夠知道使用SimpleEvaluationContext進行初始化是修復表達式注入常用方法之一,SimpleEvaluationContext會對執行的表達式做一些限制使其只能執行一些基礎的操作,不能調用java對象等。所以從補丁分析的起點就是在5.0.4版本的217行,此處是漏洞的觸發點。

    在向上看了幾行后發現expression是從sub的getSelectorExpression方法獲取到的,然后context是從213行通過StandardEvaluationContext初始化的,都封裝在filterSubscriptions方法中。

    目前存在兩個疑問:

    1.filterSubscriptions在什么時候會觸發,如何才能觸發漏洞。

    2.expression值是如何取到的,是如何傳入payload的,是在觸發過程中傳入的么?

    filterSubscriptions如何觸發到

    從污點追蹤來看,首先在本類上面一點185行,通過destintion獲取到了allMatches的值命名為result傳入到補丁修改的filterSubscriptions,然后在父類AbstractSubscriptionRegistry的filterSubscriptions單參數方法對message進行類型判斷和提取destination信息。直到SimpleBrokerMessageHandler類的sendMessageToSubscribers方法都是在對message的信息做提取和判斷。

    在到到達了SimpleBrokerMessageHandler類的sendMessageToSubscribers方法后再上面一層是在判斷message的類型,對STOPM協議的不同的命令做處理,從字面意義看是在send命令會進入并觸發漏洞。

    SimpleBrokerMessageHandler的handleMessageInternal方法是一個處理不同命令的工廠,這樣的話就還沒有到最外部通過SockJs獲取STOPM報文的點,但是目前到了這里暫時已經夠了能夠知道在什么情況下會觸發到漏洞,后面再去確定如何獲取到報文的。

    現在已經找到了在send命令下會執行expression表達式,但是咋沒看到expression表達式從哪里來的呢?

    expression值從哪里來

    expression值從哪里來關系到payload從哪里來,首先sub是從info中獲取到的,然后subId是從allMatches中獲取到的,allMatches是在185行的this.destinationCache.getSubscriptions方法獲取到的的。就是個套娃,拆套娃肯定是從外面開始拆的.....

    獲取allMatches

    通過getSubscriptions方法獲取到的allMatches參數值,進去之后是從this.accessCache中獲取到的,然后這個參數是在哪里賦值的呢?

    從下圖可以看到accessCache值都是在本類中進行賦值的有四個put,進去看看發現就是300行的那個put的調用鏈中初始化了一個表達式,然后表達式的值也是從message中獲取到的,再向上看發現是在SUBSCRIBE命令中進入到此處實現的中間經過了registerSubscription方法的一些判斷和處理,之后再次回到了熟悉的handleMessageInternal方法。

    這里put到cache中的只有cachedDestination和subs,subs只有sessionid和subId并沒有放入表達式。

    看到了這里初步估計表達式的值是在SUBSCRIBE命令的情況下傳入的,那又是那個參數導致的呢?

    在addSubscriptionInternal方法中有一個getFirstNativeHeader方法將header為selector的鍵值取出作為表達式存儲在sub中了。

    目前初步的判斷已經有了,在SUBSCRIBE命令下selector頭值會作為表達式存儲,之后在send命令下取出表達式值執行。但是目前還需要確定是根據什么去存儲和取出的表達式。

    獲取info

    info直接從Session中通過allmatches中的sesionID獲取到的,然后info是在addSubscriptionInternal中通過addSubscription方法放入的。

    獲取sub

    獲取就是從info中的sessionID獲取到的,然后在生成的時候就放入了表達式。

    關于為什么能通過sessionid和subid獲取到對應的表達式,就是和sockjs接收websocket相關了,應該是在這個session會話中這個處理命令的方法是一直在內存中存活的所以才能取到對應的值。

    05 如何挖掘

    黑盒

    在黑盒的時候可以根據包內容進行初步判斷,如果內容是明顯的STOMP協議格式則可能存在可以用payload嘗試下可能就存在對應版本的漏洞。

    白盒

    1.查看spring-messaging版本低于5.0.4是存在問題的。

    2.查看是否有使用可以通過配置類和配置文件找。

    06 修復方案

    官方給出的修復方案是升級版本

    Spring Framework 5.0到5.0.4升級到5.0.5版本

    Spring Framework 4.3到4.3.14升級到4.3.15版本

    官方通告里說spring-messaging有問題,而spring-messaging版本跟隨Spring Framework版本,所以重點關注spring-messaging的jar包即可

    文章參考:

    1.《WebSocket和Stomp協議》

    2.《淺析Spring Messaging之CVE-2018-1270》

    3.《spring-messaging 遠程代碼執行漏洞分析》

    4.《spring源碼分析之spring-messaging模塊詳解》

    漏洞挖掘spring框架
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    Part1前言在近幾年的HW比賽、紅隊項目中,攻擊隊在外圍打點時,越來越依賴于對Java站點的漏洞挖掘。Ja
    Java審計其實和Php審計的思路一樣,唯一不同的可能是復雜的框架和代碼。
    src漏洞挖掘淺談
    2023-02-20 11:22:13
    信息收集就說到這里,信息收集的主要目的就是擴大可利用面,10000萬個資產你可能碰到弱口令,但1個資產你肯定沒有弱口令挖掘前篇前邊已經講了信息收集,在測試前為了能高效的挖掘src,就需要有數據進行測試,這個數據就是我們常說的字典,字典怎么來,整理,收集,經驗,積累。金額,數量都是可以篡改的地方小結挖掘src漏洞最主要還是挖掘邏輯漏洞,無非就是耐心,細節,多留意數據包的可疑數據,數據包所實現的功能。
    Spring的英文翻譯為春天,可以說是給Java程序員帶來了春天,因為它極大的簡化了開發。
    用戶名:加密密碼:密碼最后一次修改日期:兩次密碼的修改時間間隔:密碼有效期:密碼修改到期到的警告天數:密碼過期之后的寬限天數:賬號失效時間:保留。查看下pid所對應的進程文件路徑,
    服務器的相關信息(真實ip,系統類型,版本,開放端口,WAF等) 網站指紋識別(包括,cms,cdn,證書等),dns記錄 whois信息,姓名,備案,郵箱,電話反查(郵箱丟社工庫,社工準備等) 子域名收集,旁站,C段等 google hacking針對化搜索,pdf文件,中間件版本,弱口令掃描等 掃描網站目錄結構,爆后臺,網站banner,測試文件,備份等敏感文件泄漏等 傳輸協議,通用漏洞,ex
    ?上整理的?試問題?全,有些 HW ?試的題,已經收集好了,提供給?家。
    拿到一個系統后,很多情況下只有一個登錄入口。如果想進一步得到較為高危的漏洞,只能去尋找權限校驗相關的漏洞,再結合后臺洞,最終得到一個較為滿意的漏洞
    最近兩個月我一直在做拒絕服務漏洞相關的時間,并收獲了Spring和Weblogic的兩個CVE但DoS漏洞終歸是雞肋洞,并沒有太大的意義,比如之前有人說我只會水垃圾洞而已,所以在以后可能打算做其他方向早上和pyn3rd師傅聊天
    Web安全常見漏洞修復建議
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类