原文來自安全客,作者:Ivan
原文鏈接:https://www.anquanke.com/post/id/152823
0x01 前言
CNCERT前幾天發公告稱發現Oracle公司出品的基于JavaEE結構的中間件WebLogic產品存在一個遠程上傳漏洞,并得到了廠商的確認,危害程度評分高達9.8分。鑒于廠商已進行了安全修復,筆者對該漏洞進行了一次分析。WebLogic管理端未授權的兩個頁面存在任意上傳getshell漏洞,可直接獲取權限。兩個頁面分別為/ws_utc/begin.do,/ws_utc/config.do;漏洞的影響范圍 Oracle WebLogic Server,版本10.3.6.0,12.1.3.0,12.2.1.2,12.2.1.3;相關鏈接: http://www.oracle.com/technetwork/security-advisory/cpujul2018-4258247.html#AppendixFMW , 下文筆者從這兩個文件入手來系統調試跟蹤找出漏洞產生的原理和位置。
0x02 漏洞流程
筆者首先訪問了一下 http://IP/ws_utc/config.do 并且將默認的目錄WSTestPageWorkDir修改了為 user_projects\domains\base_domain\tmp\sd\ 如下圖

工作臺設置一個新的目錄后,weblogic會將原來目錄下的子目錄和文件一起轉移到新設定的目錄下,但舊的目錄依然保留。因為不是重點,筆者對這塊的分析就此略過。筆者從攻擊者的維度簡單的畫了一個草圖,最初攻擊者肯定需要配置工作目錄,因為默認的工作目錄在URL訪問的時候不可達,然后攻擊者考慮是從config.do頁面上傳keystore文件還是從begin.do上傳,最終都是成功上傳小馬,只是小馬的訪問格式和路徑不盡相同。如下圖

如果要從原理上徹底搞清楚weblogic漏洞產生的過程還需要看下圖,簡單的描述一下,攻擊者開始攻擊后,Weblogic在服務端做了很多的判斷,如果設定了新的工作目錄,那么程序會自動拷貝所有舊目錄下的子目錄和文件到新的設定目錄里,并且設定新的目錄作為工作目錄,如果攻擊者通過begin.do上傳的話,Weblogic在服務端會判斷有沒有upload目錄,如果不存在會自動創建,再接著在upload目錄下創建Rs_Upload_格式化后的作為目錄名,緊接著獲取到import_file_name字段名作為后續的文件名拼接的一部分;如果通過config.do上傳的話就獲取GET請求中的timestamp參數作為后續webshell的文件名中的一部分,還是看下圖吧:

0x03 begin.do頁面上傳漏洞
首先在IDE里搭建好WebLogic環境,把應用跑起來后點擊頁面右上方的文件夾按鈕,這里實現的是一個導入的功能

選擇任意文件上傳,筆者選擇上傳jsp文件

抓取數據包可以看到其實真正存在上傳漏洞的地址是
http://IP:7001/ws_utc/resources/ws/config/import?timestamp=1532403983779
因為是漏洞復現和分析,筆者一邊上傳的時候就一邊把數據包抓取下來,得到下圖的HTTP

這段沒什么可說的就是一個簡單的上傳數據流,表單字段import_file_name是關鍵值,從產品防御的角度來看檢測它們也是關鍵的特征之一。
接下來就需要在IDE里動態定位到漏洞的觸發點,因為weblogic大多數漏洞都和T3協議有關聯,根據之前分析過的weblogic漏洞定位的調試斷點是在com.bea.core.weblogic.rmi.client_4.0.0.0.jar包里,多次調試后一步步跳轉到了漏洞觸發的核心包
\user_projects\domains\base_domain\servers\AdminServer\tmp\_WL_internal\com.oracle.webservices.wls.ws-testclient-app-wls_12.1.3\cmprq0\war\WEB-INF\lib\ws-testpage-impl.jar
并且查到了對應的觸發漏洞類名的位置 : \com\oracle\webservices\testclient\ws\util\RSDataHelper.class
定位到的方法convertFormDataMultiPart,代碼如下:
public KeyValuesMap<String, String> convertFormDataMultiPart(FormDataMultiPart formPartParams, boolean isExtactAttachment) {
File pathFile = new File(TestClientRT.getUploadDir());
if (!pathFile.exists()) {
pathFile.mkdirs();
}
this.cleanObsoleteFile(pathFile);
String dirName = "RS_Upload_" + df.format(new Date());
String uploadPath = (new File(pathFile, dirName)).getAbsolutePath();
return this.convertFormDataMultiPart(formPartParams, isExtactAttachment, uploadPath);
}
代碼中檢查了當前工作目錄下是否存在upload目錄,如果沒有的話則創建,并且調用了cleanObsoleteFile方法強制遍歷了一次目錄中所有的文件,并且發現文件就刪除掉,調試過程如下圖



再創建了一個以字符串Rs_Upload_打頭的加格式化后的時間命名的目錄,并且作為上傳文件保存的目錄。
String dirName = "RS_Upload_" + df.format(new Date());
String uploadPath = (new File(pathFile, dirName)).getAbsolutePath();
接下來程序獲得了上傳的表單的form-data , 經過循環遍歷獲取了所有的表單字段和對應的value,數據做兩塊存儲,一塊保存在kvMap集合中、獲取的附件通過saveAttacheFile方法保存到磁盤中,代碼如下
String filename = (new File(storePath, fileNamePrefix + "_" + attachName)).getAbsolutePath(); kvMap.addValue(key, filename);
if (isExtactAttachment)
{
this.saveAttachedFile(filename, (InputStream)bodyPart.getValueAs(InputStream.class));
} else {
kvMap.put(key, new ArrayList());
}
下圖紅圈處是拼接后的物理路徑名

接著追蹤調試到 execute方法,位于ImportTestCaseAction.class類
\user_projects\domains\base_domain\servers\AdminServer\tmp\_WL_internal\com.oracle.webservices.wls.ws-testclient-app-wls_12.1.3\cmprq0\war\WEB-INF\lib\ws-testpage-impl.jar!\com\oracle\webservices\testclient\ws\action\ImportTestCaseAction.class
public KeyValuesMap<String, String> convertFormDataMultiPart(FormDataMultiPart formPartParams, boolean isExtactAttachment) {
File pathFile = new File(TestClientRT.getUploadDir());
if (!pathFile.exists()) {
pathFile.mkdirs();
}
this.cleanObsoleteFile(pathFile);
String dirName = "RS_Upload_" + df.format(new Date());
String uploadPath = (new File(pathFile, dirName)).getAbsolutePath();
return this.convertFormDataMultiPart(formPartParams, isExtactAttachment, uploadPath);
由于筆者導入的文件格式以及數據并非weblogic能處理的,所以程序在context.createUnmarshaller方法處拋出空指針異常的錯誤,這就導致了上傳成功后Response的狀態碼是500,這也可以作為防御產品檢測的特征之一。動態調試異常如下圖

到此begin.do頁面未授權訪問引起的任意文件上傳漏洞已經很明朗,防御的策略可以檢測表單字段
Content-Disposition: form-data; name=”import_file_name”; filename=”jsp.jsp”
加上返回的狀態碼500,并且ResponseBody 如下
導入測試錯誤com.oracle.webservices.testclient.exception.WSTestRuntimeException: javax.xml.bind.UnmarshalException – with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services – 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: An error occurred unmarshalling the document Internal Exception
0x04 config.do頁面上傳漏洞
訪問 http://IP:7001/ws_utc/config.do 頁面后點擊左側的“安全”菜單,添加一個Keystore,任意設置名字和密碼,當然文件也是任意格式上傳,這里真的很隨意。

點擊提交后,抓取觸發地址: http://IP/ws_utc/resources/setting/keystore?timestamp=1532400069848 ; 抓取的包如下

和之前的套路一樣,上傳的時候就已經打開了IDE調試功能,斷點后還是定位到 RSDataHelper.class 文件,如下圖

這次獲取的表單字段是ks_filename,值得收藏,加入特征檢測范疇內;再跟進看下關鍵的shell生成那一步

上傳后的shell位于工作臺配置的目錄下的/config/keystore/目錄中,文件名的格式相對來說簡單,采用了POST請求中URL地址上攜帶的參數timestamp的值加上下劃線拼接起來的文件名,讓筆者大跌眼鏡的是weblogic作為知名軟件提供商存在這樣低級的漏洞實在匪夷所思,再加上其一系列的反序列化繞過漏洞,只能說weblogic的產品能不用就不用,實在不行少用為妙。
0x05 防御措施
- 設置Config.do、begin.do頁面登錄授權后訪問;
- IPS等防御產品可以加入相應的特征;
- 升級到官方最新版本;
0x06 參考鏈接
https://www.secrss.com/articles/4008
http://www.oracle.com/technetwork/security-advisory/cpujul2018-4258247.html#AppendixFMW
本文經安全客授權發布,轉載請聯系安全客平臺。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/647/
暫無評論