天天看點

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

Oracle七月釋出的安全更新中,包含了一個Weblogic的反序列化RCE漏洞,編号CVE-2020-14645,CVS評分9.8。

該漏洞是針對于CVE-2020-2883的更新檔繞過,CVE-2020-2883更新檔将<code>MvelExtractor</code>和<code>ReflectionExtractor</code>列入黑名單,是以需要另外尋找一個存在<code>extract</code>且方法記憶體在惡意操作的類即可繞過更新檔。

這裡找到的是 Weblogic 12.2.1.4.0 Coherence 元件特有的類 <code>com.tangosol.util.extractor.UniversalExtractor</code>,是以隻能影響 Weblogic 12.2.1.4.x。

Oracle WebLogic Server 12.2.1.4.0

這裡使用JNDI-Injection-Exploit工具開啟一個ldap服務端

https://github.com/welk1n/JNDI-Injection-Exploit
Weblogic漏洞分析之JNDI注入-CVE-2020-14645

這裡使用了Y4er師傅的poc,生成poc檔案,使用t3協定發送

彈出電腦:

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

在<code>UniversalExtractor#extract</code>中,利用了<code>invoke</code>調用 <code>JdbcRowSetImpl#getDatabaseMetaData</code>方法導緻 JDNI 遠端動态類加載。<code>UniversalExtractor</code> 是 Weblogic 12.2.1.4.0 版本中獨有的。

gadget鍊:

下面就分别解析PriorityQueue、ExtractorComparator、UniversalExtractor、JdbcRowSetImpl這四個類是怎麼進行串聯産生調用關系的

在<code>JdbcRowSetImpl</code>中,調用其<code>getDatabaseMetaData</code>方法,會進行<code>lookup</code>的操作

Weblogic漏洞分析之JNDI注入-CVE-2020-14645
Weblogic漏洞分析之JNDI注入-CVE-2020-14645

可以看到,如果<code>this.getDataSourceName()</code>參數可控,則會産生JNDI注入

使用此類的目的是,此類的<code>extract</code>方法,可以調用到<code>JdbcRowSetImpl</code>的<code>getDatabaseMetaData</code>方法

先來看<code>UniversalExtractor</code>的構造函數,在payload中傳入了三個參數sName、aoParam、nTarget做了哪些操作

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

如果第一個if判斷為true的話,則會抛出異常。是以傳入的aoParam值為null,會跳轉到else中

跳轉到else中,分别給m_sName、m_aoParam、m_nTarget指派,接着調用了this.init()

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

跟進this.init()

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

148行調用了<code>getCanonicalName</code>方法,把傳回值傳給了<code>sCName</code>,跟進<code>getCanonicalName</code>

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

86行的<code>Lambdas.getValueExtractorCanonicalName(this)</code>是判斷this是否為<code>AbstractRemotableLambda</code>類型,此處就不跟入了,它的傳回值是null。

是以進入了88行的if語句中,<code>CanonicalNames.computeValueExtractorCanonicalName(this.m_sName, this.m_aoParam);</code>

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

跟進<code>computeValueExtractorCanonicalName</code>方法

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

這裡三個框分别解釋下

如果aoParam 不為 null 且數組長度大于0就會傳回 null ,此處aoParam是我們傳入的null,不滿足條件,進入else

如果方法名 sName 不以 () 結尾,則直接傳回方法名,我們sName的值是getDatabaseMetaData(),不滿足條件,進入else

如果方法名以 VALUE_EXTRACTOR_BEAN_ACCESSOR_PREFIXES 數組中的字首開頭得話,會截取掉并傳回,檢視到數組中的元素有get、is,是以截取掉了getDatabaseMetaData()前面的get,最終傳回了databaseMetaData

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

最終傳回的databaseMetaData會指派給<code>init</code>方法中的<code>sCName</code>

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

接下來一行把this.m_fMethod指派為了false

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

到這裡<code>UniversalExtractor</code>的構造函數就已經執行完了。接下來看下<code>UniversalExtractor</code>的<code>extract</code>方法

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

在<code>extract</code>方法中,傳入了<code>oTarget</code>,調用了<code>extractComplex</code>方法,跟進<code>extractComplex</code>方法

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

在<code>extractComplex</code>方法中有使用到反射調用<code>oTarget</code>的任意方法<code>method.invoke(oTarget, aoParam)</code>,而這裡有三個參數分别是method、oTarget、aoParam,需要對這三個參數可控才可以調用到<code>JdbcRowSetImpl</code>的<code>getDatabaseMetaData</code>方法。

現在來拆解<code>extract</code>方法,來了解這個<code>extract</code>方法是怎麼一步步調用到最後的invoke的。

第一個if語句判斷oTarget的值是不是等于null

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

進而走進else中,第二個if語句判斷<code>targetPrev</code>的值如果為null,則走進else中,顯然在69行,<code>targetPrev</code>被賦予了一個預設值null

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

接着在else中就是調用了<code>this.extractComplex(oTarget)</code>

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

跟進<code>extractComplex</code>

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

開頭幾行分别是對一些變量進行指派

這裡就解釋下fProperty為什麼是true,可以在<code>isPropertyExtractor</code>方法中看到,取反this.m_fMethod,而this.m_fMethod則是在前面<code>init</code>中被賦予了false

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

是以186行第一個if語句進入了true

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

<code>sBeanAttribute</code>的值為<code>sCName</code>第一個首字母變成大寫後的值DatabaseMetaData

重點看for循環裡面的内容,因為此内容拿到了關鍵的<code>method</code>

在BEAN_ACCESSOR_PREFIXES中有get、is方法,for循環周遊拿到clzTarget對象(com.sun.rowset.JdbcRowSetImpl)的get,is + sBeanAttribute(DatabaseMetaData)方法,然後指派給了method

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

最後進行了method.invoke(oTarget, aoParam)

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

method值為getDatabaseMetaData

oTarget值為JdbcRowSetImpl

aoParam值為null

接下來就是調用到了<code>JdbcRowSetImpl</code>的<code>getDatabaseMetaData</code>方法造成了JNDI注入

<code>ExtractorComparator</code>類的<code>compare</code>方法會去調用<code>UniversalExtractor#extract</code>,并且傳入了o1,而此處的o1則是最後<code>UniversalExtractor</code>的oTarget(JdbcRowSetImpl)

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

<code>PriorityQueue</code>類是此漏洞的入口,其以<code>readObject</code>為入口,最後調用到<code>ExtractorComparator#compare</code>方法,下面是<code>PriorityQueue</code>的調用鍊

這裡有幾個注意點:

<code>comparator</code>的值為<code>PriorityQueue</code>的構造函數中傳入

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

<code>comparator.compare(x, (E) c)</code>中x和c的值都是在<code>queue</code>數組中獲得

Weblogic漏洞分析之JNDI注入-CVE-2020-14645
Weblogic漏洞分析之JNDI注入-CVE-2020-14645

最後一點是size的值要大于等于2,不然不會進入while語句中

Weblogic漏洞分析之JNDI注入-CVE-2020-14645

最後構造出整個漏洞的調用鍊

安裝Weblogic更新檔:p31537019_122140_Generic

https://www.anquanke.com/post/id/210724

https://nosec.org/home/detail/4524.html

https://paper.seebug.org/1280/#cve-2020-2883

https://github.com/Y4er/CVE-2020-14645