FlawOpen

flawopen.com/Incidents/log4shell-jndi-injection-december-2021

● Apache Software Foundation · CVE-2021-44228 · December 2021 · CVSS 10.0 · 严重
安全研究 · FlawOpen

Log4Shell(CVE-2021-44228):成因与修复

CVE-2021-44228允许日志数据触发Log4j 2查找并通过JNDI加载类。请更新Log4j并盘点所有内嵌副本。[1], [2], [4]

💡 通俗易懂的原理解析 (ELI5)

一间办公室里有个文员,他唯一的工作就是记下访客说的话。有人发现,只要访客说出某句特定的话,文员就会停笔,按那句话里提到的地址过去,从陌生人手里接过一个密封的信封,并照着里面的指示去做。可文员的本职只是做记录而已。[1]

核心概念与专有名词

消息查找
Log4j 2 的一项功能,会在写日志时把消息中的 ${...} 表达式替换成相应的值。在 2.15.0 之前,这不仅作用于配置的格式,也作用于消息里的数据。[1]
JNDI
Java 命名和目录接口,用于在 LDAP 等目录服务中查找对象的 API。向远程服务器发起的 JNDI 查找可能返回一个供 JVM 加载的类。[1]
表达式注入(CWE-917)
不可信数据到达表达式求值器,作为数据传入的文本被当作指令执行。[1]
传递依赖
应用只是因为另一个库依赖它才引入的库。许多受 Log4Shell 影响的情况,都来自无人登记的 Log4j 副本。[4]
软件物料清单(SBOM)
机器可读的清单,列出一次构建中的每个组件及其版本,能让你迅速回答“我们哪里在运行 Log4j 2.14?”。[4], [3]

框架映射

事件演进时间线

2021-11-24

阿里云安全团队的陈兆军私下向 Apache 报告了该漏洞。[1]

2021-12-09

漏洞公开;Log4j 2.15.0 发布,数小时内即出现大规模扫描。[1], [4]

2021-12-17

CISA 发布第 22-02 号紧急指令,要求美国联邦机构排查并缓解 Log4j 问题。[3]

2021-12-28

Log4j 2.17.1 修复 CVE-2021-44832,这是 2.15.0 之后三个后续 CVE(另两个为 CVE-2021-45046 和 CVE-2021-45105)中的最后一个。[1]

攻击执行流程分解

步骤 1

攻击者的文本进入日志调用

应用记录的任何值,比如用户名、请求头或搜索词,都可能带有攻击者选定的查找表达式。[1]

步骤 2

Log4j 对表达式求值

有漏洞的版本会处理日志数据中的查找,因此表达式会被解析执行,而不是作为纯文本写入。[1], [2]

步骤 3

JNDI 对外连接

JNDI 查找让服务器去连接表达式中指定的目录服务,而这往往位于攻击者的基础设施上。[1], [4]

步骤 4

远程代码被执行

远程目录可以让 JVM 去加载某个类,该类随后以应用的权限运行。在阻断了出站连接的环境中,这一步会失败。[1], [2]

源代码对比:漏洞与安全实现

示意性的 Maven 配置。导入 log4j-bom 后,所有 Log4j 模块(包括其他库带进来的副本)都会解析为同一个当前版本。enforcer 规则则会在仍能访问到任何低于 2.17.1 的 log4j-core(包括传递依赖)时让构建失败,这样新的依赖就无法悄悄把有漏洞的代码带回来。升级才是真正的修复;在应用服务器上阻断出站 LDAP 和 RMI,则是纵深防御,即使补丁滞后也能切断利用链。

存在漏洞的实现
<!-- pom.xml: a direct dependency pinned to a vulnerable release -->
<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.1</version>
  </dependency>
</dependencies>
<!-- Nothing stops another library from pulling in an older log4j-core transitively. -->
加固后的安全修复
<!-- pom.xml: one version for every Log4j module, and a build that fails on old ones -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-bom</artifactId>
      <version>2.24.3</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-enforcer-plugin</artifactId>
      <version>3.5.0</version>
      <executions>
        <execution>
          <id>ban-vulnerable-log4j</id>
          <goals><goal>enforce</goal></goals>
          <configuration>
            <rules>
              <bannedDependencies>
                <searchTransitive>true</searchTransitive>
                <excludes>
                  <exclude>org.apache.logging.log4j:log4j-core:[2.0-beta9,2.17.1)</exclude>
                </excludes>
              </bannedDependencies>
            </rules>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

工程与系统安全加固清单

参考来源