0%

Weblogic CVE-2020-14644 分析

Weblogic CVE-2020-14644 分析

该漏洞与之前利用 Comparator.compare() 链的思路不同,主要是利用 defineClass 加载自定义类实现的远程代码执行。

利用类是 com.tangosol.internal.util.invoke.RemoteConstructor,先来看我们能够控制的部分,也就是构造方法:
image

传入了 ClassDefinition,继续跟进:
image

传入一个 ClassIdentity 类型的 id 和对象的字节数组,在继续跟进 ClassIdentity,可以看到,在其构造方法中需传入一个 class 获得赋值sPackage,sBaseName,sVersion:
image

在来看反序列化的部分,该类是通过 readResolve 进行反序列化的,readResolve 可以覆盖 readobject 的内容。
image

进入 this.newInstance() 方法:
image

最终进入 com.tangosol.internal.util.invoke.RemotableSupportrealize 方法:
image

由于之前未加载过该自定义类,所以会进入 this.defineClass(definition) 方法,跟进:
image

大概看了下就知道和之前的构造方法中的参数基本相同,也就是都是我们可以控制的,进入 definition.getId().getName():
image

最终执行的是 getSimpleName() 方法,返回的是 BaseName+$+Version 的值,返回 defineClass 方法:
image

接下来就是把处理的类名、类对象的字节数组及长度传入 this.defineClass,由于 com.tangosol.internal.util.invoke.RemotableSupport 是继承 ClassLoader 的,所以这里的 this.defineClass 实际上是 ClassLoader.defineClass 也就是创建类,最后创建类的实例,达到实现自定义类的目的:
image

过程中需要注意的一点就是自定义的类名是由2部分组成的。

利用方式有2种,第一种就是利用重写原有的类,如这里是 LambdaIdentity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.tangosol.internal.util.invoke.lambda;

import java.io.IOException;

public class LambdaIdentity$423B02C050017B24DB10DFF759AA56BF{
public LambdaIdentity$423B02C050017B24DB10DFF759AA56BF() {
}

static {
try {
Runtime.getRuntime().exec("open /Applications/Calculator.app");
} catch (IOException var1) {
var1.printStackTrace();
}
}
}

这样的好处是后面的 hash 相对固定,第二种是先计算 hash,然后通过 javaassist 动态修改自定义类的名字。

整个逻辑还是相对清晰,过程也并不复杂,也提供了一种新的挖掘思路,注意构造方法中能直接传入字节数组的类