Dark background with blue code overlay
博客

Log4j 漏洞回溯分析第 1 部分:漏洞背景

Charlie Gero

Written by

Charlie Gero

January 07, 2022

Charlie Gero 是 Akamai 的企业部门副总裁兼首席技术官,还负责领导高级项目事业部。他目前专注于安全、应用数学、密码学与分布式算法领域的前沿研究,以打造下一代技术,为 Akamai 不断发展壮大的客户群保驾护航。通过在 Akamai 开展的研究工作,他已经获得了接近 30 项密码学、压缩、高性能网络系统、实时媒体分发等领域的专利,并且拥有物理学与计算机科学的学位。他在 Akamai 工作已经接近 15 年,先前曾经创办过一家初创企业,还曾在制药与网络行业担任过有关计算机科学的重要职位。

Log4j-retro1.png

时间轴

2021 年 11 月 24 日,阿里巴巴的云安全团队向 Apache Foundation 提交了一份非公开报告,指出在应用广泛的日志库 Log4j(基于 Java开发)中存在一个重大漏洞,可能造成私密信息泄漏以及远程代码执行 (RCE)。此漏洞的存在时间可以回溯到 2013 年。

次日,Apache Foundation 将 CVE-2021-44228 标记为“Reserved”(预留)状态,并开始研究修复方案。在随后的 12 天里,Apache Foundation 对该库的源代码做出了一些修改,以解决此问题, 2021 年 12 月 9 日,他们公开披露了这一漏洞

这造成漏洞利用攻击企图一时暴增,随后相关攻击企图一直在以惊人的速度增加。

Log4j 是什么?

为了真正理解这一漏洞,我们需要先了解 Log4j 是什么。Log4j 是 Java 社区开发者广泛应用的一个库。它为错误消息、诊断信息以及其他信息的日志记录提供了一种简单而强大的框架。

它拥有许多为人所称道的优点,其中之一就是能将日志记录到多个目标,包括但不限于控制台、文件、远程服务器(通过 TCP 实现)、系统日志、NT 事件日志和电子邮件。除此之外,它还支持分层筛选日志消息、日志级别、自定义布局及其他许多内容。

简而言之,凭借综合全面的功能组合,它对开发者十分有吸引力,也正因如此,这个库几乎无处不在 - 从 Web 应用程序到嵌入式设备,处处都有它的身影。

查找与嵌套

Log4j 支持的一个十分强大的功能就是“查找”。通过查找功能,开发者可以将变量或表达式嵌入到文本中,Log4j 会在输出之前自动对这些文本进行运算。例如,开发者可以写一段代码来将如下文本记入日志:

“${date:MM-dd-yyyy} All Systems Good”

Log4j 会将 ${date:MM-dd-yyyy} 这一模式识别为日期查找,并尽职尽责地将表达式替换为当天的日期。举例来说,如果当天的日期是 2021 年 12 月 20 日,它会将输入文本修改为如下内容并输出到某个目标:

“12-20-2021 All Systems Good”

这对开发者十分有帮助。如果没有这一功能,开发者必须手动编写代码来查找日期,将其格式化为字符串、附加到日志行前面,然后再输出。虽然上文这段代码编写起来不是特别困难或费力,但它与软件的核心业务逻辑无关,而且会在不同的项目中重复出现。

通过利用 Log4j 库中已编码的现成功能,开发者就可以将所有日志相关任务交给 Log4j 处理,从而集中精力关注对于其项目意义重大的差异化优势。

Log4j 支持 多种不同类型的查找表达式 。我们再来了解一下本文将重点关注的两个变量:env 和 lower。env 允许将主机系统的环境变量包含到日志行中。例如,一名开发者将如下文本写入日志:

“The current user is ${env:USER}”

假设当前运行该软件的用户身份是“Administrator”(管理员),那么这会生成如下输出:

“The current user is Administrator”

env 和 date 变量用于在文本中注入新数据,而 lower 变量则可以用来操控原有内容。Log4j 会将使用 lower 变量的表达式中的所有内容作为小写字母形式处理。例如:

“The lower case text is ${lower:ABCDEFG}”

这会生成:

“The lower case text is abcdefg”

这个例子本身算不上有趣。直接输入小写字母形式的字符串不行吗?何必要费这番周折?但 Log4j 允许 嵌套 查找表达式,这让这个变量变得十分强大。

我们可以像下面这样将前面的两个表达式结合起来:

“The lower case current user is ${lower:${env:USER}}”

此时,Log4j 会先进行 ${env:USER} 表达式运算,得出 Administrator这个结果,然后将此结果提供给 lower ,它会生成 administrator,最终得出以下一行输出:

“The lower case current user is administrator”

JNDI

尽管 dateenvlower 都是十分值得关注也非常有用的变量,但如果没有 JNDI 查询,这个漏洞也就不会存在。 JNDI是 Java 命名和目录接口 (Java Naming and Directory Interface) 的英文缩写,是 Java 开发和运行环境中原生构建的一种机制,它通过一个通用接口简化了查询各种不同目录服务以获得信息的过程。

因此,它支持许多不同类型的目录服务。例如,JNDI 支持查询 DNS 服务器,以查明某个主机的 IP 地址,还支持在 AD 和 LDAP 中查询目录条目。它甚至支持查询正在运行的 Java 环境本身,以查明 环境条目,也就是有关当前运行的软件的专用配置选项。

Log4j 中的 JNDI 查找表达式让开发者能够在记入日志的文本中嵌入表达式,从而直接访问这个无比强大的子系统。举个例子,假设一名开发者尝试将如下字符串记录到日志中:

“The current mail host is ${jndi:java:comp/env/mailhost}”

Log4j 会将 ${jndi:java:comp/env/mailhost} 表达式识别为 JNDI 查找,并将 java:comp/env/mailhost 这个伪 URL 传递到 JNDI 子系统。JNDI 会将这个特定 URL 类型识别为一条查询,用来查找当前运行的组件的 mailhost 配置选项。

我们假设这个配置选项配置为 mymailserver.example.com。JNDI 会将此信息回传给 Log4j,Log4j 随即将查找表达式替换为 mymailserver.example.com,并生成以下输出:

“The current mail host is mymailserver.example.com”

了解漏洞的存在缘由

简单来说,Apache 的 Log4j 库广为普及,并且提供了丰富的功能,特别是查找、嵌套和 JNDI 功能,因此,该漏洞给攻击者大开方便之门。这些强大的功能给开发者提供了便利,但也让攻击者有机可乘,让他们能通过传递请求来引发数据渗漏或远程代码执行 (RCE)。掌握这些信息之后,我们就可以开始更深入地认识该漏洞,探究攻击者有可能如何利用其入侵系统。

下期预告

在本系列的第 2 部分中,我们将研究攻击者如何利用此漏洞实施数据渗漏和 RCE 攻击。



Charlie Gero

Written by

Charlie Gero

January 07, 2022

Charlie Gero 是 Akamai 的企业部门副总裁兼首席技术官,还负责领导高级项目事业部。他目前专注于安全、应用数学、密码学与分布式算法领域的前沿研究,以打造下一代技术,为 Akamai 不断发展壮大的客户群保驾护航。通过在 Akamai 开展的研究工作,他已经获得了接近 30 项密码学、压缩、高性能网络系统、实时媒体分发等领域的专利,并且拥有物理学与计算机科学的学位。他在 Akamai 工作已经接近 15 年,先前曾经创办过一家初创企业,还曾在制药与网络行业担任过有关计算机科学的重要职位。