几乎每个系统都会使用日志框架,用于记录日志信息,这些信息可以提供程序运行的上下文,但是日志过多也会影响系统的性能,所以好的日志框架应该是可靠,快速和可扩展的。
Apache Log4j2 是一个基于 Java 的日志工具,是Log4j的升级版本,引入了很多丰富的特性,包括高性能,低垃圾收集,插件系统等。目前很多互联网公司以及耳熟能详的公司的系统或者开源框架都在使用Log4j2。
2021.12.7,Log4j首次被发现了一个非常严重的漏洞,在当天Log4j就发布了log4j-2.15.0-rc1
,但是12.9那天被发现这个版本仍然可以触发漏洞。简单点说,黑客可以恶意构造特殊数据请求包payload触发漏洞,从而可以在目标服务器上执行任意代码,导致服务器被黑客控制,被定性为“过去十年来最大、最关键的漏洞”。
根据目前统计,90%以上基于java开发的应用平台都会受到影响。那么这篇文章就会深入分析这个漏洞究竟是怎么产生的以及怎么修复它。
1. Log4j简介
Apache Log4j 是一个基于Java的日志记录工具。它是由Ceki Gülcü首创的,现在已经发展为Apache软件基金会的项目之一。
经过多年的开发迭代,Log4j 1.x的维护已经变得非常困难,因为它需要与非常旧的 Java 版本兼容,所以于 2015 年 8 月正式升级为Log4j2。
2. Log4j的lookup功能
本次漏洞是因为Log4j2组件中 lookup功能的实现类 JndiLookup
的设计缺陷导致,这个类存在于log4j-core-xxx.jar
中。
log4j的Lookups功能可以快速打印包括运行应用容器的docker属性,环境变量,日志事件,Java应用程序环境信息等内容。比如我们打印Java运行时版本:
public class VulnerabilityTest {
private static final Logger LOGGER = LogManager.getLogger();
public static void main(String[] args) {
LOGGER.error("Test:{}","${java:runtime}");
}
}
输出:
20:20:21.312 [main] ERROR com.ldbmcs.VulnerabilityTest - OpenJDK Runtime Environment (build 11.0.11+9) from AdoptOpenJDK
那么JndiLookup
到底有什么设计缺陷导致出现的史诗级漏洞呢?
我们首先把目标放在org.apache.logging.log4j.core.patte