91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

發布時間:2021-12-27 18:37:38 來源:億速云 閱讀:178 作者:柒染 欄目:大數據

本篇文章給大家分享的是有關如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

0x01 漏洞簡述

2020年09月29日, 360CERT對Apache ofbiz組件的反序列化漏洞進行了分析,該漏洞編號為 CVE-2020-9496,漏洞等級:高危,漏洞評分:8.0

Apache ofbiz 存在 反序列化漏洞攻擊者 通過 訪問未授權接口,構造特定的xmlrpc http請求,可以造成 遠程代碼執行的影響

0x02 風險等級

360CERT對該漏洞的評定結果如下

評定方式等級
威脅等級高危
影響面一般
360CERT評分8.0分

0x03 影響版本

- Apache Ofbiz:< 17.12.04

0x04 漏洞詳情

XML-RPC

XML-RPC是一種遠程過程調用(RPC)協議,它使用XML對其調用進行編碼,并使用HTTP作為傳輸機制。它是一種規范和一組實現,允許軟件運行在不同的操作系統上,運行在不同的環境中,通過Internet進行過程調用。在XML-RPC中,客戶端通過向實現XML-RPC并接收HTTP響應的服務器發送HTTP請求來執行RPC

Demo

客戶端

package org.apache.xmlrpc.demo.client;


import java.net.URL;


import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.apache.xmlrpc.client.XmlRpcSunHttpTransportFactory;


public class Client {
   public static void main(String[] args) throws Exception {
       // 創建客戶端實例
       XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
       config.setServerURL(new URL("http://127.0.0.1:8081/xmlrpc"));
       XmlRpcClient client = new XmlRpcClient();
       client.setConfig(config);
       // 設置傳輸工廠類
       client.setTransportFactory(new XmlRpcSunHttpTransportFactory(client));
       // 創建遠程方法的參數數組,通過指定遠程方法名稱進行調用
       Object[] params = new Object[]{new Integer(33), new Integer(9)};
       Integer result = (Integer) client.execute("Calculator.add", params);
       System.out.println(result);
   }
}

或者客戶端使用動態代理的方式,通過ClientFactory,需要客戶端和服務端都要有Adder的接口,具體實現類在服務端。

但要使用XML-RPC的動態代理功能,相應的服務器端的處理器類名稱必須是Client端接口類的全名(含包名,該名稱一般應該與Server端接口類全名一致),否則將會導致調用失敗。

public class Client_Proxy {
   public static void main(String[] args) throws MalformedURLException {
       XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
       config.setServerURL(new URL("http://127.0.0.1:8081/xmlrpc"));
       XmlRpcClient client = new XmlRpcClient();
       client.setConfig(config);
       ClientFactory factory = new ClientFactory(client);
       Adder adder = (Adder) factory.newInstance(Adder.class);
       int sum = adder.add(2, 4);
       System.out.println(sum);
   }
}

Adder接口

package org.apache.xmlrpc.demo.proxy;


public interface Adder {
   public int add(int pNum1, int pNum2);
}

服務端

package org.apache.xmlrpc.demo.webserver;


import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
import org.apache.xmlrpc.webserver.WebServer;


public class Server {
   private static final int port = 8081;


   public static void main(String[] args) throws Exception {
       WebServer webServer = new WebServer(port);


       XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();


       PropertyHandlerMapping phm = new PropertyHandlerMapping();
       /* Load handler definitions from a property file.
        * The property file might look like:
        *   Calculator=org.apache.xmlrpc.demo.Calculator
        *   org.apache.xmlrpc.demo.proxy.Adder=org.apache.xmlrpc.demo.proxy.AdderImpl
        */
       phm.load(Thread.currentThread().getContextClassLoader(),
               "MyHandlers.properties");


       /* You may also provide the handler classes directly,
        * like this:
        * phm.addHandler("Calculator",
        *     org.apache.xmlrpc.demo.Calculator.class);
        * phm.addHandler(org.apache.xmlrpc.demo.proxy.Adder.class.getName(),
        *     org.apache.xmlrpc.demo.proxy.AdderImpl.class);
        */


       phm.addHandler("Calculator",
                    org.apache.xmlrpc.demo.Calculator.class);


       xmlRpcServer.setHandlerMapping(phm);


       XmlRpcServerConfigImpl serverConfig =
               (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
       serverConfig.setEnabledForExtensions(true);
       serverConfig.setContentLengthOptional(false);


       webServer.start();
   }
}

服務端調用類

package org.apache.xmlrpc.demo;


public class Calculator {
   public int add(int i1, int i2) {
       return i1 + i2;
   }
   public int subtract(int i1, int i2) {
       return i1 - i2;
   }
}

在服務端還需要創建一個MyHandlers.properties

啟動服務端之后,運行客戶端。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

抓取流量。動態代理和普通的流量都是一樣的。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

客戶端向/xmlrpc發了一個POST請求,請求的內容為:

<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
   <methodName>Calculator.add</methodName>
   <params><param>
   <value>
       <i4>33</i4>
   </value>
   </param><param>
   <value>
       <i4>9</i4>
   </value>
   </param></params>
</methodCall>

每個XML-RPC請求都以XML元素<methodCall> </methodCall>開頭。該元素包含單個子元素<methodName>xxx</methodName>。元素<methodName>包含子元素<params>,該子元素可以包含一個或多個<param>元素。 param XML元素可以包含許多數據類型。

服務端響應的內容為

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
   <params><param>
   <value>
       <i4>42</i4>
   </value>
   </param></params>
</methodResponse>

初始化RequestHandler

注:`ofbiz  17.12.03`版本的`commons-beanutils`依賴版本是`1.9.3`

在第一次加載ControlServlet的時候,會調用init進行初始化,此時會通過getRequestHandler來初始化RequestHandler

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

調用getControllerConfigURL方法,

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

該方法從配置文件/WEB-INF/controller.xml中獲取定義好的請求映射的列表,這里會遍歷所有webappcontroller.xml配置文件。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

其中,定義xmlrpc的配置,沒有設置對應的auth選項,默認為false,不需要身份驗證,這也是之后修復的一個點。

<request-map uri="xmlrpc" track-serverhit="false" track-visit="false">
       <security https="false"/>
       <event type="xmlrpc"/>
       <response name="error" type="none"/>
       <response name="success" type="none"/>
   </request-map>

官方文檔給出的配置文件的tag

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

然后實例化ViewFactoryEventFactory

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

先看實例化ViewFactory,會根據配置文件里的typeview屬性中對應的值,遍歷出所需要的Viewerhandler,并且進行init初始化。然后存入map

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

webtools下的配置文件就存在9type

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

接著實例化EventFactory,同樣遍歷出typeeventEventHandler,并進行init初始化,然后存入map

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

然后把所有初始化的設置到servletContext里。

處理請求

根據公開的zdi文章,xml的執行是在webtools/control/xmlrpc,于是去/webtools/webapp/webtools/WEB-INF/web.xml中查看相關路由的處理。

<servlet-mapping>                              
   <servlet-name>ControlServlet</servlet-name>
   <url-pattern>/control/*</url-pattern>
</servlet-mapping>                            

請求/control下的資源都由ControlServlet來進行處理,是所有請求處理的核心。post請求也會由ControlServlet#doGet方法進行處理:

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

首先,調用getRequestHandler,因為已經初始化了,所以能夠直接獲取到。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

接著往下走,是處理request請求的一些東西,然后調用requestHandler.doRequest方法 根據request請求獲取當前請求的appname,這里是webtools,然后獲取pathinfo也就是xmlrpc

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

然后根據pathinfoconfig里獲取對應的配置,繼續往下走,requestMap.event也就是之前根據配置所獲取到的xmlrpc

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

typepathinvoke都不為null,于是跟進runEvent。根據typeeventFactory中獲取eventhandler

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

XmlRpcEventHandler的調用

然后調用eventHandler.invoke,這里我們的echo參數為null,于是調用execute方法。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

跟入getRequest方法。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

前幾行是在為SAX解析做準備,設置了一個handlerXmlRpcRequestParser,結構如下:

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

主要的element解析發生在XmlRpcRequestParser里。

然后調用parse函數,正式進入http xml解析的流程。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

XML解析

這里xml的解析主要采用SAX方式解析。SAX解析觸發的事件有

startDocument:開始讀取XML文檔;
startElement:讀取到了一個元素,例如<book>;
characters:讀取到了字符;
endElement:讀取到了一個結束的元素,例如</book>;
endDocument:讀取XML文檔結束。

整個scan流程主要發生在XMLDocumentFragmentScannerImpl#dispatch,之前的調用棧如下:

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

fScannerState用來標識當前該調用哪個方法來解析tag

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

剛開始解析的時候,state6

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

調用scanRootElementHook,用于掃描根元素,Resolvernull,于是進入else

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

接著在AbstractSAXParser#startElement,會調用ContentHandler.startElement,這個content是之前初始化的時候設置的,也就是XmlRpcRequestParser#startElement方法。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

XmlRpcRequestParser#startElement函數里,支持解析methodCall,methodName,params,parma,value標簽,如果不是,那么交給父類RecursiveTypeParserImpl做進一步處理。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

判斷到methodName會把inMethodName設置為true,之后,在dispatch根據state進入分支處理content,然后會調用XmlRpcRequestParser#characters,設置methodName屬性。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

下一個標簽是結束標簽</methodName>調用endElement,將inMethodName設置為false

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

value里標簽的解析

如果解析到是value里的子標簽,那么會調用startValueTag方法。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

會設置inValueTag屬性為true

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

后續,比如在解析serializable標簽的時候,就會進入default分支。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

RecursiveTypeParserImpl#startElement,剛開始typeParsernull

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

getParser方法里會根據標簽從TypeFactoryImpl里去創建具體對應的Parser,并且,想要拿到第一個判斷里的擴展Parser,還需要指定pURI

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

我們poc里的value里的xml結構為:

<struct>
   <member>
   <name>test</name>
   <value>
       <serializable>
           {base64codehere}
       </serializable>
   </value>
   </member>
</struct>

于是首先實例化的是MapParser,于是XmlRpcRequestParsertypeParserMapParser.

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

還是先調用Parser.startDocument

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

接著調用其對應的startElement方法。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

判斷struct標簽后,然后解析下一個標簽member

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

重復之前的過程,XmlRpcRequestParser解析不了,交給RecursiveTypeParserImpl處理。但是此時typeParser已經不為null,于是直接調用MapParser#startElement進行處理。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

第二個value標簽

中間其他tag省略了,注意serializable標簽之前還有一個value標簽,但是不在XmlRpcRequestParser處理,因為此時level已經很大了,直接看到MapParservalue的處理

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

調用startValueTag,重新將typeParser設置為null,但是這里設置的是MapParsertypeParser,這一步很關鍵,typeParsernull才能重新獲取parser

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

serializable標簽

在解析serializable的時候,XmlRpcRequestParsertypeParser依然是MapParser,但是在MapParser里處理不了serializable標簽,此時再交給RecursiveTypeParserImpl,這時獲取到的就是MapParsertypeParser,因為之前被設置為null,所以重新獲取Parser,而這時解析到serializable標簽,于是getParser返回為SerializableParser

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

SerializableParser繼承ByteArrayParser,沒有startElement方法,于是調用父類ByteArrayParser,設置OutputStream,且解碼輸入流。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

接著處理</serializable>Serializable#endElementsetResultresult賦值。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

接著是處理</value>,在MapParser#endElement

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

跟入endValueTag,typeParserSerializable

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

調用getResult,取出result并造成反序列化。

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

版本修復

Fixed: Apache OFBiz unsafe deserialization of XMLRPC arguments

https://github.com/apache/ofbiz-framework/commit/4bdfb54ffb6e05215dd826ca2902c3e31420287a#diff-b31806fbf9690361ad449e8f263345d8

如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析

直接在controller.xml配置xmlrpc需要授權訪問。

xmlrpc 本身是支持對序列化數據的反序列化的,而問題就出現在ofbiz沒有對xmlrpc接口的訪問做權限的控制,同時版本較低的情況下又存在能夠被反序列化所利用的依賴。

以上就是如何實現Apache Ofbiz 反序列化漏洞CVE-2020-9496分析,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

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

AI

鄂伦春自治旗| 景宁| 福海县| 沧州市| 太康县| 永寿县| 卓尼县| 浪卡子县| 舒城县| 佳木斯市| 兴义市| 漳浦县| 昭苏县| 孟州市| 乌什县| 左云县| 西华县| 邵阳县| 基隆市| 涿鹿县| 通城县| 柯坪县| 沁水县| 松江区| 鹤壁市| 江永县| 曲阜市| 四会市| 贵定县| 韶关市| 福鼎市| 杨浦区| 台湾省| 连平县| 浦东新区| 边坝县| 偃师市| 宝清县| 易门县| 宣城市| 黔江区|