溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫

發(fā)布時間:2021-12-22 20:53:36 來源:億速云 閱讀:253 作者:柒染 欄目:網(wǎng)絡(luò)管理

本篇文章為大家展示了Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

一、漏洞描述

4月17日,國家信息安全漏洞共享平臺(CNVD)公開了Weblogic反序列化遠程代碼執(zhí)行漏洞(CNVD-C-2019-48814)。由于在反序列化處理輸入信息的過程中存在缺陷,未經(jīng)授權(quán)的攻擊者可以發(fā)送精心構(gòu)造的惡意 HTTP 請求,利用該漏洞獲取服務(wù)器權(quán)限,實現(xiàn)遠程代碼執(zhí)行。目前,POC已在野外公開(見參考鏈接)。官方緊急補?。–VE-2019-2725)已于4月26日發(fā)布,請受影響主機及時修復(fù)漏洞。

受影響版本

Oracle WebLogic Server 10.*

Oracle WebLogic Server 12.1.3

影響組件:

bea_wls9_async_response.war

wsat.war 

二、漏洞分析

根據(jù)國家信息安全漏洞共享平臺(CNVD)漏洞公告,此漏洞存在于異步通訊服務(wù),可通過訪問路徑/_async/AsyncResponseService,判斷不安全組件是否開啟。wls9_async_response.war包中的類由于使用注解方法調(diào)用了Weblogic原生處理Web服務(wù)的類,因此會受該漏洞影響:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫為更好的理解漏洞成因,通過IDEA對WebLogic服務(wù)器遠程動態(tài)調(diào)試(因為需要跟進原生類中的方法,需要在IDEA中指定WebLogic安裝目錄中的JDK文件夾),在ProcessBuilder類中打下斷點,關(guān)鍵的調(diào)用棧過程如下所示:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫調(diào)用棧非常深,下面解釋一下幾個關(guān)鍵的部分。首先是繼承自HttpServlet的BaseWSServlet類,其中的service方法主要用于處理HTTP請求及其響應(yīng),通過HTTP協(xié)議發(fā)送的請求包封裝在HttpServletRequest類的實例化對象var1中:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫調(diào)用BaseWSServlet中定義的內(nèi)部類AuthorizedInvoke的run()方法完成傳入HTTP對象的權(quán)限驗證過程:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫若校驗成功,則進入到SoapProcessor類的process方法中,通過調(diào)用HttpServletRequest類實例化對象var1的getMethod()方法獲取HTTP請求類型,若為POST方法,則繼續(xù)處理請求:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫HTTP請求發(fā)送至SoapProcessor類的handlePost方法中:

private void handlePost(BaseWSServlet var1, HttpServletRequest var2, HttpServletResponse var3) throws IOException {
   
assert var1.getPort() != null;

   
WsPort var4 = var1.getPort();
   
String var5 = var4.getWsdlPort().getBinding().getBindingType();
   
HttpServerTransport var6 = new HttpServerTransport(var2, var3);
   
WsSkel var7 = (WsSkel)var4.getEndpoint();

    try
{
        Connection var8 = ConnectionFactory.instance().createServerConnection(var6
, var5);
       
var7.invoke(var8, var4);
   
} catch (ConnectionException var9) {
       
this.sendError(var3, var9, "Failed to create connection");
   
} catch (Throwable var10) {
       
this.sendError(var3, var10, "Unknown error");
   
}
}

為方便后續(xù)分析工作進行,在此先簡單介紹一下SOAP協(xié)議內(nèi)容及格式:SOAP(中文稱之為簡單對象訪問協(xié)議),用于在WEB上交換結(jié)構(gòu)化和固化的信息,是Web Service三要素之一,可以和現(xiàn)存的許多因特網(wǎng)協(xié)議和格式結(jié)合使用。下圖展示SOAP消息封裝的標準格式:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫BaseWSServlet類實例化對象var1封裝了基于HTTP協(xié)議的SOAP消息:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫調(diào)用var1對象中定義的getPort()方法解析SOAP消息中的根元素Envelope(可把 XML 文檔定義為 SOAP 消息),獲取所調(diào)用服務(wù)的端口信息:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫通過var4對象的getWsdlPort().getBinding().getBindingType()方法獲取當前SOAP協(xié)議規(guī)范版本信息:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫并將HttpServletRequest類的var2對象及HttpServletResponse類的對象var3傳入到HttpServerTransport類構(gòu)造函數(shù)中初始化實例對象var6統(tǒng)一處理后續(xù)HTTP請求及響應(yīng)。

繼續(xù)調(diào)用var4對象中g(shù)etEndpoint()方法完成對SOAP消息中根元素Envelope解析并讀取與其相關(guān)聯(lián)的xmlns:soap命名空間,其后分別完成對SOAP Header元素和Body元素解析工作:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫跟進WsSkel類中定義的invoke()方法,其中完成了ServerDispatcher類實例化過程,并調(diào)用setWsPort()方法指定服務(wù)請求地址,進入調(diào)試器查看WsPort對象var2的屬性值,發(fā)現(xiàn)底層依靠HashMap數(shù)據(jù)結(jié)構(gòu)保存請求服務(wù)的Address和URI,其中當前請求http://:7001/_async/AsyncResponseService服務(wù):

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫在調(diào)試器中查看ServerDispatcher對象var5屬性值,發(fā)現(xiàn)methodName屬性中賦值了onAsyncDelivery方法名,在調(diào)用dispatch()方法時將調(diào)用上述服務(wù)中定義的該方法:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫WorkAreaServerHandler類中的handleRequest()方法用于處理訪問請求,通過WlMessageContext對象var2獲取傳入的MessageContext,調(diào)用var2對象的getHeaders()方法獲取傳入SOAP消息的Header元素,并最終將該元素傳遞到WorkAreaHeader對象var4中,可以在調(diào)試器中清晰看到元素內(nèi)容的賦值:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫新建WorkContextMapInterceptor對象var5,在其receiveRequest()方法中讀入經(jīng)WorkContextXmlInputAdapter適配器構(gòu)造函數(shù)轉(zhuǎn)換過后的var4對象字節(jié)數(shù)組輸出流,經(jīng)內(nèi)部getMap() -> receiveRequest() -> readEntry() 方法處理后,將上述Content字段傳入至WorkContextXmlInputAdapter類的readUTF()方法中:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫readUTF()方法中調(diào)用WorkContextXmlInputAdapter類私有成員變量xmlDecoder的readObject()方法讀取字節(jié)數(shù)組,經(jīng)內(nèi)部SAXParser類鏈式調(diào)用一系列解析器的parse()方法后,最終在com.sun.beans.ObjectHandler類定義的endElement()方法中完成XML文檔元素解析過程,獲取了有效類名oracle.toplink.internal.sessions.UnitOfWorkChangeSet:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫在Security機制完成對類名權(quán)限校驗后,利用Java反射機制,通過元類定義的newInstance()方法實現(xiàn)上述類的實例化過程:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫同樣通過反射包中的Constructor類調(diào)用構(gòu)造器方法傳入字節(jié)數(shù)組,為上述實例對象賦初值:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫UnitOfWorkChangeSet對象完成初始化過程后,使用ByteArrayInputStream對象接收經(jīng)構(gòu)造函數(shù)傳入的字節(jié)數(shù)組,再將ByteArrayInputStream對象byteIn轉(zhuǎn)換為ObjectInputStream對象objectIn,并直接調(diào)用了objectIn對象的readObject()方法。由于WebLogic安裝包中默認SDK為1.6版本,在JDK版本<=JDK7u21前提下存在Java原生類反序列化漏洞,使用ysoserial工具生成惡意序列化對象(以計算器程序為例),可在調(diào)試器中查看到當前所傳入的序列化對象:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫經(jīng)readObject()方法反序列化惡意對象后通過在ProcessBuilder類的start()方法斷點處查看command屬性,發(fā)現(xiàn)成功傳入“calc”字符串:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫到此就完成了漏洞利用的全過程,下圖演示了漏洞利用效果,通過反序列化漏洞成功運行了計算器程序:

Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫

三、補丁繞過

下面來分析下本次漏洞和以前所公布的CVE-2017-3506和CVE-2017-10271之間的關(guān)系,依舊從補丁diff著手,上述兩個補丁都是在weblogic/wsee/workarea/WorkContextXmlInputAdapter.java中添加了validate方法。首先來看CVE-2017-3506補丁文件,其實現(xiàn)方法簡單來說就是在調(diào)用startElement方法解析XML的過程中,如果解析到Element字段值為Object就拋出異常:

private void validate(InputStream is) {      WebLogicSAXParserFactoryfactory = new WebLogicSAXParserFactory();      try {         SAXParser parser =factory.newSAXParser();         parser.parse(is, newDefaultHandler() {            public void startElement(String uri, StringlocalName, String qName, Attributes attributes) throws SAXException {               if(qName.equalsIgnoreCase("object")) {                  throw newIllegalStateException("Invalid context type: object");               }            }         });      } catch(ParserConfigurationException var5) {         throw newIllegalStateException("Parser Exception", var5);      } catch (SAXExceptionvar6) {         throw newIllegalStateException("Parser Exception", var6);      } catch (IOExceptionvar7) {         throw newIllegalStateException("Parser Exception", var7);      }   }

但上述這類采用黑名單的防護措施很快就被如下POC輕松繞過,因為其中不包含任何Object元素,但經(jīng)XMLDecoder解析后依舊造成了遠程代碼執(zhí)行:

<java version="1.4.0" class="java.beans.XMLDecoder">    <new class="java.lang.ProcessBuilder">        <string>calc</string><method name="start" />    </new></java>

針對如上所示一系列bypass CVE-2017-3506補丁限制的POC的產(chǎn)生,官方在同年十月份發(fā)布了CVE-2017-10271補丁文件。和上述不同點在于本次更新中官方將object、new、method關(guān)鍵字繼續(xù)加入到黑名單中,一旦解析XML元素過程中匹配到上述任意一個關(guān)鍵字就立即拋出運行時異常。但是針對void和array這兩個元素是有選擇性的拋異常,其中當解析到void元素后,還會進一步解析該元素中的屬性名,若沒有匹配上index關(guān)鍵字才會拋出異常。而針對array元素而言,在解析到該元素屬性名匹配class關(guān)鍵字的前提下,還會解析該屬性值,若沒有匹配上byte關(guān)鍵字,才會拋出運行時異常:

public void startElement(String uri, String localName, String qName, Attributesattributes) throws SAXException {            if(qName.equalsIgnoreCase("object")) {               throw newIllegalStateException("Invalid element qName:object");            } else if(qName.equalsIgnoreCase("new")) {               throw newIllegalStateException("Invalid element qName:new");            } else if(qName.equalsIgnoreCase("method")) {               throw newIllegalStateException("Invalid element qName:method");            } else {               if(qName.equalsIgnoreCase("void")) {                  for(int attClass = 0; attClass < attributes.getLength();++attClass) {                     if(!"index".equalsIgnoreCase(attributes.getQName(attClass))){                        throw newIllegalStateException("Invalid attribute for elementvoid:" + attributes.getQName(attClass));                     }                  }               }               if(qName.equalsIgnoreCase("array")) {                  String var9 =attributes.getValue("class");                  if(var9 != null &&!var9.equalsIgnoreCase("byte")) {                     throw newIllegalStateException("The value of class attribute is notvalid for array element.");                  }

本次反序列化漏洞繞過以往補丁的關(guān)鍵點在于利用了Class元素指定任意類名,因為CVE-2017-10271補丁限制了帶method屬性的void元素,所以不能調(diào)用指定的方法,而只能調(diào)用完成類實例化過程的構(gòu)造方法。在尋找利用鏈的過程中發(fā)現(xiàn)UnitOfWorkChangeSet類構(gòu)造方法中直接調(diào)用了JDK原生類中的readObject()方法,并且其構(gòu)造方法的接收參數(shù)恰好是字節(jié)數(shù)組,這就滿足了上一個補丁中array標簽的class屬性值必須為byte的要求,再借助帶index屬性的void元素,完成向字節(jié)數(shù)組中賦值惡意序列化對象的過程,最終利用JDK 7u21反序列化漏洞造成了遠程代碼執(zhí)行。通過巧妙的利用了void、array和Class這三個元素成功的打造了利用鏈,再次完美的繞過了CVE-2017-10271補丁限制,本次漏洞的發(fā)現(xiàn)進一步證明了依靠黑名單機制是一種不可靠的防護措施。

四、臨時修復(fù)建議

官方目前已發(fā)布針對此漏洞的緊急修復(fù)補丁,可以采取以下4種方式進行防護。

及時打上官方CVE-2019-2725補丁包

官方已于4月26日公布緊急補丁包,下載地址如下:https://www.oracle.com/technetwork/security-advisory/alert-cve-2019-2725-5466295.html?from=timeline

升級本地JDK版本

因為Weblogic所采用的是其安裝文件中默認1.6版本的JDK文件,屬于存在反序列化漏洞的JDK版本,因此升級到JDK7u21以上版本可以避免由于Java原生類反序列化漏洞造成的遠程代碼執(zhí)行。

配置URL訪問控制策略

部署于公網(wǎng)的WebLogic服務(wù)器,可通過ACL禁止對/_async/*及/wls-wsat/*路徑的訪問。

刪除不安全文件

刪除wls9_async_response.war與wls-wsat.war文件及相關(guān)文件夾,并重啟Weblogic服務(wù)。具體文件路徑如下:

10.3.*版本:

12.1.3版本:

注:wls9_async_response.war及wls-wsat.war屬于一級應(yīng)用包,對其進行移除或更名操作可能造成未知的后果,Oracle官方不建議對其進行此類操作。若在直接刪除此包的情況下應(yīng)用出現(xiàn)問題,將無法得到Oracle產(chǎn)品部門的技術(shù)支持。請用戶自行進行影響評估,并對此文件進行備份后,再執(zhí)行此操作。

上述內(nèi)容就是Weblogic反序列化遠程代碼執(zhí)行漏洞的分析報告怎么寫,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI