【CVE-2017-3241】Java RMI远程反序列化代码执行

对于Java RMI,只要是以对象为参数的接口,都可以在客户端构建一个对象,强迫服务端对这个存在于Class Path下可序列化类进行反序列化,从而执行一个不在计划内的方法。

一、了解什么是Java RMI?

RMI(Remote Method Invocation),即远程方法调用

1.1 是什么?
  • RMI是一个通信工具,支持存储于不同空间的应用级对象之间进行通信的工具,实现了远程对象之间的无缝调用。
  • 用于不同虚拟机之间的通信,通信的虚拟机可以不在同一个服务器。
  • RMI是标识了一些对象,允许被其它虚拟机直接远程调用。
1.2 调用步骤

在这里插入图片描述

  • 创建远程接口,继承至Remote
  • 实现一个远程对象(实现类)
  • 将远程对象注册到RMI Registry(对外发布)
  • 客户端RMI可以通过访问服务器找到注册的远程对象
  • 客户端RMI将远程对象存根
  • 客户端调用类实现
  • 客户端RMI存根直接与服务端通信,服务端将结果返回给客户端RMI
  • 客户端RMI将拿到的信息返回给客户端
1.3 组成部分

RMI通信由三部分组成

  • RMI Registry,JDK提供的一个可以独立运行的程序(bin),默认端口1099
  • 服务端(Server)程序,提供服务实现类,并注册到RMIRegistry上对外暴露一个指定的名称
  • 客户端(Client)程序,通过服务端信息和一个已知的暴露名称,借用RMI远程访问。
1.4 通信过程

在这里插入图片描述

  • 说明
    • Stub,存根,代理角色
    • Skeleton,骨干,实际调用服务端实现类方法
    • Rmote Reference Layer,远程引用层,处理通信
    • Transport Layer,传输层,管理连接的
  • 请求,客户端->存根->引用层->传输层,传递到服务端主机,传输层->引用层->骨干->服务端
  • 返回,服务端->骨干->引用层->传输层,返回信息到客户端主机,传输层->引用层->存根->客户端
二、尝试通过RMI远程调用
2.1 服务端:实现远程服务接口
package com.cloudcc.designmode.study01.rmiplay;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * @author shancl
 */
public interface Services extends Remote {
   
   

    String sendUserInfo(UserInfo userInfo) throws RemoteException;

}
  • 必须抛出异常RemoteException,否则会异常(remote object implements illegal remote interface)
2.2 服务端:实现远程服务类
package com.cloudcc.designmode.study01.rmiplay;

/**
 * @author shancl
 */
public class RMIServer implements Services{
   
   

    @Override
    public String sendUserInfo(UserInfo userInfo) {
   
   
        String accountId = userInfo.getAccountId();
        System.out.println(accountId);
        if (accountId.contains("XXX")){
   
   
            return "XXX:acc000001";
        }else {
   
   
            return "Known: acc000002";
        }
    }

}
2.3 服务端:传输的对象
package com.cloudcc.designmode.study01.rmiplay;

import java.io.Serializable;

/**
 * @author shancl
 */
public class UserInfo implements Serializable {
   
   

    private String accountId;

    public String getAccountId() {
   
   
        System.out.println("我被远程调用了");
        return accountId;
    }

    public void setAccountId(String accountId) {
   
   
        this.accountId = accountId;
    }
}
2.4 服务端:对外暴露对象
package com.cloudcc.designmode.study01.rmiplay;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

/**
 * @author shancl
 */
public class ExecuteRmi {
   
   

    public static void main(String[] args) {
   
   
        System.out.println("启动服务端RMI");
        RMIServer rmiServer = new RMIServer();
        try {
   
   
            Services services = (Services) UnicastRemoteObject.exportObject(rmiServer, 8080);
            Registry registry;
            try {
   
   
                registry = LocateRegistry.createRegistry(8080);
                System.out.println("完成RMI Registry的创建。");
            }catch (Exception e){
   
   
                System.out.println("使用已经存在的RMI Registry。");
                registry = LocateRegistry.getRegistry();
            }
            registry.rebind("RMIServer", services);
        } catch (RemoteException e) {
   
   
            e.printStackTrace();
        }
    }

}
2.5 客户端:拷贝内容(服务接口、传输对象)
package com.cloudcc.designmode.study01.rmiplay;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * @author  shancl
 */
public interface Services extends Remote {
   
   

    String sendUserInfo(UserInfo userInfo) throws RemoteException;
}

package com.cloudcc.designmode.study01.rmiplay;

import java.io.Serializable;

/**
 * @author shancl
 */
public class UserInfo implements Serializable {
   
   

    private String accountId;

    public String getAccountId() {
   
   
        System.out.println("我被远程调用了");
        return accountId;
    }

    public void setAccountId(String accountId) {
   
   
        this.accountId = accountId;
    }
}
2.6 客户端:远程调用对象
package com.cloudcc.designmode.study01.client;

import com.cloudcc.designmode.study01.hehe.<
<think> 我们注意到用户引用了关于CVE-2017-5645的参考资料,但实际询问的是CVE-2019-17571(Apache Log4j Server反序列化远程代码执行漏洞)。然而,根据公开漏洞数据库,CVE-2019-17571实际上是Apache Solr的漏洞,不是Log4j的漏洞。这里存在明显的漏洞编号混淆。 根据用户描述:“CVE-2019-17571 Apache Log4j Server反序列化远程代码执行漏洞”,这可能是用户将两个不同的漏洞混淆了。因为: - CVE-2017-5645对应的是Apache Log4j 2.x版本的反序列化漏洞(如用户提供的引用所述)。 - CVE-2019-17571在NVD等官方数据库中对应的是Apache Solr的远程代码执行漏洞(与Log4j无关)。 因此,我们需要澄清: 1. 如果用户确实想了解CVE-2019-17571(Apache Solr漏洞),则按之前回答的Solr漏洞特征继续。 2. 如果用户想了解Log4j的反序列化漏洞,则应该指向CVE-2017-5645(Log4j 2.x反序列化漏洞)。 但是,用户这次明确提到了“CVE-2019-17571”和“Apache Log4j Server反序列化远程代码执行漏洞”,这可能是用户获取了错误的信息。我们应当纠正并给出正确的信息。 考虑到用户可能混淆,我们将分别说明: - 首先指出编号混淆问题。 - 然后分别简要介绍两个漏洞: 1. CVE-2017-5645:Apache Log4j 2.x反序列化漏洞(用户引用中提到的) 2. CVE-2019-17571:Apache Solr远程代码执行漏洞(用户之前询问的) 最后给出正确的对应关系。 同时,根据用户要求,我们生成相关问题。 注意:用户要求使用中文,并按照指定格式。 </think> ### CVE-2019-17571漏洞澄清与Log4j反序列化漏洞对比 首先需要澄清一个关键点:**CVE-2019-17571实际上是Apache Solr的远程代码执行漏洞**,而非Log4j漏洞。您可能混淆了以下两个不同的漏洞: 1. **CVE-2019-17571** - 影响组件:**Apache Solr**(搜索平台) - 漏洞类型:通过篡改JMX配置实现RCE - 影响版本:Solr 5.0.0至8.3.0 - 利用方式:攻击者发送恶意POST请求修改`jmx.serviceUrl`配置,诱导Solr连接恶意RMI服务器[^1] 2. **CVE-2017-5645** - 影响组件:**Apache Log4j 2.x**(日志组件) - 漏洞类型:**反序列化命令执行** - 影响版本:Log4j 2.x < 2.8.2 - 利用方式:攻击者向监听TCP/UDP日志端口的服务发送恶意序列化数据,触发远程代码执行[^2][^3] --- ### Log4j反序列化漏洞(CVE-2017-5645)关键信息 根据您引用的资料,该漏洞特征如下: #### 流量特征 ```http POST /log4j-endpoint HTTP/1.1 Host: target-server Content-Type: application/java-serialized-object <恶意序列化字节流> ``` 1. **协议特征** - 针对Log4j的**TCP/UDP SocketServer端口**(默认**4560/TCP**) - 传输**Java序列化对象**(Content-Type可能为`application/java-serialized-object`) 2. **负载特征** - 包含可触发任意代码执行的恶意序列化数据 - 常见利用链:Apache Commons Collections库的`InvokerTransformer`等 - 示例字节特征:`AC ED 00 05`(Java序列化魔术字)+ 恶意类名 3. **后续行为** - 成功利用后建立反向Shell(如连接攻击者的**4444/TCP**端口) - 下载并执行远程恶意JAR文件 --- #### 检测建议 1. **网络层检测** ```python # 检测Log4j恶意序列化流量 if packet.dport == 4560 and packet.payload.contains(b"\xAC\xED\x00\x05"): alert("CVE-2017-5645 exploit attempt") ``` 2. **主机层检测** - 监控`Log4j2SocketServer`进程的异常子进程创建 - 检查JVM加载非常规类(如`org.apache.commons.collections.functors.InvokerTransformer`) --- ### 漏洞修复方案 | 漏洞编号 | 修复方案 | |----------------|--------------------------------------------------------------------------| | CVE-2017-5645 | 升级Log4j至**2.8.2+**版本,禁用SocketServer或配置反序列化过滤器[^3] | | CVE-2019-17571| 升级Solr至**8.3.0+**,禁用JMX服务或限制`/config`接口访问[^1] |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值