vlambda博客
学习文章列表

针对log4j2远程代码执行漏洞及其防护的分析

  • 近日IT业界爆出了惊天0-day大漏洞,涉及产品为Java常用基础日志工具log4j(受影响版本为2.x,后文将简称为log4j2)。该漏洞类型为RCE(远程代码执行漏洞),能够被攻击者利用任意输入框注入可执行脚本实现恶意攻击。当前该漏洞已经公开披露,在通用漏洞披露库的正式编码为CVE-2021-44228、CVE-2021-45105和CVE-2021-45046,漏洞级别为紧急。鉴于log4j已被Java生态广泛采用,众多主流开源框架均采用该工具,导致受威胁公司数量非常庞大,影响巨大,波及终端用户非常广泛。自2021年12月13日公开以来,各大厂商均开始自查,并采取应对措施已降低该漏洞进一步损害的可能。本文将从log4j2漏洞的原理和防护方法角度进行阐述,研究该类型问题的预防方式。 

1

Log4j2产品概述 

Apache Log4j 是著名开源基金会Apache托管的开源项目,是一款Java常用的基础日志工具,通过集成log4j应用可以快速拥有统一的日志输入、输出和格式化能力,通过灵活的配置文件可以实现应用日志到多个不同的目标(控制台、文件和远程socket服务器等)动态输出。该工具目前在Java业界被广泛采用,包括Elastic Search、Apache Flink和Hive等众多常用开源框架均采用log4j,是Java应用程序最流行的日志框架之一。 

Log4j由三个重要的核心组成部分: 

  • Logger(记录器):控制日志记录的级别,以及禁用或启用哪些日志输出的规则

  • Appenders(输出器):指定日志输出的目标(控制台、文件、系统日志等等)

  • Layout(格式器):格式化显示日志内容,可配置格式

其详细架构如下:

针对log4j2远程代码执行漏洞及其防护的分析本次漏洞影响的部分为 Layout 组件用到的 Lookups 功能,该漏洞的根源是 log4j2引入了 JNDI 支持,允许通过 JNDI 动态解析日志格式化内容的能力,导致攻击者成功利用 JNDI 注入漏洞执行恶意代码。

2

漏洞原理剖析

JDNI(Java Naming and Directory Interface)是 J2EE 规范中定义的一套重要的应用编程接口(API),为 Java 应用提供了命名和目录访问服务的功能。JNDI 主要有两部分组成:应用程序编程接口(API)和服务供应商接口(SPI)。JNDI 提供统一的客户端API,通过不同的服务供应接口(SPI)的实现,由管理者将 JNDI API 映射为特定的命名服务和目录系统,使得 Java 应用程序可以和这些命名服务和目录服务之间进行交互,如图

针对log4j2远程代码执行漏洞及其防护的分析


JDNI 支持调用任意的 SPI 服务,JDK 中包含了多种不同的 Service Provider 的内置实现:

  • 轻量级目录访问协议(LDAP)

  • Common Object Request Broker Architecture (CORBA) Common Object Services (COS) name service

  • Java Remote Method Invocation (RMI) Registry

  • 域名服务(DNS)

其中最常被利用的是 RMI(远程方法调用),这会导致 Java 程序通过 JNDI 接口请求远程服务端实现的 SPI 服务,从服务端加载 Java 对象到本地运行环境执行。

针对log4j2远程代码执行漏洞及其防护的分析

如下图流程所示,客户端 Java 应用只要通过 JNDI 接口发起 RMI 调用,传递一

个”hello”关键字给服务端,即可从服务端获得 IHello 对象实例到本地运行环境,此时客户端 Java 应用即可调用服务端定义的 sayHello 方法。 

针对log4j2远程代码执行漏洞及其防护的分析

log4j2 漏洞的根源就在于为 Lookups 功能引入了 JDNI 支持,并且在默认开启。该漏洞影响的版本为 2.0 <= Apache log4j2 <= 2.14.1。Lookups 功能允许应用在任意位置向log4j 动态添加值,包括日志内的动态内容部分。

针对log4j2远程代码执行漏洞及其防护的分析

针对log4j2远程代码执行漏洞及其防护的分析


3

漏洞影响

因此只要攻击者通过任意 Java 应用的输入框输入 JNDI 攻击内容,并且该输入框内容会被 log4j2 输出到日志,即可触发 JNDI 注入漏洞,执行任意远程代码。 

目前已经发现 Stream、百度、苹果等多家产商的站点存在该漏洞,同时 Minecraft 等众多 Java 客户端应用也被证实受到该漏洞影响。

针对log4j2远程代码执行漏洞及其防护的分析

百度漏洞测试(来自网络)

针对log4j2远程代码执行漏洞及其防护的分析

苹果公司漏洞测试(来自网络)


鉴于 Java 在业界采用甚广,本次漏洞影响规模之大,难以计数。

4

漏洞修复及防护

在漏洞公开的第一时间各大厂商均开展了自查行为,以下是可以采用的修复方式:

升级到最新版本

该漏洞爆出后第一时刻官方就进行了修复工作,升级到 2.15.0 及以上版本即可修复该漏洞。

版本降级

鉴于本次只影响 log4j 2.x 版本,很多厂商采取了将 log4j 降级到 1.x 版本的方式,进行立刻修复。该方式的采纳代价主要取决于厂商业务程序对 log4j 2.x 版引入的新功能的依赖程度,如果因为引入太多 2.x 版本的新 API,降级代价过大,无法第一时间完成降级,可以采用其他缓解方式。

缓解措施

  • 禁用 Lookups 功能 (修改 jvm 参数 -

    Dlog4j2.formatMsgNoLookups=true)

  • 修改/添加系统环境变量

    FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS,并设置值为 true

  • 限制受影响的服务器访问外部站点

外部流量筛选

鉴于该漏洞发作方式,外部攻击者提交的流量很可能包括”${jndi:}”典型内容,因此可以采取全局流量过滤的方式,在防火墙端丢弃可以流量包。

人工排查

通过 code review 或者 devops 工具带的合规性检测工具,对项目使用的第三方代码库/程序包进行扫描,找出依赖受影响版本的 log4j 库的项目,及时进行修复工作。用户只需检查 Java 应用是否引入了 log4j-api 和 log4j-core 两个 jar 包。如果有应用程序使用,很可能会受到影响。 

该 RCE 漏洞给了我们很多启示,我总结了以下几点防护方式:

  • 慎重使用运行时动态 API,如.NET 的反射,Java 的 JNDI。任何允许动态加载代码/可执行内容到运行时的动作都是非常危险的。如能不用尽量不用,如果必须使用,一定要做好安全评估和代码防护。

  • 仔细评估第三方基础库的引入。本次事件影响之大的原因在 log4j 使用广泛,作为成熟的老牌框架,开发人员已经习以为常,引入时心理上非常信任,不会再投入精力进行评估。因此对于任何第三方库的引入应该进行安全评估,避免引入漏洞。

  • 限制服务器对访问外部的访问。Web 服务器应仅开启必要的出站端口,对于服务器的出入站流量要进行安全分析,屏蔽可疑流量。

  • 启用最新的安全组件/服务。针对 web 服务,当前存在众多的 WAF 或者云端防火墙产品,应当积极采用此类安全产品加强防护能力。

  • 在进入危险代码块前进行严格的检测和过滤。例如使用正则严格判断输入的数据是否含有危险变量。

  • 定期 Code Review 提高代码质量。任何开发平台都具有官方的最佳实践建议,通过定期 code review 确保代码实现符合最佳实践,减少风险。

  • 引入代码安全扫描工具。同时引入代码扫描分析工具,采用静态分析方式找出潜在的 bug 和安全漏洞,例如 Deep Source 和 SonarQube 等。

  • 并且Azure Sentinel现在已经支持检测Apache Log4j漏洞。

针对log4j2远程代码执行漏洞及其防护的分析
针对log4j2远程代码执行漏洞及其防护的分析
针对log4j2远程代码执行漏洞及其防护的分析

张昌伟 | 微软云产品技术专家