0x01 漏洞概述

Weblogic官方在1月補丁中修復了CVE-2020-2551漏洞,該漏洞位于WLS核心組件中,允許遠程攻擊者通過iiop進行網絡請求,從而攻擊Weblogic服務器,最終遠程攻擊者可以利用該漏洞完全接管Weblogic服務器。
從通告中我們能看到漏洞發生在WLS的核心組件,所以給了我們一個思路去分析該漏洞,只需要從接受并解析iiop請求點入手進行分析即可。
0x02 漏洞分析
分析該漏洞應該從兩方面來進行:
-
客戶端:通過分析Context的生成過程以及
Context.bind()的流程來理解服務端解析的數據結構 -
服務端:通過分析解析流程最終找到漏洞觸發點
本文也將從這兩個方面進行分析。分析到最后其實會發現iiop只是觸發方式,關鍵的觸發點還是由于Weblogic應用本身的處理邏輯,也就是說本質上是個應用漏洞而非協議漏洞。
2.1 Context的生成以及bind的流程
無論利用rmi-iiop的方式去寫客戶端,還是寫服務端,都需要在編寫具體邏輯前獲取Conetext對象,也就是如下的代碼:
new InitialContext();
如果研究過CORBA通信過程的話,就能理解這一部分是獲取Naming Service的過程,對于客戶端來說是獲取其中存在的IOR引用以供后面的rpc流程使用;對于服務端來說,用于完成對象注冊。這里來跟進一下Context的生成過程,方便后續理解Weblogic的解析邏輯。

這里有個很重要的參數environment,在該參數中可以設置Context的靜態變量來指定Context的初始化參數,包括JNDI_FACTORY、PROVIDER_URL。這些初始化參數在后續的流程中有極其重要的作用。

當在environment中設置了Context.INITIAL_CONTEXT_FACTORY后會嘗試獲取該Context factory:


這里會根據設定的Context.INITIAL_CONTEXT_FACTORY,反射獲取工廠類,之后調用getInitialContext()方法。首先看一下在JDK中原生以及在Weblogic中所拓展出的工廠類到底有哪些:

這里我們簡單的看一下WLInitialContextFactory這個Weblogic拓展的工廠類:



這里跟進看一下getORBReference()方法:

這里和CORBA的寫法是一樣的:

都是初始化orb獲取Naming Service的過程,如果想要了解詳細的過程,可以研究一下上一篇講CORBA 的文章。
在獲取了Context后,接著來看一下其綁定流程,此流程在bind()函數中有所體現:

熟悉CORBA的同學肯定一眼就能看出這里完成的是生成IOR,同時設定corba協議中的數據類型與java類型交互的約定為tk_value,并設定請求的op或者叫做operation為bind_any。這里不僅僅設定了服務端對注冊請求的處理方式(bind_any的處理流程),同時設定了后面反序列化的方式(tk_value)。
2.2 Weblogic解析流程
在了解了Context的生成及bind()流程后,接著來看一下Weblogic的解析流程。Weblogic默認在7001端口接收iiop請求,所有的請求都是交由weblogic.rmi.cluster.ClusterableServerRef#invoke來處理的:

在handleRequest中的流程較為長,我只截關鍵處理點:

直接跟進var2.invoke(),具體的實現方法在weblogic.rmi.cluster.ClusterableServerRef#invoke:


這里首先會判斷請求是否為objectMethods中已經存在的類型,當不存在時將會調用delegate.invoke()來處理,由于我們在發送注冊請求時的請求類型為bind_any()并不在objectMethods中,所以會觸發delegate.invoke(),具體的實現類為weblogic.corba.cos.naming._NamingContextAnyImplBase#_invoke:

因為我們當前的請求類型為bind_any(),其所對應的var5為0,所以會進入兩個關鍵的流程:
-
WNameHelper.read() -
var2.read_any()


在WNameHelper.read()主要負責提取IOR中的信息(id、kind)用于之后注冊到orb的流程中。
而反序列化的觸發點在var2.read_any()中:

在上一節中,已經說過在bind()流程中發起注冊請求時,會構造一個Any類,并將交互類型設置為tk_value也就是this.read_TypeCode()。繼續跟進:


這里會根據TCKind來分派具體的處理流程,tk_value對應29:

接下來就是之前CORBA文章中所提到過的反序列化流程:

由CDRInputStream跳轉到JDK原生反序列化:

至此分析結束。
0x03 利用研究
根據0x02中的分析,可以梳理出攻擊需要的兩個元素:
-
構造一個
bind_any()請求 -
尋找一條gadget填充到
Any類中
攻擊效果如下:

Reference
-
https://cert.#/report/detail?id=d3f6666d6558f02a6204dd51cb749558
-
https://cert.#/warning/detail?id=8746760715a399499f8a46fb85edcda1
-
https://lucifaer.com/2020/02/20/Java%20CORBA%E7%A0%94%E7%A9%B6/
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1130/
暫無評論