近日,2015年最為被低估的,具有巨大破壞力的漏洞浮出水面。在FoxGlove Security安全團隊的@breenmachine 發布一篇博客中介紹了該漏洞在最新版的WebLogic、WebSphere、JBoss、Jenkins、OpenNMS中的應用,實現遠程代碼執行。更為嚴重的是,在漏洞被發現的9個月后依然沒有有效的java庫補丁來針對受到影響的產品進行加固。現在,讓我們探討下該漏洞的原理以及應用。
背景:
java反序列化漏洞
java反序列化漏洞是一類被廣泛應用的漏洞,絕大多數的編程語言都會提供內建方法使用戶可以將自身應用所產生的數據存入硬盤或通過網絡傳輸出去。這種將應用數據轉化為其他格式的過程稱之為序列化,而將讀取序列化數據的過程稱之為反序列化。
當應用代碼從用戶接受序列化數據并試圖反序列化改數據進行下一步處理時會產生反序列化漏洞。該漏洞在不同的語言環境下會導致多種結果,但最有危害性的,也是之后我們即將討論的是遠程代碼注入。
2.java反序列化漏洞發現歷程
在最近幾年間,不斷的有java反序列化漏洞被曝光。最近的幾次分別產生于spring框架以及Groovy還有文件上傳的java庫中,這些漏洞均得到了修復。
但在最近的研究中,安全人員發現java反序列漏洞遠遠不止上述幾處,該漏洞廣泛的存在于java庫中。
Java反序列化漏洞:
漏洞產生原因:
在java編寫的web應用與web服務器間java通常會發送大量的序列化對象例如以下場景:
HTTP請求中的參數,cookies以及Parameters。
RMI協議,被廣泛使用的RMI協議完全基于序列化
JMX 同樣用于處理序列化對象
自定義協議 用來接收與發送原始的java對象
在序列化過程中會使用ObjectOutputStream類的writeObject()方法,在接收數據后一般又會采用ObjectInputStream類的readObject()方法進行反序列化讀取數據。其代碼示例如下:
▲
結果如圖:
▲
上述代碼中的java類ObjectInputStream在執行反序列化時并不會對自身的輸入進行檢查,意味著一種可能性,即惡意攻擊者構建特定的輸入,在ObjectInputStream類反序列化之后會產生非正常結果。而根據最新的研究,利用這一方法可以實現遠程執行任意代碼。
為了進一步說明,可以針對對上述代碼進行了一點修改:
▲
結果:
▲
主要修改為自定義了一個被序列化的對象myobject,通過定義myobject實現了java序列化的接口并且定義了一種名為“readObject”的方法。通過對比上面例子的輸出,可以發現反序列化的相關數值被修改了,即執行的用戶自身的代碼。造成結果不同的關鍵在于readObject方法,java在讀取序列化對象的時候會先查找用戶自定義的readObject是否存在,如果存在則執行用戶自定義的方法。
2 漏洞觸發點尋找:
在之前的論述中可以發現利用該漏洞首先應找出readObject方法調用,在找到之后進行下一步的注入操作。一般可以通過以下方法進行查找:
(1)針對特定的java應用,對此漏洞的應用應首先尋找可以利用的“靶點”,即確定調用反序列化函數的地點。這可以通過對java應用進行源碼審計,例如找尋反序列化函數readObject調用情況。
(2)對于該應用的網絡行為進行抓包,尋找序列化數據(在包數據中,序列化數據一般會以ac ed 00 05開頭)來進行判斷。
3.漏洞利用
在發現序列化數據之后,需要產生一個用于測試的pyload。這里可以在github上下載一個工具“ysoserial”并執行下列指令:
▲
當/ tmp / pwned文件被創建時說明測試已經開始,而后續的步驟將結合實例一起分析。
漏洞利用實例:
這里以Jboss為例,Jboss利用的是HTTP協議,可以在任何端口上運行,默認安裝在8080端口中。而且Jboss與“JMXInvokerServlet”的通信過程中存在一個公開漏洞。JMX是一個java的管理協議,在Jboss中的JMXInvokerServlet可以使用HTTP協議與其進行通話。這一通信功能依賴于java的序列化類。
在默認安裝的Jboss中,JMXInvokerServlet的路徑恰好為http://localhost:8080/invoker/JMXInvokerServlet。如果用戶訪問一個web瀏覽器,實際上會返回一個原始的java對象,這中行為顯然存在一個漏洞。
這個漏洞可以很經常的通過互聯網被利用,由于jmxinvokerservlet與主要的Web應用程序在同一個端口上運行,因此它很少被防火墻所攔截。
基于以上原理可以通過以下指令收集jar文件來測試該漏洞是否可用:
由此可以以jmx作為Jboss接受外部輸入的點,可以利用java HTTP client包構建POST請求,post請求包中數據為使用ysoserial處理之后的構建代碼。