您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關怎么進行WebSphere遠程代碼執行漏洞CVE-2020-4450分析,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
2020年06月08日,360CERT監測到 IBM官方
發布了 WebSphere遠程代碼執行
的風險通告,該漏洞編號為 CVE-2020-4450
,漏洞等級:嚴重
,漏洞評分:9.8分
。
此漏洞由IIOP
協議上的反序列化造成,未經身份認證的攻擊者可以通過IIOP
協議遠程攻擊WebSphere Application Server
,在目標服務端執行任意代碼,獲取系統權限,進而接管服務器。
對此,360CERT建議廣大用戶及時安裝最新補丁,做好資產自查以及預防工作,以免遭受黑客攻擊。
360CERT對該漏洞的評定結果如下
評定方式 | 等級 |
---|---|
威脅等級 | 嚴重 |
影響面 | 廣泛 |
360CERT評分 | 9.8分 |
WebSphere Application Server: 9.0.0.0 to 9.0.5.4
WebSphere Application Server: 8.5.0.0 to 8.5.5.17
WebSphere Application Server: 8.0.0.0 to 8.0.0.15
WebSphere Application Server: 7.0.0.0 to 7.0.0.45
按照zdi
給出的分析,iiop
的攔截是在com.ibm.ws.Transaction.JTS.TxServerInterceptor#receive_request
,那么下斷點進行遠程調試,由于websphere
自己實現了一套iiop
,所以想要走到iiop
觸發反序列化的點還需要構造滿足條件的iiop
客戶端,這里需要走到demarshalContext
方法,前提是滿足validOtsContext
為true
,也就是需要serviceContext
不為null
。
假如我們已經構造了serviceContext
不為null
,繼續往下看,將serviceContext.context_data
傳入demarshalContext
方法。
調用createCDRInputStream
創建CDRInputStream
,實際上生成的是EncoderInputStream
,CDRInputStream
的子類,之后調用EncoderInputStream#read_any
方法。
之后的調用有些繁瑣,就不列出來了,調用棧為:
由于需要serviceContext
不為null
,才能走到demarshalContext
方法體里面,在com.ibm.rmi.iiop.Connection#setConnectionContexts
方法中,該方法如下:
setConnectionContexts
方法可以對ServiceContext
屬性進行設置,但是我們需要從iiop
生成的默認上下文中獲取存儲著的當前Connection
信息。
參考@iswin
師傅的文章,可以知道,在com.ibm.rmi.iiop.GIOPImpl
里,存在一個getConnection
方法,可以獲取當前上下文的Connection
實例對象,
不過該方法需要傳遞當前ior
參數,而GIOPImpl
的對象在orb
里,
這些都能通過反射從defaultContext
中獲取。
看一下數據流是怎么被解包的,具體在demarshalContext
方法里,也就是構造完ServeicContext
下一步要執行的。
與之對應的,marshalContext
方法里有相應的數據包生成代碼,所以只需要將關鍵代碼單獨掏出來,再把PropagationContext
對象構造一下,就能生成gadgets
對象的數據流。
構造的關鍵代碼為:
既然iiop已經通了,那么我們就根據zdi
給出的gadgets
進行構造,首先需要明確的是,反序列化的入口是org.apache.wsif.providers.ejb.WSIFPort_EJB
(因為websphere
自身類加載器的問題,導致現有的gadgets
都無法利用,所以我們只能基于新的挖掘的類來構造gadgets
)。
這里我們利用的是handle.getEJBObject
方法,handle
是一個Handle
類型,在實現了Handle
接口的類中,能夠進行利用的是com.ibm.ejs.container.EntityHandle
這個類,事實上,我們在對handle
進行賦值的時候,比較復雜,需要反射多個對象。
我們來看一下他的getEJBObject
方法。
這里有幾處需要注意的:
先來看第一處,也就是lookup
方法,這里的homeJNDIName
是我們在反序列化流程中可以控制的。于是,在能夠出網的情況下,可以指向我們的rmi
服務。
這里首先會調用registry.lookup
,獲取我們在rmi
上bind
的對象,由于jdk版本過高的原因,所以導致com.sun.jndi.ldap.object.trustURLCodebase
選項默認被設置為false
,也就是說,我們不能利用jndi去遠程服務器上利用URLClassLoader
動態加載加載類,只能實例化本地的Factory
,這里利用的方式是加載本地類,具體細節參考:Exploiting JNDI Injections in Java。
簡單來說,正常情況下,jndi
的利用會在RegistryImpl_Stub.lookup
之后返回一個ReferenceWrapper
的客戶端代理類,ReferenceWrapper
提供了三個參數,className
,factory
,factoryLocation
,如果本地加載不到className
,那么就會去factoryLocation
上加載factory
,大致流程為:
而現在不能遠程去加載factoryLocation
,那么我們尋求一個本地factory
來實例化,并利用該factory
的getObjectInstance
方法,根據zdi
提供的漏洞細節,滿足條件的factory
是org.apache.wsif.naming.WSIFServiceObjectFactory
。
前邊的調用棧是這樣的,
com.sun.jndi.rmi.registry.RegistryContext#lookupcom.sun.jndi.rmi.registry.RegistryContext#decodeObjectjavax.naming.spi.NamingManager#getObjectInstance
rmi
服務端可以在reference
對象里對factory
進行設置,當然這個factory
需要滿足一些條件,當調用WSIFServiceObjectFactory.getObjectInstance
,我們看一下這個方法。這里wsdlLoc
,serviceNS
等值都可以在rmi
端通過Reference
進行設置。
這里會對ref
進行判斷,也就是Reference
對象的第一個參數,也是可控的。我們需要走到下面的判斷里,也就是讓ref
為WSIFServiceStubRef
,原因是這樣的,需要回過來看到前面,
我們需要指定返回代理的類型是EJBHome
。這里有兩個地方需要指定接口的類型,一個是narrow
第二個參數homeClass
,一個是在Reference
指定className
,用來控制返回的代理類型。
這里的getObjectInstance
調用將從遠程URL
初始化WSIF
服務,該URL指向可由攻擊者控制的遠程XML定義,在遠程xml里,我們可以將方法進行映射,這里只說個概念,后面再仔細說。
當ref
是WSIFServiceStubRef
類型的時候,可以通過className
來指定生成stub
的接口類型,這樣就能生成實現EJHome
接口的代理,這里前面已經提到過了,具體在rmi
服務端通過Reference
進行設置。
這里會在getStub
里創建代理類。
根據提供的接口,最終返回WSIFClientProxy
代理類。
接著,在this.findFindByPrimaryKey
獲取homeClass
接口的findByPrimaryKey
方法。
之后,就會調用動態代理類的invke
方法,傳入findFindByPrimaryKey
和this.key
,也就是方法的參數。
在WSIFClientProxy.invoke
的方法里,會調用WSIFPort
實現類的createOperation
方法。
這個createOperation
方法就能將方法進行映射,這里我們可以將findFindByPrimaryKey
方法映射為本地存在的方法,比如javax.el.ELProcessor
的eval
方法,這里的映射就主要體現在之前提到的WSIF web
服務里,需要將映射內容體現在我們自定義的遠程xml文件里。主要語法可以參考:WSDL Java Extension_(https://ws.apache.org/wsif/providers/wsdl_extensions/java_extension.html)_,具體的調用就在自定義rmi服務上進行設置,之后的調用棧如下:
最終在ELProcessor#eval
方法里執行el
表達式。
利用成功的截圖如下:
在官網下載補丁_(https://www.ibm.com/support/pages/node/6220276)_進行分析,發現對反序列化入口WSIFPort_EJB
進行了修改,在readObject
方法里,將原本的handle.getEJBObject
方法給取消了,這樣,也就把這個鏈的入口給殺死了。
2020-06-04 IBM發布預警
2020-06-08 360CERT發布預警
2020-07-21 ZDI發布分析報告
2020-08-05 360CERT發布分析報告
關于怎么進行WebSphere遠程代碼執行漏洞CVE-2020-4450分析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。